gpt4 book ai didi

lisp - 如何解释 Common Lisp 中的 comma-comma-at?

转载 作者:太空宇宙 更新时间:2023-11-03 18:43:42 28 4
gpt4 key购买 nike

编辑:在我的示例中,=> 表示“评估为”,而 -> 表示“扩展到 macroexpand-1” .

我正在努力研究 Common Lisp 中的嵌套反引号,我想我已经非常接近理解它了,多亏了其他几个 SO 问题(请不要让我引用它们——我见过他们)。只有最后一件事困扰着我。考虑:

`(a `(b ,,@(list 'c 'd)))

=> (a `(b ,c ,d))

按照 CLHS 中用于扩展反引号形式的算法,我逐步完成了上面第一种形式的(读取时)扩展过程,实际上,评估从该扩展中获得的形式确实给出了等效的结果。现在,考虑一下 Peter Seibel 在他的优秀著作中给出的 once-only 的定义。

(defmacro once-only ((&rest names) &body body)
(let ((gensyms (loop for n in names collect (gensym))))
`(let (,@(loop for g in gensyms collect `(,g (gensym))))
`(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
,@body)))))

给定该定义,SBCL 显示以下宏展开式:

(once-only (from to)
`(do ((,var ,from (next-prime (+ 1 ,var))))
((>= ,var ,to))
,@body)))

-> (LET ((#:G939 (GENSYM)) (#:G940 (GENSYM)))
`(LET ((,#:G939 ,FROM) (,#:G940 ,TO))
,(LET ((FROM #:G939) (TO #:G940))
`(DO ((,VAR ,FROM (NEXT-PRIME (+ ,1 ,VAR)))) ((>= ,VAR ,TO)) ,@BODY))))

现在,我的问题是扩展表单的第二行。不应该是:

`(LET (,(,#:G939 ,FROM) ,(,#:G940 ,TO))

?

看看上面第一个例子中 ,,@ 的计算结果是如何将逗号“分配”到从列表 (c d) 中拼接的元素?为什么这里不发生这种情况?这两个例子似乎共享相同的结构,但它们的评估结果似乎不一致。

最佳答案

我想我看到了我的错误。上面宏扩展中的第二行实际上应该是:

`(LET (,`(,#:G939 ,FROM) ,`(,#:G940 ,TO))

这相当于 SBCL 显示的内容。

关于lisp - 如何解释 Common Lisp 中的 comma-comma-at?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18418679/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com