Lambdas and Closures and Currying. Oh my! (Part 8)

Writing

View the whole series:

Functional Programming Series

We are now finally back for Part 8 of my functional programming series. In this part of my series we are going to be discussing currying in C# 3.0. Currying is actually a mathematical term where you take a function with multiple parameters and turn it into a function with only one parameter. This is done by simply providing values for the parameters that you want to take away. You are probably thinking "Well, that is pretty simple." And quite frankly, the concept is simple. The execution gets a bit more tricky, but it isn’t too bad. Especially if you have made it through this whole series.

Just like most of our other entries in this series, we are going to start off with a two argument multiply method to get our gears turning. This method looks like this:

  public static int Multiply(int a, int b)
  {
    return a * b;
  }

Now, our end goal is to supply a value for one of our arguments in order to make a function that only takes a single argument. So, the way we will do that is by creating an extension method that will operate on a two parameter delegate and will return a method which takes one parameter (This is our curried method). This new method will then take that parameter and return a new method that takes a single parameter, using the parameter that we passed to our curried method (this method is said to be "partially applied"). It sounds a lot more complex than it is, so lets first look at the usage to clear up what I said above.

  //Put Multiply method into a delegate so we can use
  //our extension method
  Func<int, int, int> method = Multiply;
 
  //Now curry our Multiply method
  var curriedMultiply = method.Curry();
 
  //Use the curried method to create 
  //partially applied methods
  var doubler = curriedMultiply(2);
 
  int result1 = doubler(5);
  int result2 = doubler(10);

Hopefully that made what I was saying much more clear. Our curried method just generates partially applied methods. So in this case we generated a doubler, but we could have also generated a tripler or quadrupler. Lets look at the method that generates this method:

  public static Func<TArg1, Func<TArg2, TResult>> 
    Curry<TArg1, TArg2, TResult>
    (this Func<TArg1, TArg2, TResult> func)
  {
    return argument1 => argument2 => func(argument1, argument2);
  }

Let’s break this down so it doesn’t look so crazy. First lets look at "Curry<TArg1, TArg2, TResult>" which is actually the generic method signature. This tells us that we have two arguments and a result type that need to be specified. In our case it is <int,int,int>. The extension method just takes a Func delegate with the same generic parameters as our method signature. Our multiply method works fine because it takes two args. The return type "Func<TArg1, Func<TArg2, TResult>>" is the interesting part. This just says that our extension method is returning a delegate that takes one parameter "TArg1" and then returns another delegate that also takes one parameter.

We accomplish this return type by chaining two lambdas together as you can see above. It may look weird, but argument1 and argument2 are just integer parameters. The inside lambda takes one parameter and returns a closure that is bound to argument2 from the outer lambda (Go back and check out earlier posts in the series for info on closures). So what you end up with is the outer lambda taking one parameter and then returning a closure that uses that parameter. It may look a bit more intuitive if I write it like this:

  public static Func<TArg1, Func<TArg2, TResult>> 
    Curry<TArg1, TArg2, TResult>
    (this Func<TArg1, TArg2, TResult> func)
  {
    return (TArg1 argument1) => {
      return (TArg2 argument2) =>
      {
        return func(argument1, argument2);
      };
    };
  }

Personally I think the lambda syntax is actually easier to read, but you should do what is the most clear for you and your team. In this new, updated version you can more clearly see that we are returning a closure that returns a closure that returns the result of our "func" method. So, the caller to our method will end up with a reference to the outermost closure.

So, now that we have succeeded in creating our curry method we have to ask ourselves, "do we really need it?" Instead of creating this curried method that generates all of our other methods, wouldn’t it just be easier to pass our initial value to the curry method and get back a partially applied method right away? And the answer in this case is, yes, it would be. To do this we are going to create a method called "PartiallyApply." Here is how we are going to use this method:

  Func<int, int, int> method = Multiply;
 
  //Create our partially applied method
  var doubler = method.PartiallyApply(2);
 
  int result1 = doubler(5);
  int result2 = doubler(10);

Essentially we are just turning it into one step. We are passing our value into the "PartiallyApply" method and we are getting back a method that can be called immediately to get a value. This method looks like this:

  public static Func<TArg2, TResult> 
    PartiallyApply<TArg1, TArg2, TResult>
    (this Func<TArg1, TArg2, TResult> func, TArg1 argument1)
  {
    return argument2 => func(argument1, argument2);
  }

Here we are just passing in a delegate and a single argument, then we call our delegate with the value of the argument we passed in and return a method that takes the additional argument. This is much easier to use than our Curry method, and so you may be wondering why we would need the currying to begin with. Well, it all starts to become apparent when you graduate beyond two parameters.

This post is starting to get a bit a bit long-winded, so I am going to go ahead and stop there. We have seen how currying and partial application work in two parameters, and so far they seem to be very similar only that the currying seems to involve this useless middle step. When we return with Part 9 we are going to move beyond two parameters and show you why currying and partial application really aren’t as alike as they may seem right now. So stay tuned!

Loved the article? Hated it? Didn’t even read it?

We’d love to hear from you.

Reach Out

Comments (4)

  1. Perhaps I’m missing the significance of this. It’s definitely cool, but in a programming situation, why would you want to use this? It seems that this method of doing things just adds a few needless steps.

  2. Well, the partial application could certainly be used in a situation where you needed to build up a function call. Being that most of us are imperative programmers (probably for a good reason) we don’t think functionally. We don’t think, hmm, I could curry this method and then pass it into this method over here where it would fill the first parameter, then I could pass it over here where the second parameter would be filled and then I could pass it over here where it fills the third parameter and then sends the result back to me. Most likely we would create an object for this with some properties, pass that object around, and then call a method that computes some value.

    Most likely you will want to stick with imperative ways of doing things, it all goes back to my post "Don’t be clever." You want to do things in the most simple way, and a lot of this stuff certainly is not. Mostly though it is good to see things from both sides of the fence, otherwise how do we know that we are doing things in the best way?

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

More Insights

View All