690 votos

¿Qué es un lambda (función)?

Para una persona sin comp-sci fondo, ¿qué es una expresión lambda en el mundo de la informática?

1020voto

mk. Puntos 8276

Lambda proviene del Cálculo Lambda y se refiere a las funciones anónimas en la programación.

¿Por qué es este lugar? Permite escribir rápido tirar funciones sin nombrarlos. También proporciona una agradable manera de escribir los cierres. Con ese poder se pueden hacer cosas como esta.

Python

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

Esquema

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C# 3.5 o superior

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Como se puede ver en el fragmento de código de Python y JavaScript, la función de la serpiente tiene un argumento x, y devuelve una función anónima, o lambda, que lleva a otro argumento y. Que función anónima permite crear funciones a partir de funciones. Este es un ejemplo sencillo, pero que debe transmitir la potencia de lambdas y cierres.

101voto

Lasse V. Karlsen Puntos 148037

Una expresión lambda es un tipo de función, definida en línea. Junto con un lambda también suelen tener algún tipo de tipo de variable que puede contener una referencia a una función, lambda o de otra manera.

Por ejemplo, este es un C# trozo de código que no uso un lambda:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

Esto requiere de la Calculadora, que pasa a lo largo no sólo de dos números, pero el método que llamar dentro de la Calculadora para obtener los resultados del cálculo.

En C# 2.0 tenemos los métodos anónimos, por lo que se acorta el código de arriba:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

Y, a continuación, en C# 3.0 tenemos lambdas que hace que el código sea aún más corto:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}

60voto

Mark Cidade Puntos 53945

Se refiere al cálculo lambda , que es un sistema formal que sólo ha expresiones lambda, que representa a una función que toma una función para su único argumento y devuelve una función. Todas las funciones en el cálculo lambda son de ese tipo, es decir, λ : λ → λ.

Lisp utiliza la expresión lambda concepto a nombre de su función anónima literales. Este lambda representa una función que toma dos argumentos x e y, y que devuelva su producto:

(lambda (x y) (* x y)) 

Se puede aplicar en línea como esta (se evalúa a 50):

((lambda (x y) (* x y)) 5 10)

56voto

joel.neely Puntos 17059

El nombre de "lambda" es sólo un artefacto histórico. Todo de lo que estamos hablando es una expresión cuyo valor es una función.

Un simple ejemplo (usando Scala de la línea siguiente) es:

args.foreach(arg => println(arg))

donde el argumento de la foreach método es una expresión de una función anónima. La línea de arriba es más o menos lo mismo que escribir algo como esto (no muy real de código, pero usted consigue la idea):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

excepto que usted no tiene que molestarse con:

  1. Declarar la función en algún otro lugar (y tener que buscar cuando usted vuelve a visitar el código más adelante).
  2. Nombrar algo que usted está usando sólo una vez.

Una vez que estás acostumbrado a los valores de la función, no les parece tan absurdo como estar obligado a nombre de cada una de sus expresiones, tales como:

int tempVar = 2 * a + b
...
println(tempVar)

en lugar de sólo escribir la expresión donde la necesita:

println(2 * a + b)

La exacta notación varía de un idioma a otro; griego no siempre es necesario! ;-)

14voto

Keith Puntos 46288

Ligeramente simplificada: una función lambda es uno de los que se pueden pasar ronda a otras funciones, y es la lógica de acceso.

En C# sintaxis lambda es a menudo compilado a métodos simples de la misma manera como los delegados anónimos, pero también puede ser descompuesto y su lógica de lectura.

Por ejemplo (en C#3):

LinqToSqlContext.Where( 
    row => row.FieldName > 15 );

LinqToSql puede leer que la función (x > 15) y convertirlo en el real SQL para ejecutar utilizando árboles de expresión.

La declaración anterior se convierte en:

select ... from [tablename] 
where [FieldName] > 15      --this line was 'read' from the lambda function

Esto es diferente de los métodos normales o delegados anónimos (que son sólo compilador de la magia) porque no se puede leer.

No todos los métodos en C# que utilizar la sintaxis lambda puede ser compilado para árboles de expresión (es decir. real de las funciones lambda). Por ejemplo:

LinqToSqlContext.Where( 
    row => SomeComplexCheck( row.FieldName ) );

Ahora el árbol de expresión no puede ser leído - SomeComplexCheck no se puede descomponer. La instrucción SQL que se ejecutará sin el donde, y cada fila de los datos va a ser puesto a través de SomeComplexCheck.

Las funciones Lambda no debe ser confundido con los métodos anónimos. Por ejemplo:

LinqToSqlContext.Where( 
    delegate ( DataRow row ) { 
        return row.FieldName > 15; 
    } );

Esto también tiene un 'inline' función, pero esta vez es sólo compilador de magia - el compilador de C# va a dividir esto a un nuevo método de instancia con una autogenerado nombre.

Los métodos anónimos no se puede leer, y así que la lógica no puede ser traducido como puede para las funciones lambda.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X