Thursday, December 31, 2015

Lambda, Lambda, Lambda - How To Use a Lambda Expression

Many programming languages use lambda expressions: Python, Ruby, C#, JavaScript, and GO to name a few modern examples. Lambdas can be extremely expressive and save several lines of code when you just need a function without the need for reuse. I and others use Lambdas to create greater readability. On the flip side, if you don't understand how they work l, the syntax can be confusing and the code will be impossible to understand. My goal in this post is to help you understand what Lambdas are all about so you can understand them next time you see one and even add Lambdas to your tool set to improve your ability to be more expressive.


Here are some examples of adding 1 to x using Lambdas in various languages:

Python:
lambda x: x + 1;

Ruby:
lambda { |x| x + 1 }

C#:
x => x + 1;

js (ES6):
x => x + 1;

GO and js (<ES6):
This is where it gets interesting. These languages treat functions as first class and so a function can be passed as an argument to a function, which is really the point of lambda. This works the same way in PHP too. The syntax really doesn't matter in terms of understanding what a lambda is. Syntax is just to make things cleaner and gives you a way to declare the Lambda inline.

Let me explain by example:


Lets say we have a js function that expects a function:


function foo(bar){
    return bar();
}


This is a root form of the lambda.


In a strongly typed language like C#, it will look something like this:


int Foo(Func<int> bar)
{
    return bar():
}

Notice how the input is a Func? A Func is an anonymous method that returns a value (specified by the type in angled brackets <int>. There's also an Action which expects void.

Here is a more useful example:


public int OperateOnX(Func<int, int> expression)
{
    return expression(this._x);
}

and we call the method like this:


var a = intance.OperateOnX(x => x+1);
//or
var b = instance.OperateOnX((x) => x*x);


or if we use the C# Linq library:


var c = list.Where(x => x > 3);


In this example, the Func returns int and expects int as the first argument. Mulitple arguments can be specified as Func<int, int, string> (Action<int> expects one int argument, and Action<int, string> expects an int and a string argument):

var b = instance.OperateOnXY((x, y) => x*y); //Func<long, int, int>


The Where extension method iterates over the list and passes each item to your Lambda and returns items for which the expressions evaluates to true. The Lambda Expression is a filter.

For more advanced operations, you can encapsulate like this:



var c = list.Select(x => 
{
    var y = x.Name;
    if(y == "")
    {
        x.Name = "Phil";
    }
    return x;
});


Lambdas can take multiple arguments, after all they should behave just like a regular method or function. In fact you can pass a method to a Linq Where like this:


var d = list.Where(Filters.GreatFilter);


so long as GreatFilter matches the expected delegate type - its signature should look like this:


bool GreatFilter(ListItem item);


Since Where is an extension method in C# Linq (it Extends IEnumerable<T>) the input argument to the generic function will be T, or in this case whatever type "list" items are.


Hopefully, you understand what Lambdas are all about by now, if not feel free to ask and I will do my best to explain a bit further.


No comments:

Post a Comment