我对comma-comma-at的功能感到困惑。
使用逗号逗号的示例位于Is there a use for double unquote (double comma) when defining a Lisp macro?
在我看来
(let ((parms '(x y)))
``(beg ,,@parms end))
扩展到或等同于
`(beg ,x ,y end)
它如何扩展到那个?
我在想,如果我评估双反引号形式,它会导致第二个逗号完成它的工作,结果是:
`(beg ,<splice stuff here> end)
看起来Lisp解释器应该抱怨并且说“我不知道在逗号之前将东西拼接起来意味着什么”,这意味着当Lisp遇到时
`,@abc
它可能会说“我不知道在反引号之前拼接东西意味着什么。不要再这样做。”
但不知何故,翻译不会抱怨而只是选择
`(beg <splice stuff here and write comma in front of each of them> end)
这是否与CLHS backquote中的规则兼容?
对于读者信息,答案后面的评论指的是答案的旧版本,并导致更新答案。新读者不需要阅读评论。
另见CHLS "innermost backquoted form should be expanded first" meaning
答案 0 :(得分:5)
CLHS声明:“如果反引号语法是嵌套的,那么应首先展开最里面的反引号表单。这意味着如果连续出现几个逗号,则最左边的一个逗号属于最内层的反引号。“
所以,第一个逗号取消引用第二个反引号; ,@
然后拼接parms
的内容,因为所有引号都已撤消。 Unquoting不会像你描述的那样在步骤中“替换”表单 - 在决定如何评估包含的表单时,逗号只是在反引号表单的结构中备份。
(let ((parms '(x y)))
`(list 'beg ,@parms 'end))
显然评估为(list 'beg x y 'end)
,这就是你在这里所追求的;生成一个表单,创建所需的结构作为其输出。额外的外部反引用只是这种语法的简写,与'(foo bar)
相同(除了等式问题)是(list 'foo 'bar)
的简写。