¿Cuál es la diferencia entre una función y una lambda?

54

Estoy un poco confundido acerca de 'función' y 'lambda'. He visto algunos ejemplos que muestran que la palabra clave de esquema lambdafunciona de manera muy similar a la palabra clave de JavaScript function, pero realmente no sé cómo se relacionan.

Me dicen que 'función' y 'método' se pueden usar indistintamente cuando se habla de objetos en .net. Me pregunto si 'lambda' y 'función' significan lo mismo de manera similar. Me pregunto si 'lambda' tiene algún significado esotérico, ya que la letra griega lambda (λ) aparece en tantos avatares en este sitio. Para hacer las cosas aún más confusas, en .net, las partes funcionales de C # se refieren a expresiones de funciones pasadas a otra función como 'expresiones lambda', por lo que la palabra realmente parece estar por todas partes.

También estoy vagamente familiarizado con el término 'cálculo lambda'.

¿Cuál es la diferencia entre una función y una lambda?

Galletas De Harina De Arroz
fuente
3
Nitpick: se denominan "expresiones lambda", no "funciones lambda", al menos en lo que respecta a la documentación de C # / .NET.
Oded
@ TWith2Sugars: lee el mensaje. Su respuesta es de baja calidad, ya que es solo un enlace, por lo que se convirtió en un comentario.
Oded
17
I wonder if 'lambda' has some esoteric meaning, seeing that the Greek letter lambda (λ) appears in so many avatars on this site.Uno esperaría que fuera en referencia al cálculo lambda, pero tengo la extraña sensación de que Half Life es el culpable de los avatares lambda.
Yannis
3
Muy bien, aquí está el enlace a la respuesta stackoverflow
TWith2Sugars
@ZaphodBeeblebrox: sospecho que tienes razón sobre la influencia de Half-Life. : /
FrustratedWithFormsDesigner

Respuestas:

44

La palabra "lambda" o "expresiones lambda" con mayor frecuencia se refiere a funciones anónimas. Entonces, en ese sentido, una lambda es un tipo de función, pero no todas las funciones son una lambda (es decir, las funciones nombradas generalmente no se denominan lambdas). Dependiendo del idioma, las funciones anónimas a menudo se implementan de manera diferente a las funciones con nombre (particularmente en idiomas donde las funciones anónimas son clausuras y las funciones con nombre no lo son), por lo que hacer referencia a ellas con diferentes términos puede tener sentido.

La diferencia entre la palabra clave lambda del esquema y la palabra clave de función de Javascript es que esta última se puede usar para crear funciones anónimas y funciones con nombre, mientras que la primera solo crea funciones anónimas (y usaría definepara crear funciones con nombre).

El cálculo lambda es un lenguaje mínimo de programación / modelo matemático de computación, que utiliza funciones como su única "estructura de datos". En el cálculo lamdba, el símbolo lambda se usa para crear funciones (anónimas). De aquí proviene el uso del término "lambda" en otros idiomas.

sepp2k
fuente
1
Eso es extremadamente duro. Usas define(o letuno de sus parientes, o una definición interna) para crear nombres, eso es todo. No hay nada especial definecon respecto a las funciones.
Eli Barzilay
2
@EliBarzilay Bueno, define tienen una forma especial para la definición de funciones (es decir, se puede escribir (define (f x) (foo))en lugar de (define f (lambda (x) (foo)))), pero mi punto es que no se puede crear una función llamada usando lambdasolo, es decir, que es posible que algo no escribir como (lambda f (x) (foo))para definir una función llamada feso toma un argumento como puedes con la functionpalabra clave de Javascript .
sepp2k
1
definetiene eso como un azúcar sintáctico, por lo que no es tan importante como su función como herramienta de enlace de nombres para todos los valores. En cuanto a lambdano crear un nombre por sí mismo: esa es una característica importante, ya que separa los nombres de las formas de función ... IMO JS está haciendo lo correcto al permitir la separación y al mismo tiempo acepta un nombre opcional para aquellas masas que estarían horrorizadas por La idea de una función sin nombre. (Y afortunadamente el tamaño de esas masas está en una disminución general ...)
Eli Barzilay
18

Una lambda es simplemente una función anónima, una función sin nombre.

