2009-12-03 4 views

risposta

11

si desidera che la funzione di FUNCALL:

* (defun foo() (lambda() 42)) 
FOO 
* (funcall (foo)) 
42 
2

La funzione foo restituisce un function. Utilizzare la funzione funcall per applicare una funzione agli argomenti, anche se l'argomento impostato è vuoto.

Qui potete vedere che foo restituisce un valore di tipo function:

CL-USER> (let ((f (foo))) 
      (type-of f)) 
FUNCTION 
CL-USER> (let ((f (foo))) 
      (funcall f)) 
42 
CL-USER> (type-of (foo)) 
FUNCTION 
CL-USER> (funcall (foo)) 
42 
2

Un'altra opzione oltre funcall è APPLICA:

(apply (foo) nil)

funcall è il modo idiomatico qui, ma si' Ho bisogno di APPLY quando hai una lista di parametri.

6

I termini rilevanti qui sono "Lisp-1" e "Lisp-2".

Il tuo tentativo di chiamata funzionerebbe in un Lisp-1 come ad es. Schema o Clojure. Common Lisp è un Lisp-2, tuttavia ciò significa che i nomi delle variabili e le funzioni sono separati.

Così, al fine di chiamare la funzione legata ad una variabile si sia necessario utilizzare le forme speciali funcall o apply come altri hanno fatto notare o impostare il valore della funzione del simbolo foo piuttosto che il valore della variabile.

Il primo è quasi esclusivamente il valore della variabile del simbolo, assume/controlla che il valore è una funzione e quindi chiama la funzione (con qualsiasi argomenti passato a funcall/apply.

Non si vuole veramente fare il secondo come che è abbastanza stupido a tutti ma molto specializzate casi, ma per l'amor completezza questo è più o meno come lo faresti:

CL-USER> (setf (symbol-function 'foo) (lambda() 42)) 
#<FUNCTION (LAMBDA()) {C43DCFD}> 
CL-USER> (foo) 
42 

si dovrebbe anche voler esaminare le labels e flet forme speciali (che sono comunemente usati) - ci sei davvero do usa questi ultimi metodi (queste forme creano una funzione temporanea che si lega ai simboli).

Quindi il problema sarebbe lì simile a questa:

(flet ((foo() 
     42)) 
    (foo)) 

cioè qui si associa temporaneamente la funzione di valore del simbolo foo alla funzione che restituisce 42. In tale contesto temporanea si può quindi chiamare (foo) come funzioni globali regolari.

+0

Questa è un'ottima risposta! –