What exactly are lambda expressions in C#?

Yesterday I watched a very interesting Channel 9 video with Erik Meijer and Charles Torre. The video is about functional programming and why that is important in the multi-core world. They talk also about LINQ and lambda expressions and by the end of the video Erik mentions that he often gets the question about what lambda expression exactly are (in C#). So what are they?

To understand that we should probably go a little bit back in time. Let’s go back to the time of .NET 1.0 (C# 1.0) and start with the concepts of delegates. Delegates are a concept that wasn’t completely new with the advent of .NET. It was there before and for example in C++ they were called “function pointer”, which is probably more clear about what they do: a delegate holds a reference to a function (or method; whatever you like more) and allows you to call that function later on in time.

In .NET they renamed the concept to “delegate” and added type-safety to it. That means you have to exactly specify in the delegate what result type you expect and how many arguments and of what type you expect. After that you can use your delegate to point it to a method that has the specified signature; if you try to point it to a method with another signature you will get a compiler error, which is good! You can then pass the method around as if it is a variable:

internal sealed class Program
{
    // Definition of the delegate.
    public delegate void MyCoolDelegate(string arg);

    static void Main(string[] args)
    {
        // create the delegate and point it to the "PrintToConsole" method.
        MyCoolDelegate myCool = new MyCoolDelegate(PrintToConsole);

        // invoke the delegate.
        myCool(“Test”);
    }

    public static void PrintToConsole(string value)
    {
        Console.WriteLine(value);
    }
}

A delegate is just a reference to a method that you can use as if it is a variable. You can pass it to methods and invoke it whenever you think it is required. Delegates are a powerful concept because now not only variables are data, but also functions/methods can be threaten as if they are data. Functions have become first class citiziens.

Let’s fast forward little bit and stop at the time when .NET 2.0 and C# 2.0 were released. For C# 2.0 the C# team added something very nice and useful: anonymous delegates or better known as anonymous methods.

The difference between anonymous methods and traditional delegates (as in .NET 1.0) is only that you don’t need to define a method somewhere else and point to it with a delegate to do the job. You directly define the method where you would create the delegate and the C# compiler will take care of it. The C# compiler will create the method for you and convert it into something that looks exactly like in .NET 1.0.

Let’s compare the tranditional delegate and anonymous method ways:

// — the traditional way.
internal sealed class Program
{
    static void Main(string[] args)
    {
        // create a list with some data.
        List<string> list = new List<string>();
        list.Add(“value1″);
        list.Add(“value2″);

        // find in the list. We need to specify a method here
        // that does the logic to find the data we need.
        string result = list.Find(new Predicate<string>(FindInList));
    }

    // This method finds the data in the list.
    static bool FindInList(string value)
    {
        return (value == “value2″);
    }
}

// — the anonymous method
internal sealed class Program
{
    static void Main(string[] args)
    {
        // create a list with some data.
        List<string> list = new List<string>();
        list.Add(“value1″);
        list.Add(“value2″);

        // find in the list by using an anonymous method.
        string result = list.Find(delegate(string value)
            {
                return (value == “value2″);
            });
    }
}

You can clearly see the difference here. With the anonymous method we don’t need to create another method and a delegate that points to that method. We just say that we want to use a delegate here and specify the body of the method. It’s much more convenient to use an anonymous method instead of the traditional delegate way. The reason for that is that the code that belongs together stays together.

Another nice feature that has been introduced with anonymous methods is the possiblity to use variables that are defined outside of the method inside the method:

static void Main(string[] args)
{
    // create a list with some data.
    List<string> list = new List<string>();
    list.Add(“value1″);
    list.Add(“value2″);

    string toFind = “value2″;

    // find in the list. We need to specify a method here
    // that does the logic to find the data we need.
    string result = list.Find(delegate(string value)
    {
        return (value == toFind);
    });
}

In the example you can see that I use the “toFind” variable inside the delegate body although it is defined outside of it. That’s some magic that is done by the C# compiler: in this case the C# compiler doesn’t only create a method for us but a whole class (that contains the method) where the value that we use in the body is passed in as class member. That is why we can access the value inside of the method body: as class member it is part of the class and you have access to the class members from inside a method.

Now let’s move on to the present day and C# 3.0 (and .NET 3.5) and speak about lambda expressions. Lambda expression are just the next step in the “delegate evolution”. The compiler now even hides away the whole “delegate(…) { … }”. It’s is very convenient because that saves us a lot of typing!

A lambda expression always consists of a left and a right part. The left part is on the left side of the “=>” and the right part is on the right side of it. The left part holds the list of arguments, where we even don’t need to specify the types because they can be automatically fetched by the compiler. The right side contains the body of the method. A lambda expression always expects us to return some value that is why we can also omit the “return” keyword:

static void Main(string[] args)
{
    // create a list with some data.
    List<string> list = new List<string>();
    list.Add(“value1″);
    list.Add(“value2″);

    string toFind = “value2″;

    // find in the list. We need to specify a method here
    // that does the logic to find the data we need.
    string result = list.Find(value => toFind == value);
}

To sum it up: lambda expressions are just delegates (or type-safe “function pointers”). They only look as they are because some assumptions are taken (like a lambda expression are functions and therefore always returns a value) and the types can be automatically fetched by the compiler. The nice side effect is that lambda expressions save us a lot of typing and time. :)

Published on Jan 21st, 2008 — Tags: ,
   digg it!    kick it   

12 Comments ( Comments RSS TrackBack )

  1. A few corrections about C++:

    C++ function pointers are type safe, so delegates don’t differ in that manner. The major difference is that a delegate contains more information than just a function pointer. A delegate to a member function maintains both a pointer to the function and the instance of the object on which to call the member function, which is not something you can do with C++ function pointers. However, C++ has library support for this type of thing, both in FunPtr and their kin and in Boost libraries that will be part of C++0x.

    Comment by wekempf — January 22, 2008 @ 4:07 pm

  2. I have always read that in C++ function pointers aren’t type safe. Like you can give as arguments to the function pointer whatever you want.

    Even the official documentation on .NET delegates says the following “Delegates are like C++ function pointers but are type safe.” - http://msdn2.microsoft.com/en-us/library/ms173171.aspx

    Comment by Christian Liensberger — January 22, 2008 @ 5:28 pm

  3. http://www.thescripts.com/forum/thread214122.html

    Too many people are “changing the language” when they discuss technical matters, which leads to confusion, as seen in the above linked thread.

    C++ is strongly typed. Pointers are strongly typed. Function pointers are strongly typed. C++ does, however, allow you to “cast away” type information. However, the definition of “type safe” does NOT preclude this capability, so when people “changed the language” to say C++ function pointers aren’t type safe because of this, it only lead to confusion. People start to assume this means there is no type safety, that you can “give function pointers different numbers of arguments and whatever type you want”, which isn’t true. C++ IS a type safe language.

    Comment by wekempf — January 22, 2008 @ 5:38 pm

  4. Interesting argument… still consider that even Microsoft says it the official documentation that delegates are real type-safety. Probably because you can find ways around in C++ that you can’t in .NET.

    Comment by Christian Liensberger — January 22, 2008 @ 5:48 pm

  5. nice and sweet comprehensible summary!
    are you doing it for every new c# 3.0 feature?
    thx

    sell war super!!
    peter

    Comment by Petz — January 23, 2008 @ 8:10 am

  6. I’ll see what I can do :) Perhaps I do it for more new features. Would be a nice series, indeed.

    Comment by Christian Liensberger — January 23, 2008 @ 7:38 pm

  7. [...] Btw, if you are interested in what LINQ and lambda expressions in .NET are, you cold have a look at one of my older posts. Filed under: Programming, Software, LINQ, Object Relational Mapping, Opf3 — Feb 18th, [...]

    Pingback by Christian Liensberger » Opf3 and LINQ support — February 18, 2008 @ 9:47 pm

  8. [...] language. That’s for sure! Recently, the adding of the var keyword, anonymous types and lambda expressions have added some “dynamic” to the language. But still it’s not a dynamic [...]

    Pingback by Christian Liensberger » Adding some dynamic to C#: interface wrapping — March 21, 2008 @ 4:47 pm

  9. This was all sorts of helpful. Thanks a million! :D

    Comment by Rich — May 14, 2008 @ 9:01 pm

  10. Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

    Comment by sandra407 — September 9, 2009 @ 9:18 am

  11. I love your site. :) Love design!!! I just came across your blog and wanted to say that I?ve really enjoyed browsing your blog posts. Sign: ndsam

    Comment by angelina jolie — September 10, 2009 @ 9:11 am

  12. Sign: zdbrw Hello!!! nnfhz and 6275yrwmxauzhf and 6974 : I love your site. :) Love design!!! I just came across your blog and wanted to say that Ive really enjoyed browsing your blog posts.

    Comment by celebrity fuck you — August 24, 2010 @ 11:27 am

Leave a comment

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> [code][/code] [code lang="csharp"][/code].