gpt4 book ai didi

macros - 这个反引号 "syntax"在 lisp 中是如何工作的?

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

这里是 Paul Graham 的 On Lisp 一书中的简化示例(类似语法的方案)。

(define-macro (bar)
(let ((x 10) (y '(1 2 3)) (z 'foo))
`(list ,x `(,',z ,,@y))))

我知道 ,,@y 应该如何工作,但不确定 ,',z 究竟应该如何工作应该首先评估什么以及以什么顺序评估。 (我知道它应该评估为符号 foo,因为它以诡计返回 (10 (foo 1 2 3)),但我不确定确切的步骤是什么)。

我在 JavaScript 中的 lisp 需要这个,我得到了结果:

(10 ((unquote z) 1 2 3))

因为它只是从左到右评估它(我只专门处理 ,, 和更多逗号)。你应该如何评估这个表达式。

书上也有这个例子:

(defmacro propmacro (propname)
`(defmacro ,propname (obj)
`(get ,obj ',',propname)))

应该如何评估',',?这种情况下的步骤是什么?

是否还有其他带有反引号/准引号的奇怪边缘情况?您能否举出这些例子以及应该如何评估它们以及按什么顺序评估它们?

最佳答案

如何 ,',z有效的是:

`(list ,x `(,',z ,,@y))))
^ ^
| `- this comma
`- belongs to this backquote

上面的逗号将表达式 ',z 插入到内部反引号中或 (quote ,z) .那,z , 又属于外反引号。

因此 z 的值被插入 (quote ,z)制作(quote <value-of-z>) .

然后,实际上,内部反引号的行为类似于 `(,'<value-of-z>) .

具体来说,假设z包含列表 (+ 2 2) .那么我们可以理解为外层反引号插入(+ 2 2)进入内部生产`(,'(+ 2 2) ...) .这现在很容易理解:当计算内部反引号时,(+ 2 2)被保护免于评估,导致对象 ((+ 2 2) ...) .

图案 ,',',', ... ,',expr用于获得 expr 的单个评估在最外层反引号的评估期间,这样该值然后通过剩余反引号嵌套的任意数量的评估轮传播而不进行进一步评估。这里有一种“反引号代数”在起作用,其中“逗号和引号相互抵消”。

您还可以可视化 ,',','...作为一种钻头,可以挖掘嵌套层,使您可以在结构中的任何位置植入文字值。例如

(defmacro super-nested-macro (arg)
`(... `(.... `(.....`(we simply want arg down here ,',',',arg)))))

super-nested-macro 的作者只想保留 arg 的值进入模板,位于埋在其他三个反引号中的位置。因此通常,arg不能使用:该逗号会被误解为属于最内层的反引号。

Are there any other weird edge cases with backquote/quasiquote?

反引号中的一个奇怪的边缘情况是试图拼接成一个点位置:

`(a b c . ,@foo)  ;; not allowed

`(a b c . ,foo) ;; OK: equivalent to `(a b c ,@foo)

不确定各种实现如何处理点位置的反引号:

`(a b c . `(d e f))

这真的没有意义,我怀疑获得的实际结果将取决于反引号实现的内部结构。

并非所有对象都被遍历以取消引用:

 `#c(,(sin theta) ,(cos theta)) ;; Not required by ANSI CL, oops!

这可以通过实现的扩展来实现。

关于macros - 这个反引号 "syntax"在 lisp 中是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56438808/

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