为什么在这个宏定义中需要@符号?

时间:2011-04-14 10:30:20

标签: macros lisp

以下是宏:

(defmacro when (condition &rest body)
  `(if ,condition (progn ,@body)))

为什么有一个at符号?

3 个答案:

答案 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))