2012-06-26 12 views
18

Jestem mylić temat defun prac makro, bodlaczego defun to nie to samo co (setq <name><lambda>)?

(defun x() "hello") 

stworzy funkcji X, ale symbol x nadal będzie nieograniczony.

Jeśli będę wiązać pewne lambda x to x ma wartość, ale nie będą traktowane przez tłumacza jako funkcja w postaci tak:

(x) 

myślę, że to jest związane z fakt, że defun powinien definiować funkcję w środowisku globalnym, ale nie jestem pewien, co to dokładnie oznacza. Dlaczego nie mogę wyświetlać tego w bieżącym środowisku?

Czy istnieje sposób na zmusienie interpretatora do traktowania symbolu jako funkcji, jeśli jakiś lambda był z nim związany? Na przykład:

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

P.S .: Używam SBCL.

Odpowiedz

20

Common Lisp ma różne przestrzenie nazw dla funkcji i wartości.

Użytkownik definiuje funkcje w przestrzeni nazw funkcji za pomocą DEFUN, FLET, LABELS i kilku innych.

Jeśli chcesz uzyskać obiekt funkcji jako wartość, używaj FUNCTION.

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

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

lub krócej:

#'foo -> #<the function foo> 

Jeśli chcesz wywołać funkcję, a następnie piszesz (foo 100).

Jeśli chcesz wywołać funkcję jako wartość wtedy trzeba użyć FUNCALL lub APPLY:

(funcall #'foo 1) 

Możesz przekazać funkcji wokół i nazywają je:

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

(bar #'+ 2) -> 4 

W przypadku DEFUN:

To nie jest (setf (symbol-value 'FOO) (lambda ...)). To jest bardziej podobne do (setf (symbol-function 'foo) (lambda ...)).

Zauważ, że te dwie przestrzenie nazw pozwalają napisać:

(defun foo (list) 
    (list list)) 

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

Nie ma konfliktu pomiędzy wbudowaną funkcją LIST i zmiennej LIST. Ponieważ mamy dwa różne przestrzenie nazw, możemy użyć tej samej nazwy dla dwóch różnych celów.

Należy również zauważyć, że w przypadku funkcji lokalnych nie jest wymagany symbol o symbolu. Przestrzenie nazw niekoniecznie są powiązane z symbolami. W związku z tym dla zmiennych lokalnych funkcja wyszukiwania za pomocą nazwy symbolu nie jest możliwa.

5

Common Lisp ma wiele gniazd dla każdego symbolu, w tym gniazda wartości i gniazda funkcji. Gdy używasz składni (x), zwykły seplion szuka powiązania z slotem funkcji z x. Jeśli chcesz wywołać wartość wiążącą, użyj funcall lub apply.

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

Powiązane problemy