Common Lisp中的逗号逗号

时间:2013-07-30 21:06:02

标签: lisp common-lisp

我对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

1 个答案:

答案 0 :(得分:5)

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

所以,第一个逗号取消引用第二个反引号; ,@然后拼接parms的内容,因为所有引号都已撤消。 Unquoting不会像你描述的那样在步骤中“替换”表单 - 在决定如何评估包含的表单时,逗号只是在反引号表单的结构中备份。

(let ((parms '(x y)))
  `(list 'beg ,@parms 'end))

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

相关问题