2009-05-26 8 views
13

¿Por qué debería usar # 'junto con lambda? Por lo general, está escrito de esa manera, así que supongo que es una buena forma. Pero estas líneas parecen iguales a mí:¿Por qué usar # 'con lambda?

> (mapcar #'(lambda (x) (+ x 1)) '(1 2 3)) 
(2 3 4) 
> (mapcar (lambda (x) (+ x 1)) '(1 2 3)) 
(2 3 4) 

¿Alguien quiere aclarar a un principiante sobre la diferencia?

Respuesta

11

#' es la abreviatura de function, que devuelve un puntero a una función (en lugar de aplicarlo). lambda devuelve una función, y es habitual querer un puntero a esa función. Como esto es tan común, también hay una macro (en espacio variable) que lo hace por usted, que también se llama lambda. Ambas líneas de código son idénticas.

Lo que es mejor se reduce al Lisp-1/Lisp-2 debate: en Common Lisp puede hacerlo, gracias a la macro. Como siempre, sé consistente.

+0

Lisp no tiene punteros de función, las macros no están en espacio variable, ... –

14

Es diferente en varios dialectos Lisp. A continuación se utiliza Common Lisp:

Primera #' es un corto notación para (función ...). Así que los siguientes son solamente textualmente diferente, pero Common Lisp les dice lo mismo:

#'(lambda (x) (* x 2)) 

y

(function (lambda (x) (* x 2))) 

#' es un readmacro, y transforma cuando el código Lisp es leído por el sistema Lisp.

Si Lisp evalúa

(function (lambda (x) (* x 2))) 

el sistema Lisp crea un objeto de función y función devuelve como su valor.

Por lo tanto, siempre que necesite una función como valor, debe escribirla así. Se necesita una función como valor, cuando desea pasarla a otras funciones como argumento, cuando desea devolverla desde una función o cuando desea almacenarla en una variable. Ejemplos:

(map #'(lambda (x) (* x 2)) '(1 2 3)) 

(defun (y) #'(lambda (x) (* x y))) 

(defparameter *twice-fn* #'(lambda (x) (* x 2))) 

Ahora, ¿qué es (lambda (x) (* x 2))?

Es dos cosas diferentes según el contexto.

expresión Lambda

La expresión lambda se puede utilizar en lugar de un nombre de función:

(function foo) and (function (lambda (x) (* x 2))) 

y

(foo 17) and ((lambda (x) (* x 2)) 17) 

Sobre dos son sintaxis legal Common Lisp. Allí se puede usar una expresión lambda directamente.

Nota que las dos formas siguientes son ilegal en Common Lisp:

(#'(lambda (x) (* x 2)) 17) ; illegal in Common Lisp 

(function #'(lambda (x) (* x 2))) ; illegal in Common Lisp 

Macro

Durante el proceso de normalización Common Lisp una macro LAMBDA ha sido añadido (que no era parte de la primera descripción, CLtL1, de Common Lisp). Hace posible escribir un código ligeramente más corto. Ejemplo:

(lambda (x) (* x 2)) 

En el caso anterior, LAMBDA es una macro. Durante la expansión macro que se ampliará a:

(function (lambda (x) (* x 2))) 

recordar que en forma de función anterior, el lambda interior es parte de una expresión lambda, denota la función y no serán expandidas.

lo tanto, ahora los tres ejemplos de arriba se puede escribir como:

(map (lambda (x) (* x 2)) '(1 2 3)) 

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

(defparameter *twice-fn* (lambda (x) (* x 2))) 

Es un poco más corto, se ve un poco más despejado y se ve un poco más similar al código de Scheme. Simplemente se ve un poco mejor para los programadores que utilizan para leer y escribir código Scheme.

Resumen

a) (function (lambda (x) (x 2 *))) es el camino 'verdadero' para escribir código que devuelve una función como un valor.

b) # '(lambda (x) (* x 2)) es una notación más corta de arriba

c) (lambda (x) (* x 2)) es aún más corto, pero utiliza expansión de macro para crear la forma de a).