servidor - ¿Qué es una lambda(función)?
qué es aws lambda (21)
Para una persona sin antecedentes comp-sci, ¿qué es un lambda en el mundo de la informática?
Lo ilustraré intuitivamente paso a paso en códigos Python simples y legibles.
En resumen, una lambda es solo una función anónima y en línea.
Empecemos por la tarea de entender a las lambdas
como estudiantes de primer año con antecedentes de aritmética básica.
El plano de asignación es ''el nombre = valor'', ver:
In [1]: x = 1
...: y = ''value''
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: ''value''
''x'', ''y'' son nombres y 1, ''valor'' son valores. Probar una función en matemáticas.
In [4]: m = n**2 + 2*n + 1
NameError: name ''n'' is not defined
Informes de error,
no puede escribir una matemática directamente como código, ''n'' debe definirse o asignarse a un valor.
In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396
Funciona ahora, y si insiste en combinar las dos líneas separadas en una. Viene lambda
In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>
No hay errores reportados.
Esta es una mirada a lambda
, le permite escribir una función en una sola línea como lo hace en matemática en la computadora directamente.
Lo veremos más tarde.
Vamos a seguir profundizando en la ''asignación''.
Como se ilustra arriba, el símbolo igual =
funciona para el tipo de datos simples (1 y ''valor'') y la expresión simple (n ** 2 + 2 * n + 1).
Prueba esto:
In [15]: x = print(''This is a x'')
This is a x
In [16]: x
In [17]: x = input(''Enter a x: '')
Enter a x: x
Funciona para declaraciones simples, hay 11 tipos de ellas en Python 7. Declaraciones simples - Documentación de Python 3.6.3
¿Qué hay de declaración compuesta,
In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax
Ahí viene de habilitarlo funcionando
In [23]: def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
...:
In [24]: m(2)
Out[24]: 9
Tada, analízalo, ''m'' es nombre, ''n ** 2 + 2 * n + 1'' es valor. :
es una variante de ''=''.
Encuéntralo, aunque solo sea por comprensión, todo comienza desde la asignación y todo es asignación.
Ahora regresa a lambda
, tenemos una función llamada ''m''
Tratar:
In [28]: m = m(3)
In [29]: m
Out[29]: 16
Aquí hay dos nombres de ''m'', la función m
ya tiene un nombre, duplicado.
Se está formateando como:
In [27]: m = def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
SyntaxError: invalid syntax
No es una estrategia inteligente, por lo que los informes de error
Tenemos que eliminar uno de ellos, establecer una función sin nombre.
m = lambda n:n**2 + 2*n + 1
Se llama ''función anónima''
En conclusión,
-
lambda
en una función en línea que le permite escribir una función en una línea recta al igual que en matemáticas -
lambda
es anonima
Espero que esto ayude.
Para una persona sin antecedentes comp-sci, ¿qué es un lambda en el mundo de la informática?
@Brian uso lambdas todo el tiempo en C #, en operadores LINQ y no LINQ. Ejemplo:
string[] GetCustomerNames(IEnumerable<Customer> customers)
{ return customers.Select(c=>c.Name);
}
Antes de C #, usé funciones anónimas en JavaScript para las devoluciones de llamadas a las funciones AJAX, antes incluso de que se acuñara el término Ajax:
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
Sin embargo, lo interesante de la sintaxis lambda de C # es que, por su propia cuenta, no se puede inferir su tipo (es decir, no se puede escribir var foo = (x, y) => x * y) pero dependiendo de qué tipo son asignados a, se compilarán como delegados o árboles de sintaxis abstracta que representan la expresión (que es la forma en que los mapeadores de objetos LINQ hacen su magia "integrada en el idioma").
Lambdas en LISP también se puede pasar a un operador de cotización y luego recorrer como una lista de listas. Algunas macros poderosas se hacen de esta manera.
El cálculo lambda es una teoría matemática consistente de sustitución. En matemáticas de la escuela se 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 estos dos, siempre que las sustituciones de ecuaciones cruzadas se realicen de forma lógica. El cálculo lambda codifica la forma correcta de hacer estas sustituciones.
Dado que y = x−1
es un reordenamiento válido de la segunda ecuación, esto: λ y = x−1
significa una función que sustituye los símbolos x−1
por el símbolo y
. Ahora imagine la aplicación de λ y
a cada término en la primera ecuación. Si un término es y
entonces realiza la sustitución; de lo contrario no hagas nada. Si lo hace en papel, verá cómo aplicar λ y
hará que la primera ecuación sea solucionable.
Esa es una respuesta sin ningún tipo de informática o programación.
El ejemplo de programación más simple que se me ocurre proviene de http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works :
Aquí es cómo se podría definir la función cuadrada en un lenguaje de programación imperativo (C):
int square(int x) { return x * x; }
La variable x es un parámetro formal que se reemplaza por el valor real que se va a cuadrar cuando se llama a la función. En un lenguaje funcional (Esquema) se definiría la misma función:
(define square (lambda (x) (* x x)))
Esto es diferente de muchas maneras, pero aún usa el parámetro formal x de la misma manera.
Añadido: http://imgur.com/a/XBHub
El nombre "lambda" es solo un artefacto histórico. Todo lo que estamos hablando es una expresión cuyo valor es una función.
Un ejemplo simple (usando Scala para la siguiente línea) es:
args.foreach(arg => println(arg))
donde el argumento del método foreach
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 (no es un código real, pero obtendrás la idea):
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
excepto que no necesitas molestarte con:
- Declarar la función en otro lugar (y tener que buscarla cuando vuelva a visitar el código más adelante).
- Nombrando algo que solo estás usando una vez.
Una vez que te acostumbras a los valores de la función, tener que prescindir de ellos parece tan tonto como tener que nombrar cada expresión, como:
int tempVar = 2 * a + b
...
println(tempVar)
En lugar de simplemente escribir la expresión donde la necesite:
println(2 * a + b)
La notación exacta varía de un idioma a otro; ¡El griego no siempre es necesario! ;-)
En Javascript, por ejemplo, las funciones se tratan como el mismo tipo mixto que todo lo demás ( int
, string
, float
, bool
). Como tal, puede crear funciones sobre la marcha, asignarlas a cosas y volver a llamarlas más tarde. Es útil pero, no es algo que quieras usar en exceso o confundirás a todos los que tienen que mantener tu código después de que ...
Este es un código con el que estaba jugando para ver qué tan profundo va este agujero de conejo:
var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert(''index 0 pressed''); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert(''index 1 pressed''); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert(''index 2 pressed''); }; }; }
for(var i=0 ;i<3; i++)
x.thingy[i]()()();
En el contexto de CS, una función lambda es un concepto matemático abstracto que aborda un problema de evaluación simbólica de expresiones matemáticas. En ese contexto, una función lambda es lo mismo que un término lambda .
Pero en los lenguajes de programación es algo diferente. Es un fragmento de código que se declara "en su lugar" y que se puede transmitir como un "ciudadano de primera clase". Este concepto pareció ser útil para que entrara en casi todos los lenguajes de programación modernos populares (vea las funciones lambda en cualquier lugar).
En programación de computadoras, lambda es un fragmento de código (declaración, expresión o un grupo de ellos) que toma algunos argumentos de una fuente externa. No siempre debe ser una función anónima, tenemos muchas formas de implementarlas.
Tenemos una separación clara entre expresiones, declaraciones y funciones, que los matemáticos no tienen.
La palabra "función" en la programación también es diferente, tenemos la función "es una serie de pasos a seguir" (del latín "realizar"). En matemáticas es algo acerca de la correlación entre variables.
Los lenguajes funcionales intentan ser tan similares a las fórmulas matemáticas como sea posible, y sus palabras significan casi lo mismo. Pero en otros lenguajes de programación lo tenemos diferente.
Es una función que no tiene nombre. Por ejemplo, en c # puedes usar
numberCollection.GetMatchingItems<int>(number => number > 5);
para devolver los números que son mayores que 5.
number => number > 5
Es la parte lambda aquí. Representa una función que toma un parámetro (número) y devuelve un valor booleano (número> 5). El método GetMatchingItems usa esta lambda en todos los elementos de la colección y devuelve los elementos coincidentes.
Imagine que tiene un restaurante con una opción de entrega y tiene un pedido que debe hacerse en menos de 30 minutos. El punto es que a los clientes generalmente no les importa si envías su comida en bicicleta con un auto o descalzos, siempre y cuando mantengas la comida caliente y atada. Así que vamos a convertir este lenguaje a Javascript con funciones de transporte anónimas y definidas.
A continuación, definimos la forma de nuestra entrega. También definimos un nombre para una función:
// ES5
var food = function withBike(kebap, coke) {
return (kebap + coke);
};
¿Qué pasa si usaríamos las funciones de flecha / lambda para realizar esta transferencia?
// ES6
const food = (kebap, coke) => { return kebap + coke };
Usted ve que no hay diferencia para el cliente y no hay tiempo que perder para pensar en cómo enviar alimentos. Solo envialo.
Por cierto, no recomiendo el kebap con coque, es por eso que los códigos superiores le darán errores. Que te diviertas.
La pregunta ha sido respondida completamente, no quiero entrar en detalles. Quiero compartir el uso al escribir cálculos numéricos en el óxido.
Hay un ejemplo de un lambda (función anónima)
let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };
Cuando estaba escribiendo un módulo del método de Newton-Raphson, se usó como derivado de primer y segundo orden. (Si desea saber qué es el método de Newton-Raphson, visite " https://en.wikipedia.org/wiki/Newton%27s_method ".
La salida como la siguiente
println!("f={:.6} df={:.6}", f(10.0), df(10.0))
f=98.000000 df=20.000000
La pregunta tiene una gran respuesta formal, por lo que no intentaré agregar más sobre esto.
En palabras muy simples e informales para alguien que sabe muy poco o nada sobre matemática o programación, lo explicaría como una pequeña "máquina" o "caja" que toma alguna entrada, hace algo de trabajo y produce algo de salida, no tiene un nombre particular , pero sabemos dónde está y solo por este conocimiento, lo usamos.
Hablando en términos prácticos, para una persona que sabe qué es una función, les diría que es una función que no tiene nombre, que generalmente se coloca en un punto de la memoria que se puede usar solo haciendo referencia a esa memoria (generalmente a través del uso de una variable - si han escuchado sobre el concepto de los punteros de función, los usaría como un concepto similar) - esta respuesta cubre los conceptos básicos bonitos (sin mencionar los cierres, etc.) pero se puede obtener el punto fácilmente.
Lambda proviene del cálculo de Lambda y se refiere a funciones anónimas en la programación.
¿Por qué esto es genial? Te 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 código de Python, la función sumador 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 el poder que tienen las 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
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
Kotlin
val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true
Ligeramente simplificado: una función lambda es aquella que se puede pasar a otras funciones y se puede acceder a la lógica.
En C #, la sintaxis lambda se compila a menudo con métodos simples de la misma forma que los delegados anónimos, pero también se puede desglosar 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 utilizando á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 los delegados anónimos (que en realidad son simplemente la magia del compilador) porque no se pueden leer .
No todos los métodos en C # que usan la sintaxis lambda se pueden compilar en árboles de expresión (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 dividir. La instrucción SQL se ejecutará sin el dónde, y cada fila en los datos se pondrá a través de SomeComplexCheck
.
Las funciones 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 solo es magia del compilador: el compilador de C # dividirá esto en un nuevo método de instancia con un nombre generado automáticamente.
Los métodos anónimos no se pueden leer y, por lo tanto, la lógica no se puede traducir como se puede hacer para las funciones lambda.
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 rápida explicación: Lambdas es una forma de tratar el código (funciones) como datos.
Puedes considerarlo como una función anónima; aquí hay más información: Wikipedia - Función anónima
Se refiere al cálculo lambda , que es un sistema formal que solo tiene expresiones lambda, que representan una función que toma una función como ú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 funciones anónimas literales. 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 a 50 ):
((lambda (x y) (* x y)) 5 10)
Solo porque no puedo ver un ejemplo de C ++ 11 aquí, seguiré adelante y publicaré este buen ejemplo desde here . Después de buscar, es el ejemplo más claro de lenguaje específico que pude encontrar.
Hola, Lambdas, versión 1
template<typename F>
void Eval( const F& f ) {
f();
}
void foo() {
Eval( []{ printf("Hello, Lambdas/n"); } );
}
Hola, Lambdas, versión 2:
void bar() {
auto f = []{ printf("Hello, Lambdas/n"); };
f();
}
Tengo problemas para envolver mi cabeza alrededor de las expresiones lambda porque trabajo en Visual FoxPro, que tiene la sustitución de macros y las funciones ExecScript {} y Evaluate (), que parecen tener el mismo propósito.
? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");
FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)
Un beneficio definitivo del uso de lambdas formales es (supongo) la verificación en tiempo de compilación: Fox no sabrá si escribe la cadena de texto anterior hasta que intenta ejecutarlo.
Esto también es útil para el código controlado por datos: puede almacenar rutinas completas en campos memo en la base de datos y luego evaluarlas en tiempo de ejecución. Esto le permite ajustar parte de la aplicación sin tener acceso a la fuente. (Pero ese es otro tema en conjunto).
Un ejemplo de un lambda en Ruby es el siguiente:
hello = lambda do
puts(''Hello'')
puts(''I am inside a proc'')
end
hello.call
Generará la siguiente salida:
Hello
I am inside a proc
Un lambda es un tipo de función, definido en línea. Junto con un lambda, también suele tener algún tipo de tipo de variable que puede contener una referencia a una función, lambda o de otro tipo.
Por ejemplo, aquí hay un código de 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, pasando no solo dos números, sino a qué método llamar dentro de la Calculadora para obtener los resultados del cálculo.
En C # 2.0 obtuvimos métodos anónimos, lo que acorta 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 que hacen 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);
}
Yo tambien lo tengo Lo he probado en JS con este:
var addAndMult = function(x) {
return (function(y) {
return (function(z) {
return (x+y)*z;
});
});
};
Agrega de 2 a 4 y luego reduce el resultado por 6. Sin embargo, a veces me resulta difícil de leer :(
También he hecho una función interesante para cada uno:
var forEach = function(arr) {
return (function(x) {
for (var i=0; arr[i]; i++) {
x(arr[i]);
}
});
}
forEach ([1,2,3,4,5]) (console.log);
Este método itera una matriz y realiza una acción, en el caso de que se imprima en la consola. Ahora yo también entiendo por qué los labmdas son poderosos.