Oded
fuente
44
Nota: los lambda pueden contener un estado (como en el cierre) que se enganchan del contexto donde se declaran.
Martin York
77
También podría una función con nombre, si el lenguaje le permite declarar funciones anidadas.
cHao
44
Felicitaciones por ingresar a la pestaña de revisión de "publicaciones de baja calidad" con una respuesta votada.
Yannis
@ZaphodBeeblebrox - No intencionalmente, te puedo asegurar.
Oded
En realidad, no, una lambdaexpresión en Scheme es como una functionexpresión sin nombre, pero no hay nada que te impida luego darles un nombre. Por ejemplo var f = [function(x){return x;}][0]. Se podría argumentar que el valor de la función en sí no tiene nombre, pero eso sería cierto para todas las funciones ...
Eli Barzilay
8

En C #, la función anónima es un término general que incluye expresiones lambda y métodos anónimos (los métodos anónimos son instancias delegadas sin declaración de método real).

Las expresiones lambda se pueden dividir en expresión lambda y declaración lambda

Expresión lambda:

(int x, string y) => x == y.Length 

La declaración lambda es similar a la expresión lambda, excepto que las declaraciones están encerradas entre llaves:

(int x, string y) => {
         if (x == y.Length) {
             Console.WriteLine(y);
         }
}

Cuando hablamos de expresiones lambda en JavaScript, eso básicamente significa usar una función como argumento en una llamada a otra función.

var calculate = function(x, y, operation){
    return operation(x, y);
}

// we're passing anonymous function as a third argument
calculate(10, 15, function(x, y) {
    return x + y;
}); // 25
Christian P
fuente
+1 Mucha gente ha mencionado que las lambdas son funciones anónimas, pero hay más que eso. El cuerpo (lado derecho) de una lambda es a menudo una expresión más que un bloque de enunciados. El cuerpo de una función con nombre que es una expresión generalmente se permite (o se requiere) en lenguajes funcionales, pero no en lenguajes imperativos.
Zantier
4

TL; DR Como otros señalaron: la notación lambda es solo una forma de definir funciones sin verse obligado a darles un nombre.

Versión larga

Me gustaría elaborar un poco sobre este tema porque me parece muy interesante. Descargo de responsabilidad: he tomado mi curso sobre cálculo lambda hace mucho tiempo. Si alguien con mejor conocimiento encuentra alguna imprecisión en mi respuesta, siéntase libre de ayudarme a mejorarla.

Comencemos con expresiones, por ejemplo, 1 + 2y x + 2. Los literales como 1y 2se llaman constantes porque están vinculados a valores fijos específicos.

Un identificador como xse llama variable y para evaluarlo primero debe vincularlo a algún valor. Entonces, básicamente no puedes evaluar x + 1mientras no sepas qué xes.

La notación lambda proporciona un esquema para vincular valores de entrada específicos a variables. Se puede formar una expresión lambda agregando λx .delante de una expresión existente, por ejemplo λx . x + 1. Variable xse dice que es libre en x + 1y con destino enλx . x + 1

¿Cómo ayuda esto a evaluar expresiones? Si alimenta un valor a la expresión lambda, así

(λx . x + 1) 2

entonces puede evaluar la expresión completa reemplazando (vinculando) todas las apariciones de la variable xcon el valor 2:

(λx . x + 1) 2
      2 + 1
      3

Entonces, la notación lambda proporciona un mecanismo general para vincular cosas a variables que aparecen en un bloque de expresión / programa. Dependiendo del contexto, esto crea conceptos visualmente diferentes en los lenguajes de programación:

  • En un lenguaje puramente funcional como Haskell, las expresiones lambda representan funciones en el sentido matemático: se inyecta un valor de entrada en el cuerpo de la lambda y se produce un valor de salida.
  • En muchos lenguajes (por ejemplo, JavaScript, Python, Scheme), evaluar el cuerpo de una expresión lambda puede tener efectos secundarios. En este caso, se puede usar el término procedimiento para marcar la diferencia con funciones puras puras.

Además de las diferencias, la notación lambda se trata de definir parámetros formales y vincularlos a parámetros reales.

