What are lambda expressions? And what is the purpose of using them?

52

When I first started using LINQ I saw that I could use the famous lambda expressions .

I even know that x => x * x is a lambda expression, but I could not explain to a colleague what they really are, and what the advantage is in using them.

Then I ask you:

What are lambda expressions? And what's the point in using them?

    
asked by anonymous 29.01.2014 / 18:36

7 answers

42

What are lambda expressions?

Lambda expressions are those of type A goes to B, meaning primarily a transformation. In C #, there are constant lambdas, and multiparametrized.

In C #, a lambda expression can be converted to:

  • a Delegate : is a compiled method, which can be executed, and passed as if it were a variable for who needs it. Also called anonymous methods, because they do not have their own identifier.
  • a Expression<> representing an expression tree that denote the transformation representing the lambda expression as a data structure.

Use in the form of Delegate

When converted to a delegate, lambda can be passed as if it were a variable. A lambda produces a delegate of a specific type that depends on the context in which it is created.

The calls below generate delegates of different types:

// delegate gerado do tipo Func<string, bool>
Func<string, bool> func = s => s == null;

// delegate gerado do tipo Predicate<string>
Predicate<string> pred = s => s == null;

So, each delegate of a different type can be passed as if it were a common variable, so you can call these methods like this:

pred("string to test");

All delegates, regardless of the specific type, inherit from the Delegate class.

Closures on delegates

Lambdas can present in their content, variables present in the method that constructs it, imprisoning this variable, in the form of a reference to it. This is also possible when building inline delegates.

int i = 0;
Action incrementa = () => i++;
incrementa();
// neste ponto a variável i, terá seu valor incrementado

This is a very powerful tool, and also dangerous, especially when used in loops, using the value of the iteration variable.

var listFunc = new Func<int>[10];
for (int it = 0; it < 10; it++)
    listFunc[it] = () => it;
// todos os elementos de listFunc retornam 10
// pois a variável it, neste ponto vale 10,
// e todos os delegates referenciam a mesma variável

Use in the form of Expression

When talking about lambda expression, it is common to get hit by this way of using them, but is widely used by frameworks such as EntityFramework and MVC , both from Microsoft.

LINQ supports the IQueryable interface, which is based on the use of transformed lambdas in data structure, which it analyzes in order to create a query that can be executed in the database.

As these libraries do, you can read this data structure generated from a lambda expression, using the classes present in the System.Linq.Expressions .

In addition, these lambdas in the form of Expression can be copied and modified, and then compiled, being one of the ways to generate dynamically executable code . You can also create a zero expression tree by dynamically generating integer methods by using the

29.01.2014 / 18:46
23

