Pregunta ¿Qué es una lambda (función)?


Para una persona sin antecedentes de ciencia ficción, ¿qué es una lambda en el mundo de la informática?


619
2017-08-19 16:20


origen


Respuestas:


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

¿Por qué es genial? Le permite escribir funciones de eliminación rápida sin nombrarlas. También proporciona una buena manera de escribir cierres. Con ese poder puedes hacer cosas como esta.

Pitón

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

Como puede ver en el fragmento de Python, el sumador de funciones toma un argumento x y devuelve una función anónima, o lambda, que toma otro argumento y. Esa función anónima te permite crear funciones a partir de funciones. Este es un ejemplo simple, pero debe transmitir la potencia que tienen los lambdas y los cierres.

Ejemplos en otros idiomas

JavaScript

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

JavaScript (ES6)

const adder = x => y => 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);

Rápido

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = function () use (&$a, &$b) {
    echo $a + $b;
};

echo $lambda();

Haskell

(\x y -> x + y) 

Java ver esta publicación

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

932
2017-08-19 16:27



Una lambda es un tipo de función, definida en línea. Junto con una lambda también suele tener algún tipo de tipo de variable que pueda contener una referencia a una función, lambda o de otro modo.

Por ejemplo, aquí hay un fragmento de código C # que no usa 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 llama a la Calculadora, transfiriendo no solo dos números, sino también el método para llamar a la Calculadora y obtener los resultados del cálculo.

En C # 2.0 obtuvimos métodos anónimos, que acortan el código anterior a:

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 luego en C # 3.0 obtuvimos lambdas, lo 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);
}

96
2017-08-19 16:27



Se refiere a cálculo lambda, que es un sistema formal que solo tiene expresiones lambda, que representan 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 usó el concepto lambda para nombrar sus literales de función anónimos. Esta lambda representa una función que toma dos argumentos, x e y, y devuelve su producto:

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

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

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

54
2017-08-19 16:23



El nombre "lambda" es solo un artefacto histórico. De lo único de lo que estamos hablando es de una expresión cuyo valor es una función.

Un ejemplo simple (usando Scala para la próxima línea) es:

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

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

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

excepto que no necesita molestarse con:

  1. Declarar la función en otro lugar (y tener que buscarla cuando vuelva a visitar el código más adelante).
  2. Nombrar algo que solo estás usando una vez.

Una vez que está acostumbrado a valores de función, tener que prescindir de ellos parece tan tonto como exigirle que nombre cada expresión, como por ejemplo:

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

en lugar de solo escribir la expresión donde la necesites:

println(2 * a + b)

La notación exacta varía de un idioma a otro; ¡Griego no siempre es requerido! ;-)


48
2017-08-29 18:36



El cálculo lambda es una teoría matemática de sustitución consistente. En las matemáticas de la escuela uno ve, por ejemplo, x+y=5 Emparejado con x−y=1. Junto con las formas de manipular ecuaciones individuales, también es posible juntar la información de estas dos, siempre que las sustituciones de ecuación cruzada se realicen lógicamente. El cálculo lambda codifica la forma correcta de hacer estas sustituciones.

Dado que y = x−1 es una reordenación válida de la segunda ecuación, esto: λ y = x−1 significa una función que sustituye los símbolos x−1 para el simbolo y. Ahora imagine la aplicación λ y a cada término en la primera ecuación. Si un término es y luego realiza la sustitución; de lo contrario no hagas nada. Si haces esto en papel, verás cómo aplicar eso λ y hará que la primera ecuación se pueda resolver.

Esa es una respuesta sin ninguna informática o programación.

El ejemplo de programación más simple que puedo pensar proviene de http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works:

aquí es cómo la función cuadrada podría definirse en un imperativo   lenguaje de programación (C):

int square(int x)
{
    return x * x;
}

La variable x es un parámetro formal que es reemplazado por el real   valor que se cuadrará cuando se llama a la función. En un funcional   idioma (Esquema) se definiría la misma función:

(define square
  (lambda (x) 
    (* x x)))

Esto es diferente en muchos aspectos, pero aún usa el parámetro formal   x de la misma manera.


Adicional:  http://imgur.com/a/XBHub

lambda


37
2017-08-14 03:00



Ligeramente simplificado: una función lambda es aquella que se puede pasar a otras funciones y se accede a la lógica.

En C # lambda, la sintaxis a menudo se compila a métodos simples del mismo modo que a los delegados anónimos, pero también se puede analizar y leer su lógica.

Por ejemplo (en C # 3):

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

LinqToSql puede leer esa función (x> 15) y convertirla al SQL real para ejecutar usando árboles de expresiones.

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 en realidad son solo magia del compilador) porque no pueden ser leer.

No todos los métodos en C # que usan la sintaxis lambda se pueden compilar en árboles de expresiones (es decir, funciones lambda reales). Por ejemplo:

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

Ahora el árbol de expresiones no se puede leer: SomeComplexCheck no se puede analizar. La instrucción SQL se ejecutará sin el dónde, y cada fila de los datos se transmitirá a través de SomeComplexCheck.

Las funciones de Lambda no deben confundirse con métodos anónimos. Por ejemplo:

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

Esto también tiene una función 'en línea', pero esta vez es solo magia del compilador: el compilador de C # dividirá esto en un nuevo método de instancia con un nombre autogenerado.

Los métodos anónimos no se pueden leer, por lo que la lógica no se puede traducir como lo hace para las funciones lambda.


13
2017-08-19 16:30



Me gusta la explicación de Lambdas en este artículo: La evolución de LINQ y su impacto en el diseño de C #. Tenía mucho sentido para mí, ya que muestra un mundo real para Lambdas y lo construye como un ejemplo práctico.

Su explicación rápida: Lambdas es una forma de tratar el código (funciones) como datos.


6
2017-08-19 16:29



Un ejemplo de lambda en Ruby es el siguiente:

hello = lambda do
    puts('Hello')
    puts('I am inside a proc')
end

hello.call

Generará el siguiente resultado:

Hello
I am inside a proc

6
2017-08-19 17:17