问题描述
|
例如,这是一个宏:
(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)
我想念什么?
解决方法
Emacs Lisp要求列表形式的第一个元素是内置函数(或subr),lambda表达式(即
(lambda LIST . LIST)
)或宏lambda表达式(即(macro lambda LIST . LIST)
)。第一个元素也可以是符号,其功能插槽中包含一个有效的第一个元素。
(my-macro 2 3)
没有必需的格式,因此它是无效函数。
如果您习惯使用Scheme,在该函数中对函数调用的函数部分进行了正常评估,请注意,这在Lisp中不能完全相同,因为Lisp中的函数具有不同的命名空间((f 3)
查找f
的函数槽,而“ѭ9”的值通常是其值槽)。
如果要评估正常值之类的函数,可以使用use11ѭ或apply
。
(funcall (my-macro 2 3) 1)
, 正如错误消息所表明的那样,在评估形式“ 3”时,Emacs不会在评估列表的第一个元素之前扩展“ 1”。你想说
(funcall (my-macro 2 3) 1)
要么
(eval (list (my-macro 2 3) 1)
或类似的东西,以便对宏进行评估。