请帮忙.我正在尝试创建这个lisp宏,它将一个(数字)列表作为输入并返回这些数字的总和.代码
(setf g (list 1 2 3 4))
(defmacro add-test(var)
`(+ ,@var))
Run Code Online (Sandbox Code Playgroud)
(add-test g) 给出了这个错误
The value G is not of type LIST.
[Condition of type TYPE-ERROR]
Run Code Online (Sandbox Code Playgroud)
同时(add-test (1 2 3 4))给出正确的结果,即10.
你能解释一下,为什么在将变量传入函数时它不起作用?
其他详情 -
Lispbox - SBCL
Ubuntu Linux
提前致谢
这很简单,也是最常见的宏观问题之一.
(add-test g)
Run Code Online (Sandbox Code Playgroud)
现在在宏扩展时,ADD-TEST使用参数VAR获取值G(符号)来调用宏.
然后尝试列表操作.反引号表达式
`(+ ,@var)
Run Code Online (Sandbox Code Playgroud)
VARis 的值G,并尝试将其拼接到列表中(+ ... ).现在返回的表达式是(+ . G).
CL-USER 12 > (macroexpand '(add-test g))
(+ . G)
T
Run Code Online (Sandbox Code Playgroud)
(+ . G)不是一个有效的Lisp表单.它不是有效的源代码.
请记住,宏的参数是未评估的源表达式.
将其与以下内容进行比较:
CL-USER 13 > (macroexpand '(add-test (1 2 3 4)))
(+ 1 2 3 4)
T
Run Code Online (Sandbox Code Playgroud)
你说:'你能解释一下,为什么当变量传入函数时它不起作用?'
记住,ADD-TEST不是一个功能,它是一个宏.宏获取传递的源代码并返回一个新表单 - 然后稍后评估该表单.