开发者

Why doesn't application of function returned by elisp macro work?

For example, here is a macro:

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

and (my-macro 2 3) return开发者_如何学JAVAs (lambda (z) (+ z 3))

However, ((my-macro 2 3) 1) returns an error saying,

 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)

What am I missing?


Emacs Lisp requires the first element of a list form to be a built-in function (or subr), a lambda-expression (i.e. (lambda LIST . LIST)) or a macro lambda-expression (i.e. (macro lambda LIST . LIST)). The first element can also be a symbol whose function slot contains a valid first element.

(my-macro 2 3) doesn't have the required form, so it's an invalid function.

If you're used to Scheme, where the function part of a function call is evaluated normally, note that this can't work identically in Lisp where functions have a different namespace ((f 3) looks up f's function slot, whereas the value of f is normally its value slot).

If you want to evaluate a function like a normal value, you can use funcall or apply.

(funcall (my-macro 2 3) 1)


As the error message makes clear, in evaluating the form ((my-macro 2 3) 1), Emacs doesn't expand (my-macro 2 3) before evaluating the list it's the first element of. You want to say

(funcall (my-macro 2 3) 1)

or

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

or something like that, so that the macro gets evaluated.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