2009-12-05 20 views

Respuesta

12

Son bastante intercambiables. La respuesta es que functionhabilita la lambda para ser compilada por bytes, mientras que las otras dos no (y son equivalentes). Nota: esto no significa que function en realidad compila byte la lambda.

¿Cómo podría darse cuenta de eso? Una pequeña introspección de ceceo de Emacs proporciona algunas pistas. Para iniciar: C-h función f RET:

función es una forma especial en 'C código fuente'.

(función arg)

Como 'cita', pero preferido para objetos que son funciones. En la compilación byte , 'function' hace que se compile su argumento . 'quote' no puede hacer eso.

Ok, así que esa es la diferencia entre (function (lambda ...)) y '(lambda ...), el primero le dice al compilador de bytes que puede recopilar de forma segura la expresión. Considerando que las ' expresiones ed no necesariamente pueden ser compilados (ya que éste podría ser simplemente una lista de números

¿Qué pasa sólo los desnudos (lambda ...)Ch f lambda RET presenta:.?

lambda es una macro Lisp en `subr.el'.

(args lambda [docstring] [interactivo] cuerpo)

devolver un lambda expresión. un llamada de el formulario (lambda args docstring cuerpo interactivo) es autocitado; el resultado de la evaluación de la expresión lambda es la expresión en sí. La expresión lambda puede ser entonces tratada como una función, es decir, almacenado como el valor de la función de un símbolo, pasó a 'funcall' o 'mapcar', etc.

Por lo tanto, (lambda ...) y '(lambda ...) son equivalente.

Además, no es la notación #'(lambda ...), que es el azúcar sintáctica para (function (lambda ...)).

Para obtener más información sobre las funciones en Emacs lisp, lea Functions info pages.

sólo para comprobar todo esto, puede escribir lo siguiente en la * búfer * scratch y evaluar las expresiones:

(caddr '(lambda (x) (+ x x))) 
(+ x x) 

(caddr (lambda (x) (+ x x))) 
(+ x x) 

(caddr (function (lambda (x) (+ x x)))) 
(+ x x) 

(equal '(lambda (x) (+ x x)) 
     (function (lambda (x) (+ x x)))) 
t 

(equal '(lambda (x) (+ x x)) 
     (lambda (x) (+ x x))) 
t 

Así, las tres variantes del uso de lambda acaba de construir listas que pueden ser utilizados como funciones (una de las cuales puede ser compilada por byte).

+0

¿Pero no está usando una comilla simple delante de una expresión que hace que el intérprete LISP la devuelva como está y no la evalúe? Eso significaría que '(+ 1 2) volverá como (+ 1 2) y (+ 1 2) regresará como 3 ... – Joscha

+0

@Joscha, no estoy seguro de qué parte está comentando. Lambda es autocitado, lo que significa que cuando el intérprete evalúa una expresión lambda, el resultado es la misma expresión lambda. Creo que esto es diferente de la mayoría de los otros cefaleas debido a la búsqueda variable utilizada por Emacs (alcance indefinido y extensión dinámica). El esquema crea pequeños cierres con cierta información del entorno debido a la extensión léxica (creo). –

+2

'(lambda ...)' es en realidad equivalente a '(function (lambda ...))' not ''(lambda ...)' como se puede probar evaluando '(macroexpand (lambda (x) (+ xx))) ' – nschum

3

Bueno (quote (lambda...)) y (lambda...) no son equivalentes (cuando se compila byte). Las lambdas citadas no son compiladas por bytes, mientras que todo lo demás sí lo es.

Por ejemplo:

(defun foo (a) 
    (byte-code-function-p a)) 

(defun bar() 
    (foo '(lambda() (ignore 'me)))) 

(defun bar2() 
    (foo (lambda() (ignore 'me)))) 

(defun bar3() 
    (foo (function (lambda() (ignore 'me))))) 

(defun bar4() 
    (foo #'(lambda() (ignore 'me)))) 

(byte-compile 'bar) 
(byte-compile 'bar2) 
(byte-compile 'bar3) 
(byte-compile 'bar4) 

(bar) ; -> nil 

(bar2) ; -> t 
(bar3) ; -> t 
(bar4) ; -> t 

Por lo general, no quiere citar un lambda menos que la función que se va a pasar el lambda está haciendo algo más con él que apenas funcall ella.

+1

Creo que esto ha cambiado con el tiempo. Al mirar '(info" (elisp) Anonymous Functions ")', dice "Hoy en día es posible omitir 'function' por completo ... Esto es porque 'lambda' en sí mismo implica 'función'." Esa página es un poco confusa en la primera lectura, pero sus ejemplos son una buena aclaración :) (a) '(function (lambda ...))' es una variante de '(quote (lambda ...)) 'que permite la compilación de bytes. (b) * un * -quoted '(lambda ...)' es (hoy en día) lo mismo que '(function (lambda ...))'! – phils

Cuestiones relacionadas