2009-12-03 4 views
5

Angenommen, ich habe diese wundervolle Funktion fooeine Lambda-Funktion in clisp Rückkehr, dann ist es die Bewertung

[92]> (defun foo() (lambda() 42)) 
FOO 
[93]> (foo) 
#<FUNCTION :LAMBDA NIL 42> 
[94]> 

Nun nehme ich will Verwendung foo tatsächlich und 42.

zurückkehren Wie kann ich tun Das? Ich habe bei Google herumgeschnüffelt und ich kann nicht mit der richtigen Syntax kommen.

Antwort

11

Sie wollen die FUNCALL Funktion:

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

Ihre Funktion foo ein function zurückgibt. Verwenden Sie die Funktion funcall, um eine Funktion auf Argumente anzuwenden, auch wenn das Argumentset leer ist.

Hier können Sie sehen, dass foo einen Wert vom Typ gibt 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

Eine weitere Option neben FUNCALL ist GILT:

(apply (foo) nil)

FUNCALL ist der idiomatische Weg hier, aber Sie‘ Ich brauche APPLY, wenn Sie eine Liste von Parametern haben.

6

Die relevanten Begriffe hier sind "Lisp-1" und "Lisp-2".

Ihr Anrufversuch würde in einem Lisp-1 wie z. Schema oder Clojure. Common Lisp ist ein Lisp-2, was in etwa bedeutet, dass Variablennamen und Funktionsnamen getrennt sind.

Also, um auf eine Variable die Funktion gebunden rufen Sie entweder die speziellen Formen funcall oder apply als andere verwenden müssen, haben darauf hingewiesen, oder den Funktionswert des Symbols foo anstatt der Variablenwert gesetzt.

Erstere nimmt grundsätzlich den Variablenwert des Symbols nimmt/überprüft, ob Wert eine Funktion ist und ruft dann die Funktion (mit dem, was Argumente, die Sie zu funcall/apply geben.

Sie wirklich nicht wollen tun diese als das ziemlich albern in allen ist aber sehr spezielle Fälle, aber für Vollständigkeit halber ist dies etwa, wie Sie es tun würde:

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

Sie sollten schauen wollen in die labels und flet Sonderformen auch (die häufig verwendet werden) - da bist du eigentlich do Verwenden Sie die letzteren Methoden (diese Formulare erstellen eine temporäre Funktion Bindung für Symbole).

Also Ihr Problem würde es so aussehen:

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

dh hier Sie vorübergehend die Funktion Wert des Symbols foo an die Funktion binden 42. Innerhalb dieser temporären Kontext der Rückkehr Sie dann (foo) nennen kann wie regelmäßige globale Funktionen.

+0

Das ist eine gute Antwort! –

Verwandte Themen