What on Earth is a Lambda Expression?

Recently I've spoken with a few customers that have asked what a Lambda Expression is, which surprised me. It seems that a second wave of developers are now starting to use Lambdas (i.e. those that didn't adopt C# 3.0 immediately) and need some pointers, so this post is intended to help you understand what they represent.

I'm not going into the how, why, where, and more here – there are better posts that do. This is just "what the heck does that syntax mean?"

An Example Situation

I'm going to use an example common to software development in the modern world – filtering a list of Llamas according to their height and how prone to grumpiness they are (OK, perhaps only fairly common, and yes, I'm writing this on a Friday afternoon J).

Imagine we have a list of our favourite Llamas;

private static List<Llama> Llamas = new List<Llama>()

{

    new Llama { Name = "Larry", Height = 10, IsGrumpy = true },

    new Llama { Name = "Loulou", Height = 12, IsGrumpy = false },

    new Llama { Name = "Lara", Height = 8, IsGrumpy = true },

    new Llama { Name = "Lorry", Height = 4, IsGrumpy = true },

    new Llama { Name = "Laurel", Height = 20, IsGrumpy = false },

    new Llama { Name = "Louise", Height = 17, IsGrumpy = true }

};

Now imagine that I want to get a list of all Llamas that are both Tall and prone to Grumpiness. We might achieve that like this;

var results = new List<Llama>();

foreach (var llama in Llamas)

{

    bool include = llama.IsGrumpy && llama.Height > 9;

    if (include)

        results.Add(llama);

}

Refactoring to a Lamda

The problem is that's a lot of code to do some simple filtering... and we know there are these great Extension Methods in LINQ that allow us to do a Where command on a collection of objects.

Let's make some changes to the syntax to start heading in the right direction. Note that much of the content in the rest of this post is intentionally invalid C# syntax – I'm leading you to the solution. I'll call out the next time it becomes valid syntax again!

Imagine that Where took as input the name of a method to perform filtering of a list. Perhaps our code would look like this;

var results = Llamas.Where(Filter);

... and a helper method named Filter;

private bool Filter(Llama llama)

{

    return llama.IsGrumpy && llama.Height > 9;

}

That makes sense right? The Where method calls the Filter method with each Llama to check if it should be included in the results.

Anonymous Inline Methods

But our Filter method is only ever used by this single line of code to filter our Llamas, so we could just not bother declaring a separate method, and use an inline one instead, perhaps something like this (again, this isn't valid syntax like much of this post)...

var results = Llamas.Where(

bool Filter(Llama llama)

{

return llama.IsGrumpy && llama.Height > 9;

});

Here you can see we've in-lined the method, and gotten rid of the private keyword as it's no longer a class member. But why does it have a name then? Let's lose the name...

var results = Llamas.Where(

bool (Llama llama)

{

return llama.IsGrumpy && llama.Height > 9;

});

Our syntax is getting pretty concise, so stay with me... all this says is "this method returns a Boolean, and requires a Llama as input", and then defines the method body.

Implied Types

But the C# compiler is pretty smart right? So why am I telling it that this returns a Boolean, when it knows the Where method needs a Boolean, and it can check that the "IsGrumpy && Height > 9" statement is a Boolean expression? Let's lose that bool keyword...

var results = Llamas.Where(

(Llama llama)

{

return llama.IsGrumpy && llama.Height > 9;

});

And we also know that the Where method is operating on a List<Llama>, so the only possible input to this method is of type Llama... so let's stop needlessly calling this out in our code;

var results = Llamas.Where(

(llama)

{

return llama.IsGrumpy && llama.Height > 9;

});

Needless Constructs

The thing is, our method is such a simple single line Boolean expression, why do we need the return keyword? Or the semi-colon terminating the line? We know that's what it is doing. And we don't need the braces for a single line expression right?

var results = Llamas.Where(

(llama)

llama.IsGrumpy && llama.Height > 9

);

The problem is that if we remove some white space;

var results =

  Llamas.Where( (llama) llama.IsGrumpy && llama.Height > 9 );

... it gets pretty tough to read, so we need a new way of separating the input parameters from the body of our expression, and in C# that is the => operator;

var results =

  Llamas.Where( (llama) => llama.IsGrumpy && llama.Height > 9 );

Now we don't need the brackets around our input parameter as there's only one...

var results =

  Llamas.Where( llama => llama.IsGrumpy && llama.Height > 9 );

... and why use all those characters to spell out "llama" all the time when we could use "l"?

var results = Llamas.Where( l => l.IsGrumpy && l.Height > 9 );

Summary

It turns out that the last three statements above are valid Lambda Expressions that filter a list of Llamas for us. The intention of this code hasn't changed – it is still saying;

Here is a method that takes an input parameter named "l", and returns a Boolean result by executing the following expression against that parameter. Use this method to filter Llamas please!

So explain to yourself what this syntax would mean?

tallGrumpyLlamas.ForEach(l => Console.WriteLine(l.Name));

I really hope this has been a slightly different approach to explaining how to use Lambda Expressions... of course you should now do some reading up to understand related things like Expression<>, Func<>, Action<>, and more... enjoy!

I've attached the simplest example code in case you want to play with it yourself.

Program.cs