Qual è la differenza traEmacs Lisp: differenza tra (funzione (lambda ...)) e (lambda ...)?
(function (lambda ...))
e
(lambda ...)
e
'(lambda ...)
?
Sembra che tre siano intercambiabili in molti casi.
Qual è la differenza traEmacs Lisp: differenza tra (funzione (lambda ...)) e (lambda ...)?
(function (lambda ...))
e
(lambda ...)
e
'(lambda ...)
?
Sembra che tre siano intercambiabili in molti casi.
Sono abbastanza intercambiabili. La risposta è che function
abilita 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).
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.
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
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
@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). –
'(lambda ...)' è in realtà equivalente a '(function (lambda ...))' not ''(lambda ...)' come si può provare valutando '(macroexpand (lambda (x) (+ xx))) ' – nschum