In essence, the advantage (in C #) of using them is to be able to carry small functions as values.

In essence. Because they involve several other advantages.

In fact, x => x * x is not ONLY a Lambda Expression, it is also known as an anonymous function, and can thus be used like any other function. You can even declare it like this:

Func<int, int> aoQuadrado = x => x * x;

And you could run it in a list, for example:

Enumerable.Range(1, 101).Select(aoQuadrado).ToList();

What would produce an IEnumerable with the squares of the numbers from 1 to 100 (% with% is exclusive, ie it does not include the last number - in this case, 101 - in its operations).

This is equivalent to this (which is essentially the same, imperative rather than functional):

int AoQuadrado(int n)
{
    return n * n;
}

var quadrados = new List<int>();
for (int i = 0; i < 101; i++) quadrados.Add(AoQuadrado(i));

Incidentally, both methods and anonymous functions (or lambda) are functions, that is, you could do this too:

int AoQuadrado(int n)
{
    return n * n;
}

var quadrados = from i in Enumerable.Range(1, 101).Select(AoQuadrado).ToList();

Even because this is perfectly valid:

int AoQuadrado(int n)
{
    return n * n;
}

Func<int, int> aoQuadrado = AoQuadrado;

This is often called "first-class functions". It is the possibility to use functions as values, and thus, to be able to transport them more easily.

In short: The main use of them is to be able to carry small functions as values, I would say.

    
29.01.2014 / 18:46
12

A lambda expression is a concise way of declaring a function or subroutine. In an object-oriented world, it is quite similar to an object that has a single method.

There are two main advantages of using a lambda expression instead of a function or method defined separately:

  • Simplicity. Why give a name to something that will only be used once?

  • Lexical scope. Lambda functions can automatically use all variables of the current scope. For example:

    int y = 10;
    Func<int,int> f = (x => x + y);
    

    f is a function that adds 10 to its argument. To do something equivalent using classes, we would need to create a new class, create a "y" field in that class, initialize that field in the class constructor, and pass the 10 as a parameter when creating f . Using anonymous functions this all comes for free.

  • 29.01.2014 / 18:54
    10

    In general lambda means to pass a function as an argument to another function (definition given for JavaScript, and extends to all functional languages):

    Free translation:

      

    Lambda basically means to use one function as an argument in a call to another function. Lambda is a popular buzzword in functional programming and is widely used. Worst of all, it is used as if everyone knew its real meaning. So if you see something like "Here we will use a lambda expression", it means they are just passing a function as an argument.

         

    Visually, in psuedo-code, Lambda is represented by the symbol λ, the 11th letter of the Greek alphabet. You can also see variable names as lambda to indicate that it will receive a function.

    link

    The point of using them is to be able to have the lambda function run at another time. (This is how callbacks work in JavaScript.)

    For example, if it is necessary to do some computation in / after a certain asynchronous event (such as an http request) is executed, we use a lambda (callback) expression in the function. Asynchronous events are important in the sense that they do not bar the program from running:)

        
    29.01.2014 / 20:33
    6

    Lambda expressions are nothing less than the types of methods you encode in a summarized way without specifying the entire structure of a method. In fact, they return a reference to that encoded functionality.

    This is very common in LINQ because when you filter a collection you basically want to pass a method that decides whether or not an object should be among those filtered. For example, suppose you have a collection of objects of the following class

    public class Cliente
    {
        public int ClienteID { get; set; }
        public string Nome { get; set; }
        /* Outros membros */
    }
    

    And then you want only those that have ClienteID par for example. So you use LINQ as follows:

    var clientesFiltrados = listaClientes.where(verificaIdPar);
    

    This verificaIdPar points to a method that can check whether ClienteID is even. But think a little: to code this method normally, you would have to put it in a class and everything, referencing it and then passing it to where and would hardly use it again. For this lambda expressions simplify your life, you can simply put a lambda expression in place, which returns a reference to the method that has the functionality described in the lambda expression.

    Note also that you can reference lambda expressions by variables of type delegate. And this is actually what these LINQ methods do: expect a delegate to point to a method that filters, selects, or any other operation, and then for simplicity we use lambda expressions.

        
    29.01.2014 / 18:52
    5

    Guilherme, this is a good question and would require a very extensive answer. It was trying to be brief, and for that was leaving out a lot, okay?

      

    What are lambda expressions?

    They are, by definition, anonymous functions. I like to think of lambda expressions as math functions. You have the input parameters and the function body, for example: f (x) = x * 2

    On the left you define what the function receives, on the right side what it does.

      

    And what's the catch in using them?

    IMHO, the biggest advantage is being able to send functions as arguments to methods. The biggest example of this is in Linq, as you commented. See:

    cidades.Where(x => x.Nome == "Florianópolis");
    

    Let's see the signature of the Where method:

    public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
    

    The first argument is needed because it is an extension method, so let's put it aside for now. But look at the second. It is an expression where its type is the type of the collection and that it returns a boolean. In this way, any lambda expression that conforms to these constraints can be sent as a parameter.

    The cool thing is that you can use all that potential in your code, you do not have to just leave it in the framework.

        
    29.01.2014 / 18:52
    3

    I think the concept is more important than how it is implemented.

    Lambda expressions are functions, the way we learn in high school. For a given value of X, we will always get a given result Y. That is, given an X value, we will always get the SAME value of Y. This behavior of an expression / function is called immutability, extremely important in functional languages, and in programming minimizes bugs related to side effects and allows you to work with parallel and distributed programming more easily.

    When a programming language implements the use of lambda expressions, it allows it to be treated as a value. That is, the function / expression can be placed in a variable, passed as a parameter and can usually be used in loops, in list of values and the like, depending on how the language implements the feature.

        
    30.01.2014 / 13:37