Macros 这句话怎么说;语法;用lisp工作?

Macros 这句话怎么说;语法;用lisp工作?,macros,lisp,common-lisp,lisp-macros,Macros,Lisp,Common Lisp,Lisp Macros,下面是Paul Graham的Lisp书中的简化示例(类似于scheme的语法) 我知道,@y应该如何工作,但不确定,',z应该如何工作应该先评估什么以及以什么顺序评估。(我知道它应该计算为symbol foo,因为它以guile返回(10(foo 1 2 3)),但我不确定确切的步骤是什么) 我在JavaScript中的lisp中需要这个,我的结果是: (10 ((unquote z) 1 2 3)) 因为它只是从左到右对其求值(我只是专门处理、和更多逗号)。您应该如何计算此表达式 书中也有

下面是Paul Graham的Lisp书中的简化示例(类似于scheme的语法)

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

我在JavaScript中的lisp中需要这个,我的结果是:

(10 ((unquote z) 1 2 3))
因为它只是从左到右对其求值(我只是专门处理
和更多逗号)。您应该如何计算此表达式

书中也有这样一个例子:

(defmacro propmacro (propname)
   `(defmacro ,propname (obj)
       `(get ,obj ',',propname)))
应该如何评估
,,
?这种情况下的步骤是什么


是否有其他使用反报价/准报价的奇怪边缘案例?你能展示一下这些例子吗?它们应该如何评估以及以什么顺序进行评估?

如何工作

`(list ,x `(,',z ,,@y))))
          ^ ^
          |  `- this comma
           `- belongs to this backquote
上面的逗号将表达式
',z
(quote,z)
插入到内部反引号中。而
,z
,则属于外部反引号

因此,
z
的值被插入
(quote,z)
以使
(quote)

然后,实际上,内部反引号的行为类似于
`(,')

具体地说,假设
z
包含列表
(+2)
。然后,我们可以通过将
(+2)
插入内部后引号来理解它,从而生成
`(,'(+2)…)
。这一点现在很容易理解:当对内部反引号求值时,
(+2)
受到保护而不被求值,从而导致对象
(+2)…)

模式
,expr
用于在最外层的backquote求值期间获得
expr
的单个求值,这样该值就可以在剩余backquote嵌套的任意数量的求值轮中传播,而无需进行进一步求值。这里有一种“反引号代数”,其中“逗号和引号相互抵消”

您还可以将
、'、'、'…
可视化为一种钻取嵌套层的钻头,以便在结构中的任何位置植入文字值。例如

(defmacro super-nested-macro (arg)
  `(... `(.... `(.....`(we simply want arg down here ,',',',arg)))))
super-nested macro
的作者只想将
arg
的值粘贴到模板中,放置在其他三个反引号中。因此,不能使用通常的
,arg
:该逗号将被误解为属于最里面的反引号

是否有其他使用反报价/准报价的奇怪边缘案例

backquote中一个奇怪的边缘情况是试图拼接到点位置:

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

`(a b c . ,foo)   ;; OK: equivalent to `(a b c ,@foo)
`(a b c . `(d e f))
不确定各种实现如何处理点位置的反引号:

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

`(a b c . ,foo)   ;; OK: equivalent to `(a b c ,@foo)
`(a b c . `(d e f))
这真的没有意义,我怀疑获得的实际结果将取决于backquote实现内部

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

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

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

Google“lisp嵌套反引号”,您会发现许多解释。特别是,这一解释非常完整: