2009-12-05 6 views

Répondre

12

Ils sont assez interchangeables. La réponse est que functionpermet à que le lambda soit compilé, alors que les deux autres ne le sont pas (et sont équivalents). Note: cela ne signifie pas que function réellement octet compiler le lambda.

Comment peut-on comprendre cela? Un peu d'introspection Emacs Lisp fournit quelques indices. Pour commencer: fonction C-h f RET:

fonction

est une forme particulière en "C code de source.

(fonction arg)

Comme 'citation', mais pratique pour objets qui sont des fonctions. En octets compilation, 'fonction' provoque la compilation de son argument . 'citation' ne peut pas faire cela.

Ok, donc c'est la différence entre (function (lambda ...)) et '(lambda ...), le premier indique au compilateur d'octets qui peut en toute sécurité compiler l'expression. Alors que les ' expressions ées ne peuvent pas être compilés nécessairement (car ils pourraient juste être une liste de numéros

Qu'en est-il seulement les (lambda ...)nues Ch f lambda RET montre:.?

lambda est une macro Lisp en (lambda corps args [docstring] [interactive] ) `subr.el.

retour une expression lambda. a appel de le formulaire (lambda args docstring corps interactif) est auto-devis; le résultat de l'évaluation de l'expression lambda est l'expression elle-même. L'expression lambda peut alors être traitée en fonction, par exemple, stockée sous forme la valeur de fonction d'un symbole, passé à « funcall » ou « mapcar », etc.

Par conséquent, (lambda ...) et '(lambda ...) sont équivalent.

En outre, il existe la notation #'(lambda ...), qui est le sucre syntaxique pour (function (lambda ...)).

Pour plus d'informations sur les fonctions dans Emacs lisp, consultez le Functions info pages.

Juste pour vérifier tout cela, vous pouvez taper la commande suivante dans la mémoire tampon scratch * * et évaluer les expressions:

(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 

Ainsi, les trois variantes d'utilisation lambda simplement construire des listes qui peuvent être utilisés comme fonctions (dont l'une peut être compilée en octets).

+0

Mais n'utilise pas de guillemet simple devant une expression pour que l'interpréteur LISP le renvoie tel quel et ne l'évalue pas? Cela voudrait dire que '(+ 1 2) retournera comme (+ 1 2) et (+ 1 2) retournera 3 ... – Joscha

+0

@Joscha, je ne sais pas sur quelle partie vous commentez. Lambda est auto-quotant, ce qui signifie simplement que lorsque l'interpréteur évalue une expression lambda, le résultat est la même expression lambda. Je crois que c'est différent de la plupart des autres lisps en raison de la recherche de variables utilisée par Emacs (portée indéfinie et étendue dynamique). Scheme crée de petites fermetures avec quelques informations sur l'environnement en raison de l'étendue lexicale (je crois). –

+2

'(lambda ...)' est en fait équivalent à '(fonction (lambda ...))' pas ''(lambda ...)' comme vous pouvez l'essayer en évaluant '(macroexpand (lambda (x) (+ xx))) ' – nschum

3

Le puits (quote (lambda...)) et (lambda...) ne sont pas équivalents (en cas de compilation d'octets). Les lambdas cités ne sont pas compilés octets alors que tout le reste l'est.

Par exemple:

(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 

Vous ne voulez pas l'habitude de citer un lambda à moins que la fonction que vous allez passer le lambda est en train de faire autre chose avec elle que juste funcall il.

+1

Je crois que cela a changé au fil du temps. En regardant '(info" (elisp) Fonctions anonymes ")', 'il est dit" De nos jours, il est possible d'omettre 'function' entièrement ... C'est parce que 'lambda' lui-même implique 'fonction'. " Cette page est légèrement déroutante en première lecture, mais vos exemples apportent une bonne clarification :) (a) '(fonction (lambda ...))' est une variante de '(quote (lambda ...)) 'qui permet la compilation d'octets. B) * un * -quoted '(lambda ...)' est (de nos jours) identique à '(fonction (lambda ...))'! – phils

Questions connexes