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

53

Hasta ahora he oído hablar de:

  • cálculo Lambda
  • programación Lambda
  • expresiones Lambda
  • funciones Lambda

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

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

enlace

¿Puede alguien definir brevemente qué son las cosas lambdas y dar un lugar donde pueda ser útil?

    
pregunta jokoon 10.12.2010 - 11:34

3 respuestas

43
  • cálculo Lambda

El cálculo lambda es un modelo de cálculo 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 están directa o indirectamente inspirados en el cálculo lambda.

El cálculo lambda en su forma más básica tiene dos operaciones: Abstracción (creando una función (anónima)) y aplicación (aplicar una función). La abstracción se realiza utilizando el operador λ, dando su 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 lambda se usa para cree funciones anónimas en muchos idiomas basados en lisp por el mismo motivo).

  • programación Lambda

Este no es un término comúnmente usado, pero asumo que significa programar usando funciones anónimas o programando usando funciones de orden superior.

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

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

Por ejemplo, si desea ordenar un vector de vectores por el elemento i th de cada vector (donde i es 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 elemento i th, tendría que tomar tres argumentos ( i y 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 suministrar de alguna manera el argumento i a la función antes de pasarlo a la función de clasificación, pero no podemos hacerlo con funciones de C simples.

Para resolver esto, C ++ introdujo el concepto de "objetos de función" o "functores". Un functor es básicamente un objeto que tiene un método operator() . Ahora podemos definir una clase CompareByIthElement , que toma el argumento i como un argumento constructor y luego toma los dos vectores para compararlos como argumentos al método operator() . Para ordenar un vector de vectores por el elemento i th ahora podemos crear un objeto CompareByIthElement con i como 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 funciones técnicamente (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 funciones como argumentos se definen utilizando plantillas para que funcionen con punteros de función y objetos de función.

Ahora a lambdas:

Definir una clase entera para comparar por el elemento i th es un poco detallado si solo lo vas a usar una vez para ordenar un vector. Incluso en el caso de que solo necesite un puntero a función, la definición de una función nombrada 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 realmente no existe una buena razón para abstraer la lógica en su propia función (aparte de que no puede tener punteros de función sin definir una función).

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

  1. Defina una clase que tenga dos variables miembro ( x1 y x2 ) y un operator() con los argumentos ( y1 y y2 ) y el cuerpo bla .
  2. Cree una instancia de la clase, configurando las variables miembro x1 y x2 a los valores de las variables x1 y x2 actualmente en el alcance.

Entonces, los lambdas se comportan como objetos de función, excepto que no se puede acceder a la clase que se genera para implementar un lambda de ninguna otra manera que no sea el uso del lambda. En consecuencia, cualquier función que acepte funtores como argumentos (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.

    
respondido por el sepp2k 10.12.2010 - 14:02
18

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

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

Esto dará como resultado aproximadamente 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 necesita some_functor solo para esta llamada a std::for_each() , entonces la función lambda tiene varias ventajas:

  • lo que se hace en el bucle se especifica justo donde se llama a la función de bucle
  • te libera de escribir algo del código de la placa de la caldera
  • no hay ningún funtor en algún espacio de nombres que haga que todos los que miran el código se pregunten para qué se necesita
respondido por el sbi 10.12.2010 - 12:16
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 como tal

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

Con un lambda simplemente harías

reduce(lambda x, y: a+b, [5,3,2])
    
respondido por el Martin Konecny 20.05.2013 - 06:22

Lea otras preguntas en las etiquetas