Common Lisp中的逗号逗号

Jis*_*Yoo 4 lisp common-lisp

我很困惑逗号逗号如何做它的作用.

逗号逗号的使用示例是在定义Lisp宏时是否使用双引号(双逗号)?

在我看来,这

(let ((parms '(x y)))
  ``(beg ,,@parms end))
Run Code Online (Sandbox Code Playgroud)

扩展到或等同于

`(beg ,x ,y end)
Run Code Online (Sandbox Code Playgroud)

它是如何扩展到那个?

我在想,如果我评估双反引号形式,它会导致第二个逗号完成它的工作,结果是:

`(beg ,<splice stuff here> end)
Run Code Online (Sandbox Code Playgroud)

看起来像Lisp解释器应该抱怨并说"我不知道在逗号之前将东西拼接起来意味着什么"在Lisp遇到的意义上

`,@abc
Run Code Online (Sandbox Code Playgroud)

它可能会说"我不知道在反引号之前拼接东西意味着什么.不要再这样做了."

但不知何故,翻译不会抱怨而只是选择这样做

`(beg <splice stuff here and write comma in front of each of them> end)
Run Code Online (Sandbox Code Playgroud)

这是否与CLHS反引用中的规则兼容?


对于读者信息,答案后面的评论指的是答案的旧版本,并导致更新答案.新读者不需要阅读评论.


另见CHLS"最内层反引号形式应首先扩展"的含义

jla*_*ahd 5

CLHS声明:"如果反引号语法是嵌套的,那么应该首先扩展最里面的反引号形式.这意味着如果连续出现几个逗号,则最左边的一个逗号属于最内层的反引号."

所以,第一个逗号不引用第二个反引号; 在,@随后拼接中的内容parms,因为所有的报价都被撤销.Unquoting不会像您描述的那样"替换"表单 - 在决定如何评估包含的表单时,逗号只是在反引号表单的结构中备份.

(let ((parms '(x y)))
  `(list 'beg ,@parms 'end))
Run Code Online (Sandbox Code Playgroud)

显然是评价(list 'beg x y 'end),这就是你在这里所追求的; 生成一个表单,创建所需的结构作为其输出.额外的外部反引用只是这种语法的简写,与'(foo bar)(平等问题除外)简写相同(list 'foo 'bar).