¿Qué es una lambda y por qué sería útil? [cerrado]

56

Hasta ahora escuché sobre:

  • Cálculo lambda
  • Programación lambda
  • Expresiones lambda
  • Funciones lambda

Todo lo cual parece estar relacionado con la programación funcional ...

Aparentemente se integrará en C ++ 1x, por lo que podría entenderlo ahora:

http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

¿Alguien puede definir brevemente qué son las cosas lambdas y dar un lugar donde puede ser útil?

jokoon
fuente
2
Tenga en cuenta que la terminología históricamente proviene de querer una buena manera de hablar sobre la función representada por una expresión. La función representada por x + 1 se escribe lambda x. x + 1.
kasterma
De manera lambda, una función come otra función y / o un valor de entrada, produce otra función. Esto continúa hasta que una función produce una solución. Además, huevos de cocodrilo .
SD
No entiendo nada. Creo que iré a tomar un giroscopio, me gusta el cordero, duh.

Respuestas:

44
  • Cálculo lambda

El cálculo lambda es un modelo informático inventado por Alonzo Church en los años 30. La sintaxis y la semántica de la mayoría de los lenguajes de programación funcionales se inspiran directa o indirectamente en el cálculo lambda.

El cálculo lambda en su forma más básica tiene dos operaciones: abstracción (crear una función (anónima)) y aplicación (aplicar una función). La abstracción se realiza utilizando el operador λ, dando nombre al cálculo lambda.

  • Expresiones lambda
  • Funciones lambda

Las funciones anónimas a menudo se llaman "lambdas", "funciones lambda" o "expresiones lambda" porque, como dije anteriormente, λ era el símbolo para crear funciones anónimas en el cálculo lambda (y la palabra lambdase usa para crear funciones anónimas en muchos lisp). basados ​​en idiomas por la misma razón).

  • Programación lambda

Este no es un término de uso común, pero supongo que significa programar usando funciones anónimas o programar usando funciones de orden superior.


Un poco más de información sobre lambdas en C ++ 0x, su motivación y cómo se relacionan con los punteros de función (mucha de esto es probablemente una repetición de lo que ya sabe, pero espero que ayude a explicar la motivación de lambdas y cómo difieren). de punteros de función):

Los punteros de función, que ya existían en C, son bastante útiles para, por ejemplo, pasar una función de comparación a una función de clasificación. Sin embargo, hay límites para su utilidad:

Por ejemplo, si desea ordenar un vector de vectores por el ielemento th de cada vector (donde ies un parámetro de tiempo de ejecución), no puede resolver esto con un puntero de función. Una función que compara dos vectores por su ielemento th, necesitaría tomar tres argumentos ( iy los dos vectores), pero la función de clasificación necesitaría una función que tome dos argumentos. Lo que necesitaríamos es una forma de proporcionar de alguna manera el argumento ia la función antes de pasarla a la función de clasificación, pero no podemos hacer esto con funciones simples de C.

Para resolver esto, C ++ introdujo el concepto de "objetos de función" o "functores". Un functor es básicamente un objeto que tiene un operator()método. Ahora podemos definir una clase CompareByIthElement, que toma el argumento icomo un argumento constructor y luego toma los dos vectores para compararlos como argumentos del operator()método. Para ordenar un vector de vectores por el ielemento th ahora podemos crear un CompareByIthElementobjeto con iun argumento y luego pasar ese objeto a la función de clasificación.

Dado que los objetos de función son solo objetos y no técnicamente funciones (aunque están destinados a comportarse como ellos), no puede hacer que un puntero de función apunte a un objeto de función (por supuesto, puede tener un puntero a un objeto de función, pero tendría un tipo como CompareByIthElement*y, por lo tanto, no sería un puntero de función).

La mayoría de las funciones en la biblioteca estándar de C ++ que toman las funciones como argumentos se definen usando plantillas para que funcionen con punteros de función y objetos de función.

Ahora a lambdas:

Definir una clase completa para comparar por el ielemento th es un poco detallado si solo lo va a usar una vez para ordenar un vector. Incluso en el caso de que solo necesite un puntero de función, la definición de una función con nombre es subóptima si solo se usa una vez porque a) contamina el espacio de nombres yb) la función generalmente será muy pequeña y no hay realmente una buena razón para abstraer la lógica en su propia función (aparte de eso no puede tener punteros de función sin definir una función).

Entonces para arreglar esto se introdujeron lambdas. Las lambdas son objetos de función, no punteros de función. Si utiliza un literal lambda [x1, x2](y1,y2){bla}, se genera un código similar que básicamente hace lo siguiente:

  1. Defina una clase que tenga dos variables miembro ( x1y x2) y una operator()con los argumentos ( y1y y2) y el cuerpo bla.
  2. Cree una instancia de la clase, estableciendo las variables miembro x1y x2los valores de las variables x1y x2actualmente en el alcance.

Por lo tanto, las lambdas se comportan como objetos de función, excepto que no puede acceder a la clase que se genera para implementar una lambda de otra manera que no sea el uso de la lambda. En consecuencia, cualquier función que acepte functores como argumentos (que básicamente significa cualquier función que no sea C en la biblioteca estándar) aceptará lambdas, pero cualquier función que solo acepte punteros de función no lo hará.

sepp2k
fuente
¿Se utilizan funciones anónimas con punteros de función? Sí no, Cuál es la diferencia ?
jokoon
1
@jokoon: No, las funciones anónimas no se pueden pasar como parámetros a funciones que solo toman punteros de función. Sin embargo, la mayoría de las funciones que toman funciones como argumentos se definen usando plantillas para que puedan tomar cualquier tipo de objeto de función como argumento, no solo puntero de función. Es decir, en la mayoría de los lugares donde puede usar punteros de función ( std::sortpor ejemplo), podrá usar funciones anónimas en su lugar. Sin embargo, al definir una función que debería tomar una función anónima como argumento, debe usar una plantilla o usarla std::functioncomo tipo de argumento.
sepp2k
entonces un puntero de función no puede contener una lambda ...
jokoon
1
+1 Excelente explicación: tampoco pude descubrirlo.
Michael K
2
Estoy con Michael en esto. Esto es muy completo. +1de mi parte.
sbi
18

Básicamente, las funciones lambda son funciones que crea "sobre la marcha". En C ++ 1x podrían usarse para mejorar su soporte para la programación funcional:

std::for_each( begin, end, [](int i){std::cout << i << '\n';} );

Esto dará como resultado un código similar a este:

struct some_functor {
  void operator()(int i) {std::cout << i << '\n';}
};

std::for_each( begin, end, some_functor() );

Si some_functorsolo necesita esta llamada std::for_each(), entonces esa función lambda tiene varias ventajas sobre ella:

  • lo que se hace en el bucle se especifica justo donde se llama la función de bucle
  • te libera de escribir algo del código de la placa de la caldera
  • no hay un functor en algún espacio de nombres que haga que todos mirando el código se pregunten para qué se necesita
sbi
fuente
7

Una función lambda es otro nombre para una función anónima, esencialmente una función sin nombre.

Por lo general, usa esto en idiomas donde solo necesitará usar la función una vez. Por ejemplo en lugar de

def add(a, b)
  return a+b

y luego pasar esa función a otra función así

reduce(add, [5,3,2])

Con una lambda simplemente harías

reduce(lambda x, y: a+b, [5,3,2])
Martin Konecny
fuente