El siguiente paso es darle un nombre a una función / procedimiento. En varios idiomas, las funciones son valores como cualquier otro, por lo que puede asignar un nombre a una función de la siguiente manera:

(define f (lambda (x) (+ x 1)))      ;; Scheme

f = \x -> x + 1                      -- Haskell

val f: (Int => Int) = x => x + 1     // Scala

var f = function(x) { return x + 1 } // JavaScript

f = lambda x: x + 1                  # Python

Como señaló Eli Barzilay, esta definición solo une el nombre fa un valor, que resulta ser una función. Entonces, a este respecto, las funciones, números, cadenas, caracteres son todos valores que pueden vincularse a los nombres de la misma manera:

(define n 42)   ;; Scheme

n = 42          -- Haskell

val n: Int = 42 // Scala

var n = 42      // JavaScript

n = 42          # Python

En estos idiomas también puede vincular una función a un nombre utilizando la notación más familiar (pero equivalente):

(define (f x) (+ x 1))         ;; Scheme

f x = x + 1                    -- Haskell

def f(x: Int): Int = x + 1     // Scala

function f(x) { return x + 1 } // JavaScript

def f(x): return x + 1         # Python

Algunos lenguajes, por ejemplo, C, solo admiten la última notación para definir funciones (con nombre).

Cierres

Algunas observaciones finales sobre cierres . Considera la expresión x + y. Este contiene dos variables libres. Si te unes xusando la notación lambda obtienes:

\x -> x + y

Esto no es (todavía) una función porque todavía contiene una variable libre y. También puede hacer una función al vincularlo y:

\x -> \y -> x + y

o

\x y -> x + y

que es lo mismo que la +función.

Pero puede vincular, por ejemplo, yde otra manera (*):

incrementBy y = \x -> x + y

El resultado de aplicar la función incrementBy a un número es un cierre, es decir, una función / procedimiento cuyo cuerpo contiene una variable libre (por ejemplo y) que se ha vinculado a un valor del entorno en el que se definió el cierre.

Así incrementBy 5es la función (cierre) que incrementa los números en 5.

NOTA (*)

Estoy engañando un poco aquí:

incrementBy y = \x -> x + y

es equivalente a

incrementBy = \y -> \x -> x + y

entonces el mecanismo de enlace es el mismo. Intuitivamente, pienso en un cierre como la representación de un trozo de una expresión lambda más compleja. Cuando se crea esta representación, algunos de los enlaces de la expresión madre ya se han establecido y el cierre los usa más tarde cuando se evalúa / invoca.

Giorgio
fuente
Solo soy un principiante, pero creo que esto puede ser un poco confuso si estás tratando de entender el cálculo λ en el sentido matemático, ya que lo que llamas constantes se llaman variables y se denotan con los símbolos a, b, c ... Lo que las variables de llamada serían una variable indeterminada x . Por otro lado, 1 es λ f x . f x , 2 es λ f x . f ( f x ) y así sucesivamente.
jinawee
@jinawee: Admito que no busqué la definición exacta. Recuerdo haber usado los términos variables y constantes en lógica. Allí, una constante es un símbolo que se asigna a un dominio, mientras que una variable es un símbolo que se puede cuantificar. Pero, nuevamente, (1) hace mucho tiempo que tomé un curso sobre lógica, y (2) el cálculo lambda no necesita seguir 1-1 los conceptos de lógica matemática. Si me señala una referencia, puedo intentar arreglar mi terminología.
Giorgio
0

"Lambda" en programación generalmente significa "función lambda" (o también "expresión lambda", "término lambda"). Cuando la función es un bloque de código con nombre definido antes de su uso, la "función lambda" es un bloque de código (o una expresión) definido en lugar del uso que se puede usar como ciudadano de primera clase en un lenguaje de programación.

En JavaScript ES6 (2015) hay una sintaxis corta para definir lambdas llamada "Funciones de flecha" . En C #, dicha sintaxis se introdujo en .NET 3.0 (alrededor de 2006) .

En matemáticas, una noción de "función" tiene varios significados donde uno de los significados es sobre la notación de una función (es decir, cómo escribirla), luego la "función lambda" (en cálculo) es un tipo especial de notación de función. Para más discusión, verifique las funciones lambda en lenguajes de programación .

battlmonstr
fuente