4

我对 comma-comma-at 的作用感到困惑。

使用 comma-comma-at 的一个例子在Is there a use for double unquote (double comma) when defined 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 反引号中的规则兼容吗?


供读者参考,答案后面的评论指的是旧版本的答案,并导致答案的更新。新读者无需阅读评论。


另见CHLS“最内层的反引号形式应首先展开”含义

4

1 回答 1

5

CLHS规定:“如果反引号语法是嵌套的,则应首先展开最里面的反引号形式。这意味着如果连续出现多个逗号,则最左边的一个属于最里面的反引号。”

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

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

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

于 2013-07-30T21:24:01.503 回答