fp - a library for programming in a functional style
use fp; # filter out all be the even numbers filter(function { is_even(head(@_)) }, range(1, 100)); # split the string, get unique list out of it # then get that list's length, and then check # that is equal to 26 is_equal_to(len(unique(explode("the quick brown fox jumped over the lazy dog and ran on down the road"))), 26); # the sum of the numbers 1 through 10 is 55 is_equal_to(sum(range(1, 10)), 55);
This module is an experiment in functional programming in perl. It uses nothing but a combination of; subroutines, the @_ array and a few built in operators to implement a style of functional programming.
@_
None of the code above is all that interesting until you consider that at no point was variable assignment (=), if statements, or non-recursive iteration used. Although, do be entirely honest, there is actually two times when the = operator is used in the entire module. The first time is to assign the module's version, the second time is within the import routine, but those are really not parts of this library and really more infastructure anyway.
=
if
Variable assignment is not utilized, instead the contents of the @_ argument array are accessed/manipulated and passed along as the return of values from functions. Recursion is the only means of iteration, we do not use any of perl's built in iteration mechanisms (for, foreach, while, etc.). All functions are non-destructive to their inputs, and just about everything returns an array of some sort, so function call chaining works quite well. It operates only on flat lists only, since perl will flatten any arrays given as arguments.
for
foreach
while
This code is also written without side-effects. Meaning that each function is written to express an algorithm that produces its result rather than produce its result through the coercion of side-effects. Here is an example of what i mean, using even/odd predicate functions.
with side effects:
sub is_even { (($_[0] % 2) == 0); } sub is_odd { (($_[0] % 2) != 0); }
without side efffects:
sub is_even { ($_[0] <= 0) ? true : is_odd($_[0] - 1); } sub is_odd { ($_[0] <= 0) ? false : is_even($_[0] - 1); }
The side-effect version uses the side effects of the mathematical calculation of (x % 2) to test if x is even or odd. Where the side-effect free version uses mutual recursion to continually subtract 1 from x until it reaches 0, at which point it will be either odd or even based upon the function it stops in.
Represents a true value.
Represents a false value.
Represents an empty list.
Constructs a list out of the elements passed to it.
Constructs a list spanning from the first argument to the second argument.
Constructs a function.
Returns the length of the list.
Reverses the list given to it.
Appends an element to a list.
Prepends an element to a list.
Returns the element at the head of the list.
Returns the list, less the first element.
Returns the nth element of the list.
Returns the first element of the list.
Returns the second element of the list.
Returns the third element of the list.
Returns the fourth element of the list.
Returns the fifth element of the list.
Returns the sixth element of the list.
Reduce a list by removing the head of the list.
Returns the element at the end of the list.
Returns true if the given list is empty (equal to nil).
nil
Returns true if the given list is not empty (equal to nil).
Tests for the existence of a given element in the list.
Filter a list with a predicate function.
Apply a function to each element in a list.
Divides a number up into its individual numeric components.
Divides a string into characters.
Given a list of strings, it combines them into a single string.
Sums a list of numbers
Returns the product of all the elements in the list.
Combine two lists into one.
Only return the unique elements of a given list.
Returns a unique list of two lists.
Prepends the element to the list, while retaining uniqueness.
Appends the element to the list, while retaining uniqueness.
Returns a union of two lists.
Adjoin a set with mutliple new elements
Intersection of two sets is a list of all elements found in both.
This along with its mutually recursive mate is_odd will determine if a given number is even.
is_odd
This along with its mutually recursive mate is_even will determine if a given number is odd.
is_even
This attempts to determine if two elements are equal.
This attempts to determine if two elements are not equal.
This attempts to discern if a given element is a digit.
This attempts to discern if a given element is whitespace.
This attempts to discern if a given element is an alphabetical character.
This library is missing two set operations, because I cannot yet figure out a way to accomplish them without resorting to assignment statements.
None that I am currently aware of. Of course, that does not mean that they do not exist, so if you find a bug, let me know, and I will be sure to fix it.
I use Devel::Cover to test the code coverage of my tests, below is the Devel::Cover report on this module test suite.
---------------------------- ------ ------ ------ ------ ------ ------ ------ File stmt bran cond sub pod time total ---------------------------- ------ ------ ------ ------ ------ ------ ------ fp.pm 100.0 88.0 n/a 100.0 100.0 69.7 97.1 fp/functionals.pm 100.0 100.0 n/a 100.0 100.0 0.3 100.0 fp/lambda.pm 100.0 n/a n/a 100.0 n/a 29.7 100.0 fp/lambda/utils.pm 100.0 n/a n/a 100.0 100.0 0.3 100.0 ---------------------------- ------ ------ ------ ------ ------ ------ ------ Total 100.0 89.3 n/a 100.0 100.0 100.0 98.7 ---------------------------- ------ ------ ------ ------ ------ ------ ------
This module was inspired by reading one to many books about functional programming. Here is a short list of those books, all of which I recommend reading if you are insterested in such things.
This was really my first introduction to LISP and functional programming as a style/paradigm. It is an both informative and entertaining. Not to be missed, is Paul's web site http://www.paulgraham.com, it has many a good article on it.
This is a collection of essays for a advanced course in functional programming given at Newcastle Univeristy in the summer of 1981. Some of the essay highlights are one by Gerald Jay Susseman (of MIT fame), and one by John H. Williams about John Backus's FP language. I got this gem on Ebay a few years ago, I doubt it is still in print, but here is the ISBN number if you want to try and track it down: 0-521-24503-6.
While not specifically about functional programming, but rather about all kinds of programming, this book is a must have for any programming language enthusiast (like myself). Its 800+ pages of densly packed inforamtion on all sorts of programming langauges.
Erlang is a language developed by Ericson's research labs for use in soft-real-time programming. It is part-functional, part-declarative, and an extremely interesting langauge. This book, written by the 4 researchers who created Erlang, is well written and gives a great introduction into how to code, real world applications in a more functional style.
Standard ML is one of the more interesting functional langauges out there, and this book is an excellent reference on the langauge. I have to say that it does at times get very dense with theory and math, but it is a book I still refer to often, even when not programming functionally.
Not really a book, but instead the speech given by John Backus at the 1977 Turing Awards. This speech introduced FP, a very interesting (although somewhat odd) functional language. This was a very influential speech in the world of functional programming. It can be found in PDF form at http://www.stanford.edu/class/cs242/readings/backus.pdf.
stevan little, <stevan@iinteractive.com>
Copyright 2004, 2005 by Infinity Interactive, Inc.
http://www.iinteractive.com
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install fp, copy and paste the appropriate command in to your terminal.
cpanm
cpanm fp
CPAN shell
perl -MCPAN -e shell install fp
For more information on module installation, please visit the detailed CPAN module installation guide.