2009-12-05 2 views

risposta

12

Sono abbastanza intercambiabili. La risposta è che functionabilita il lambda da compilare in byte, mentre gli altri due non (e sono equivalenti). Nota: questo non significa che in realtà il byte function compili il lambda.

Come potrebbe capirlo? Una piccola introspezione di Emacs fornisce alcuni indizi. Inizio: C-h funzione f RET:

funzione è una forma speciale in 'C codice sorgente'.

(funzione arg)

Come 'quote', ma preferito per oggetti che sono funzioni. Nella compilazione del byte , 'funzione' fa compilare l'argomento . 'quote' non può farlo.

Ok, in modo che la differenza tra (function (lambda ...)) e '(lambda ...), il primo dice al compilatore di byte che si può compilare in modo sicuro l'espressione. Considerando che le ' espressioni Ed non possono necessariamente essere compilati (perché potrebbe essere proprio un elenco di numeri

Che dire solo le nude (lambda ...)Ch f lambda RET spettacoli:.?

lambda è una macro Lisp in `subr.el'.

(args lambda [docstring] [interattivo] corpo)

ritorno una lambda espressione. a chiamata di il modulo (lambda args docstring corpo interattivo) è auto-quotante; il risultato di di valutazione dell'espressione lambda è l'espressione stessa. L'espressione lambda può quindi essere trattato come una funzione, cioè, memorizzato come valore funzione di un simbolo, passato a 'funcall' o 'mapcar', ecc

Pertanto, (lambda ...) e '(lambda ...) sono equivalente.

Inoltre, c'è la notazione #'(lambda ...), che è zucchero sintattico per (function (lambda ...)).

Per ulteriori informazioni sulle funzioni in Emacs lisp, leggere il numero Functions info pages.

solo per controllare tutto questo, è possibile digitare quanto segue nella * tampone * scratch e valutare le espressioni:

(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 

Così, tutte e tre le varianti di utilizzo lambda solo costruire liste che possono essere utilizzati come funzioni (una delle quali può essere compilata in byte).

+0

Ma non sta usando una virgoletta singola davanti a un'espressione che fa in modo che l'interprete LISP lo restituisca così com'è e non lo sta valutando? Ciò significherebbe che '(+ 1 2) restituirà come (+ 1 2) e (+ 1 2) restituirà come 3 ... – Joscha

+0

@Joscha, non si sa quale parte si sta commentando. Lambda è auto-quotante, il che significa che quando l'interprete valuta un'espressione lambda, il risultato è la stessa espressione lambda. Credo che questo sia diverso dalla maggior parte degli altri lisps a causa della ricerca variabile usata da Emacs (ambito indefinito ed estensione dinamica). Scheme crea piccole chiusure con alcune informazioni sull'ambiente a causa dell'estensione lessicale (credo). –

+2

'(lambda ...)' è in realtà equivalente a '(function (lambda ...))' not ''(lambda ...)' come si può provare valutando '(macroexpand (lambda (x) (+ xx))) ' – nschum

3

Bene (quote (lambda...)) e (lambda...) non sono equivalenti (se byte di compilazione). I lambda citati non sono byte compilati mentre tutto il resto lo è.

Ad esempio:

(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 

Di solito non si vuole citare una lambda a meno che la funzione che si sta per passare il lambda a sta facendo qualcos'altro con esso che appena funcall esso.

+1

Credo che questo sia cambiato nel tempo. Guardando '(info" (elisp) Funzioni anonime ")', dice "Al giorno d'oggi è possibile omettere 'funzione' interamente ... Questo perché 'lambda' stesso implica 'funzione'." Quella pagina è un po 'confusa in prima lettura, ma i tuoi esempi fanno per una buona chiarimento :) (a) '(function (lambda ...))' è una variante di '(citazione (lambda ...)) 'che abilita la compilazione di byte. (b) * un * -quotato '(lambda ...)' è (al giorno d'oggi) lo stesso di '(funzione (lambda ...))'! – phils