2012-06-26 20 views
18

Ich bin verwirrt darüber, wie defun Makro funktioniert, weilwarum defun ist nicht das gleiche wie (setq <name><lambda>)?

(defun x() "hello") 

wird Funktion x erstellen, aber das Symbol X wird noch ungebunden sein.

Wenn ich etwas Lambda x binden werden, dann wird x einen Wert haben, aber es wird nicht durch Dolmetscher als Funktion in Form so behandelt werden:

(x) 

Ich denke, dass es die in Beziehung steht Tatsache, dass defun Funktion in der globalen Umgebung definieren sollte, aber ich bin mir nicht sicher, was es genau bedeutet. Warum kann ich es nicht in der aktuellen Umgebung beschatten?

Gibt es eine Möglichkeit, Interpreter behandeln Symbol als Funktion zu erzwingen, wenn einige Lambda daran gebunden war? Zum Beispiel:

(setq y (lambda() "I want to be a named function")) 
(y) 

S.S .: Ich benutze SBCL.

Antwort

20

Common Lisp verschiedene Namensräume für Funktionen und Werte hat.

Sie definieren Funktionen im Funktionsnamensraum mit DEFUN, FLET, LABELS und einigen anderen. Wenn Sie ein Funktionsobjekt als Wert erhalten möchten, verwenden Sie .

(defun foo (x) (1+ x)) 

(function foo) -> #<the function foo> 

oder kürzer:

#'foo -> #<the function foo> 

Wenn Sie eine Funktion aufrufen möchten, dann schreiben Sie (foo 100).

Wenn Sie die Funktion als Wert anrufen wollen, dann müssen Sie verwenden FUNCALL oder APPLY:

(funcall #'foo 1) 

können Sie Funktionen übergeben um und nennen sie:

(defun bar (f arg) 
    (funcall f arg arg)) 

(bar #'+ 2) -> 4 

Im Falle von DEFUN:

Es ist nicht (setf (symbol-value 'FOO) (lambda ...)).

Es ist mehr wie (setf (symbol-function 'foo) (lambda ...)).

Beachten Sie, dass die beiden Namespaces Sie ermöglichen schreiben:

(defun foo (list) 
    (list list)) 

(foo '(1 2 3)) -> ((1 2 3)) 

Es gibt keinen Konflikt zwischen der integrierten Funktion LIST und die Variable LIST. Da wir zwei verschiedene Namespaces haben, können wir denselben Namen für zwei verschiedene Zwecke verwenden.

Beachten Sie auch, dass bei lokalen Funktionen kein Symbol beteiligt ist. Die Namespaces sind nicht notwendigerweise an Symbole gebunden. Somit ist für lokale Variablen eine Funktionssuche über einen Symbolnamen nicht möglich.

5

Common Lisp verfügt über mehrere Steckplätze für jedes Symbol, einschließlich eines Wertsteckplatzes und eines Funktionssteckplatzes. Wenn Sie die Syntax (x) verwenden, sucht Common Lisp nach der Funktion-Slot-Bindung von x. Wenn Sie die Wertbindung aufrufen möchten, verwenden Sie funcall oder apply.

Siehe http://cl-cookbook.sourceforge.net/functions.html

Verwandte Themen