Jacob Carpenter’s Weblog

January 2, 2008

C# abuse of the day: Functional library implemented with lambdas

Filed under: csharp, extension methods, functional programming — Jacob @ 6:09 pm

With all the cool kids writing about F# and functional programming, I started thinking about a possible blog post.

One of my goals was to use lambda syntax to express the functional method implementations. To my eyes, lambdas are great at succinctly expressing higher-order functions. And using the => operator multiple times in a single line rocks! Without thinking about it too hard, I figured I could use static readonly fields to accomplish this goal.

Once I started writing the example code, though, I ran into a bit of a hitch with the generic parameters for the fields’ Func types.

Joseph Albahari (or perhaps his brother and coauthor, Ben) puts it well in C# 3.0 In a Nutshell [which, incidentally, is proving to be a great C# book] (pg. 99):

Generic parameters can be introduced in the declaration of classes, structs, interfaces, delegates [...], and methods. Other constructs such as properties [or fields] cannot introduce a generic parameter, but can use one.

Meaning, if I want to declare a field that contains a generic parameter, that generic parameter has to be declared by the containing type.

Specifically:

public static class Functional
{
    public static readonly Func<Func<X, Y, Z>, Func<X, Func<Y, Z>>> Curry =
        fn => x => y => fn(x, y);
}

Won’t compile. Instead you’ll get a few of these:

error CS0246: The type or namespace name ‘X’ could not be found (are you missing a using directive or an assembly reference?)

You’d need to modify the class definition like so:

public static class Functional<X, Y, Z>

Now we could add the parameters to our Functional class, but then the calling code would be hideous:

Func<int, int, int> add = (x, y) => x + y;
Func<int, Func<int, int>> addCurried = Functional<int, int, int>.Curry(add);

I mean, I know this is C#, but that is just way too much type decoration. Especially since the three type arguments to Functional should all be inferable.

Ideally, the calling code should be an extension method:

Func<int, int, int> add = (x, y) => x + y;
Func<int, Func<int, int>> addCurried = add.Curry();

And then it dawned on me: we can define generic extension methods on a static FunctionalEx class and delegate the implementation to a nested generic class (with generic fields).

That is, we can hide the ugly syntax of invoking a delegate field of a generic class, while utilizing the ugly syntax of implementing our functional methods using lambdas!

public static class FunctionalEx
{
    public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(this Func<T1, T2, TResult> fn)
    {
        return Implementation<T1, T2, TResult>.curry(fn);
    }

    public static Func<T2, T1, TResult> Flip<T1, T2, TResult>(this Func<T1, T2, TResult> fn)
    {
        return Implementation<T1, T2, TResult>.flip(fn);
    }

    private static class Implementation<X, Y, Z>
    {
        public static readonly Func<Func<X, Y, Z>, Func<X, Func<Y, Z>>> curry = 
            fn => x => y => fn(x, y);
        
        public static readonly Func<Func<X, Y, Z>, Func<Y, X, Z>> flip =
            fn => (y, x) => fn(x, y);
    }
}

Notice how the Curry extension method is implemented by the curry field of the nested generic Implementation class. Also notice how [un-?]readable the lambda implementation is. (Seriously though, if you look at the flip lambda long enough, it should start to make sense.)

Here’s some (far from practical) sample calling code to help:

class Program
{
    static void Main(string[] args)
    {
        Func<int, int, int> add = (x, y) => x + y;
        Func<int, Func<int, int>> addCurried = add.Curry();
        Func<int, int> increment = addCurried(1);

        Func<int, int, int> subtract = (x, y) => x - y;
        Func<int, Func<int, int>> subtractFlipped = subtract.Flip().Curry();
        Func<int, int> decrement = subtractFlipped(1);        

        Console.WriteLine("Expected: {0}; Actual {1}", 5, add(2, 3));
        Console.WriteLine("Expected: {0}; Actual {1}", 7, increment(6));

        Console.WriteLine("Expected: {0}; Actual {1}", 6, subtract(9, 3));
        Console.WriteLine("Expected: {0}; Actual {1}", 4, decrement(5));
    }
}

The output of which is:

Expected: 5; Actual 5
Expected: 7; Actual 7
Expected: 6; Actual 6
Expected: 4; Actual 4

I never did get around to writing that post on functional programming, but I now know how I’m going to implement the library if I do.

If you want to read more on currying in C#, I’d recommend Dustin’s post. In fact I should probably skip writing any further posts on functional programming with C#, since he’s got that topic pretty thoroughly covered.

About these ads

2 Comments »

  1. Too bad you can’t implicitly-type those lambda functions – that’s really all that’s holding me back from using C# in a functional fashion like this.

    Comment by Erik Forbes — October 13, 2008 @ 3:01 pm

  2. Why do you need that Implementation class? Why can’t you just write

    public static Func<T1, Func> Curry(this Func fn)
    {
    return p1 => p2 => fn(p1, p2);
    }

    Comment by Timwi — April 6, 2010 @ 4:29 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: