2011-06-21 19 views
8

Na przykład tutaj jest makro:Dlaczego nie działa funkcja zwracana przez makro makr?

(defmacro my-macro (x y) 
    (if (> x 0) 
    `(lambda (z) (+ z ,y)) 
`(lambda (z) (+ ,x z)))) 

i (my-macro 2 3) powraca (lambda (z) (+ z 3))

Jednak ((my-macro 2 3) 1) zwraca błąd mówiący

Debugger entered--Lisp error: 

(invalid-function (my-macro 2 3)) 
    ((my-macro 2 3) 1) 
    eval(((my-macro 2 3) 1)) 
    eval-last-sexp-1(nil) 
    eval-last-sexp(nil) 
    call-interactively(eval-last-sexp nil nil) 

Czego mi brakuje?

+0

Nie zapomnij przyjąć odpowiedzi, jeśli jesteś zadowolony z udzielonej pomocy. Zobacz http://stackoverflow.com/faq#howtoask – phils

Odpowiedz

7

Emacs Lisp wymaga pierwszy element listy form być wbudowana funkcja (lub subr), A lambda-expression (tj (lambda LIST . LIST)) lub macro lambda-expression (tj (macro lambda LIST . LIST)). Pierwszym elementem może być także symbol, którego gniazdo funkcji zawiera poprawny pierwszy element.

(my-macro 2 3) nie ma wymaganego formularza, więc jest to nieprawidłowa funkcja.

Jeśli jesteś przyzwyczajony do Schematu, gdzie funkcja części wywołania funkcji jest normalnie oceniana, zwróć uwagę, że to nie może działać identycznie w Lisp gdzie funkcje mają inną przestrzeń nazw (wyszukuje gniazda funkcji f, mając na uwadze, że wartość f jest zwykle jej przedziałem wartości).

Jeśli chcesz ocenić funkcję podobną do wartości normalnej, możesz użyć funcall or apply.

(funcall (my-macro 2 3) 1) 
+0

Dzięki za wyjaśnienie. – user328148

0

Jak jasno wynika z komunikatu o błędzie, przy ocenie formularza ((my-macro 2 3) 1), przed obliczeniem listy, Emacs nie rozwija (my-macro 2 3), jest to pierwszy element. Chcesz powiedzieć

(funcall (my-macro 2 3) 1) 

lub

(eval (list (my-macro 2 3) 1) 

lub coś podobnego, tak, że makro zostanie oceniona.

+0

Cool. Działa jak marzenie. – user328148

Powiązane problemy