lisp 宏函数中的 ",@"

",@" in lisp macro functions

来自 http://www.gigamonkeys.com/book/practical-a-simple-database.html :

The ,@ "splices" the value of the following expression--which must evaluate to a list--into the enclosing list. You can see the difference between , and ,@ in the following two expressions:

`(and ,(list 1 2 3))   ==> (AND (1 2 3)) 

`(and ,@(list 1 2 3))  ==> (AND 1 2 3)

即使有这个例子,我也无法理解 ,@ 的作用。有人可以明确提及第二个示例中的步骤吗? (是的,这里是 lisp 初学者)

这里是你的例子的一个稍微修改的版本:

`(foo bar ,(list 1 2 3) baz)   ==> (foo bar (1 2 3) baz) 

`(foo bar ,@(list 1 2 3) baz)  ==> (foo bar  1 2 3  baz)

在第一个表达式中,列表 (1 2 3) 作为结果列表中的一个元素插入。在第二个表达式中,列表 (1 2 3) 的元素成为结果列表中的元素。列表是 "spliced".

请注意,反引号功能独立于。这是从 模板 构建列表的通用机制。由于 Lisp 源代码基于列表,因此有时从源代码模板构建 Lisp 源代码也很有用。

CL-USER 86 > `(one   pi ,(* 1 pi)
               two   pi ,(* 2 pi)    
               three pi ,(* 3 pi))
(ONE PI 3.141592653589793D0
 TWO PI 6.283185307179586D0
 THREE PI 9.42477796076938D0)

CL-USER 87 > `((one   pi ,(* 1 pi))
               (two   pi ,(* 2 pi))
               (three pi ,(* 3 pi)))
((ONE PI 3.141592653589793D0)
 (TWO PI 6.283185307179586D0)
 (THREE PI 9.42477796076938D0))


CL-USER 90 > `(((one pi) (two pi) (three pi))
               ,(loop for i from 1 upto 3 collect (list (* pi i))))
(((ONE PI) (TWO PI) (THREE PI))
 ((3.141592653589793D0) (6.283185307179586D0) (9.42477796076938D0)))

这里有一个 ,@ 的示例,其中拼接了结果列表。结果列表消失,其元素成为结果列表的成员。

CL-USER 91 > `(((one pi) (two pi) (three pi))
               ,@(loop for i from 1 upto 3 collect (list (* pi i))))
(((ONE PI) (TWO PI) (THREE PI))
  (3.141592653589793D0) (6.283185307179586D0) (9.42477796076938D0))