Week 4: Currying

This week we'll be covering the process of partially applying parameters to a subroutine, this is based off of closures which we covered last week.  This allows us to create new subroutines that we can pass around that already have some of their parameters defined.  One of the benefits of this is that we don't have to pass around a parameter list and wait until all the parameters are ready, instead we can apply each parameter as we get it and then execute the subroutine at some later time when we are ready.  Doing this in Perl is actually very simple.

The function above provides us the ability to curry other functions.  Analyzing it shows that all we are doing is creating a new anonymous function that is going to call the function we passed in with the parameters we passed in and the parameters it receives.  Let's see an example of how this would work.

So, let's look at how it all worked.  First, we made a new anonymous function that takes a list of parameters, joins them, and prints them.  Next we curried that list with 3 fruit.  To do this we created a new anonymous subroutine that passed in the three fruit into the first anonymous subroutine.  After that we repeated the process, by currying the new subroutine we created from the last curried we now have a subroutine that calls the subroutine created on line 3 with 2 new fruit, that subroutine calls the subroutine created on line 1.  Once we execute this we will output a list of all the fruit we've given to the function.

We don't have to only curry anonymous functions.  Because we can get the reference of named functions and builtins we can also curry those.

This concludes this week's lesson.  Next week we will move past the building blocks of functional programming and start getting into systems built on top of this functional foundation.  Next week we'll cover dynamic dispatch tables.

As an aside, the name curry didn't come from the tasty South Asian type of dish, unlike the naming of Mix-Ins.  Instead, currying is named after the American Mathematician and Logician Haskell Curry.

Week 2: Closures

This week we will be covering closures.  Closures are another basic concept of functional programming.  They are based right on top of anonymous functions so if you haven't read last week's article it would behoove you to do so.

Closures are subroutines that "close over" variables thereby storing them in the scope of the subroutine to be accessed later.  Values stored in variables that exist within the scope of a function are guaranteed to exist as long as the function does.  This allows a developer to create subroutines that do many useful things, including provide state and encapsulate values.

In Perl a subroutine can access variables defined anywhere lexically above it, even once the scope that it is in is left.  This allows us to access otherwise lost data.

Whereas if we change this example to simply:

This code will fail at compilation time because $value isn't defined in the outer scope.

This is not unique to named functions, anonymous functions provide the same functionality:

We can use closures to create new subroutines that have some state stored in them.  For example, here is a subroutine that returns a subroutine that takes numbers to the power of the variable that was closed over.

It is important to note in the example above that each time power_of_generator is called the new anonymous subroutine returned has a new value to $power and cannot interfere with any other subroutines value of $power.

Another useful ability that closures have is that they can safely encapsulate data, more safely than many of the OOP approaches in Perl.

It is important to note in the example above that $name cannot be accessed outside of the scope of the outer curly brackets.  As such, there is no way to set $name to a value that is not title cased.  This is because the only way to set name is through set_name() which will not accept a value that isn't title cased.

The example above only provides the ability to store one name in a running program.  If we wanted to safely store multiple names we could do so by wrapping the $name and accompanying subs into a larger sub.

This concludes our discussion on closures.  Next week we will move on to currying and a discussion on 'higher order' subroutines.

 

Week 1: The Lambda Function

***UPDATE:  I modified the final example with Naveed's (@ironcamel) suggestion, it looks much nicer now.***

***UPDATE: Christopher Bottom caught some vestigial lines of code in the final example, which I have removed.***

The Lambda Function is the building block of all functional programming.  It is also referred to as an anonymous function or sometimes in Perl as an anonymous subroutine.  Perl treats subroutines as first class data types.  Because of this it is incredibly simple to create, store, and invoke anonymous subroutines.  To create an anonymous subroutine you simply use the 'sub' keyword without putting a name between the keyword and the body.  For example:

Is an example of an anonymous subroutine.  Obviously it isn't very useful though.  To make this useful we need to store the reference of that anonymous subroutine in a variable:

Now that we have an anonymous subroutine referenced by the $hello variable we can access it by dereferencing and calling it like so:

Anonymous subroutines are just like normal subroutines.  Because of this you can pass parameters in to them.  Passed in parameters are provided in @_ just like in a normal subroutine.  If an anonymous subroutine exists within a larger subroutine then both will have their own @_ within their scope and you won't have to worry about them intermingling.



Without dereferencing and calling it you are simply referring to the variable itself, which you can pass around.  In fact, because these subroutine references are first class they can be treated the same as any other value.  This means that you can store subroutine references in arrays and in hashes (as both the key or the value), and that you can pass it along in subroutines.


This concludes this week's installment in Functional Perl.  Next week will cover the next building block, closures.