为什么elisp宏返回的函数的应用不起作用?

时间:2011-06-21 22:55:25

标签: emacs macros elisp

例如,这是一个宏:

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

(my-macro 2 3)返回(lambda (z) (+ z 3))

但是,((my-macro 2 3) 1)会返回错误,

 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)

我错过了什么?

2 个答案:

答案 0 :(得分:7)

Emacs Lisp要求列表form的第一个元素是内置函数(或subr),lambda-expression(即(lambda LIST . LIST))或{ {3}}(即(macro lambda LIST . LIST))。第一个元素也可以是macro lambda-expression,其功能槽包含有效的第一个元素。

(my-macro 2 3)没有所需的表单,因此它是一个无效的函数。

如果你已经习惯了函数调用的函数部分正常计算,请注意,在函数具有不同命名空间的(f 3) {{1}中,这在Lisp中不能完全相同。函数槽,而f的值通常是它的值槽。

如果要评估类似普通值的函数,可以使用symbol

f

答案 1 :(得分:0)

正如错误消息所表明的那样,在评估表单((my-macro 2 3) 1)时,Emacs在评估列表之前不会展开(my-macro 2 3)它是第一个元素。你想说

(funcall (my-macro 2 3) 1)

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

或类似的东西,以便评估宏。