以下是宏:
(defmacro when (condition &rest body)
`(if ,condition (progn ,@body)))
为什么有一个at符号?
答案 0 :(得分:18)
通过进行一些实验很容易看出差异
> (let ((x '(1 2 3 4))) `(this is an example ,x of expansion))
(THIS IS AN EXAMPLE (1 2 3 4) OF EXPANSION)
> (let ((x '(1 2 3 4))) `(this is an example ,@x of expansion))
(THIS IS AN EXAMPLE 1 2 3 4 OF EXPANSION)
正如您所看到的,使用,@
会将列表的元素直接放在扩展中。如果没有您,请将列表放在扩展中。
答案 1 :(得分:2)
@
也可以被认为是解构列表并将其附加到列表中,如Practical Common Lisp中所述。
`(a ,@(list 1 2) c)
相当于:
(append (list 'a) (list 1 2) (list 'c))
产生:
(a 1 2 c)
答案 2 :(得分:0)
该宏定义等同于
(defmacro when (condition &rest body)
(list 'if condition (cons 'progn body)))
但没有@
则等同于
(defmacro when (condition &rest body)
(list 'if condition (list 'progn body)))
由于body
是一个列表,因此将其评估为好像带括号的函数调用,例如(when t 1 2 3)
将扩展为
(if t (progn (1 2 3)))
代替正确的
(if t (progn 1 2 3))