|We don't bite newbies here... much|
I've been doing a little research into the strange world of functional programming using Haskell. It's an interesting language and I was playing with it to improve my understanding of how functional programming works with Perl. I feel that I have a fine grasp on map, grep, sort, closures and other aspects of Perl that are related to functional programming. Further, I'm familiar with Why I like Functional Programming by tilly. However, I would love to see more examples of how things are done in a functional manner in Perl. For example, in Perl, to compute the product of all of the elements of a list, we might do the following:
In Haskell, this would be illegal because variables are defined, not assigned values. In other words, if you have x = 3, then 'x' is always equal to three. You cannot change the value and last two lines of code above would not have a direct equivalent (shifting an element of off the list changes the list in the second line).
Let's say that I want the first element of a list. The first line below is bad, the second is good.
This leads to interesting properties of the language. In the following example, 'i' is set to seven, even though 'j' is not listed yet. This is because these variables are defined at compile time.
Needless to say, a similar construct in Perl would not perform the same. We can think of these variables as being analogous to what we experience in our math classes. If we have x + 3 = 7, we know that x is four and that its value will not change.
Another interesting thing about Haskell is that it does not have loop constructs such as while or for. This is because the language is essentially a series of definitions and the compiler or interpreter applies these definitions to the problem at hand and determines how to arrive at the result. Using loops involves having the programmer direct the actions of the computer and typically uses a variable set as a flag to indicate when the loop terminates. Since you cannot change the value of variables in Haskell, you cannot set such a flag. Thus, loops appear to be replaced with recursive definitions. Let's use this to get the product of a list in Haskell.
And here's a Perl equivalent of that.
So in looking at functional programming as a series of definitions and not as a series of directives, we define a factorial function in terms of the &prod_list function.
This leads to the following program to determine the factorial of a number supplied on the command line.
Yes, it looks very strange. Also, note that for simplicity, I have left off error checking. Further, functional programming as performed by Haskell is difficult to simulate in Perl as Haskell does many interesting tricks with type checking. I also think that my factorial example may not be the best example as that's a fair amount of overhead to set up a simple function (again without error checking).
I realize that I have given some rather simplistic examples above that do not even begin to touch on the power of functional programming, but rather, they illustrate some of the different approach to problem solving. Perhaps a more classic example would appear to be the Schwartzian Transform (ST).
With the ST, we don't have "loops", per se. Instead, we can think of these as definitions of how to transform a list. Further, we don't have the variables being reassigned to (though they might be in &expensive_func).
I am wondering about the following things.
Note that there are many things that I have not touched on. I don't know what monads are, for example. Also, I haven't dicussed guards (which appear to be similar to method overloading), lazy evaluation (hurry up, Perl 6! :), or first class functions, to name just a few topics.
It should be noted that Perl types being based on data structures as opposed to data types definitely causes potential problems here. Also, the &prod_list could be written differently.
Also, much of functional programming involves passing functions to other functions. I haven't discussed that.
This is all a long-winded way of saying "I don't quite grok functional programming."
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.