我是 Racket 和 Lisp 的初学者,正在研究语法定义。我定义了一个简单的转换,如下所示:
(define-syntax hello
(syntax-rules (in)
((_ name in world) (format "Hello ~a in ~a" name world))
((_ in name) (format "Hello ~a in here" name))))
现在,当我像这两种情况一样运行它时,它工作正常:
(hello "me" in "world") === "Hello me in world"
并且,
(define in "inside")
(hello me in in) === "Hello me in inside"
但是,这会导致错误,
(let ([in "Shire"])
(hello "Martin" in in)) === Error: hello: bad syntax in: (hello "Martin" in in)
那么,hello 在 let 绑定(bind)中失败的原因是什么,而它对于定义却工作得很好?另外,我在哪里可以获得有关这种差异的更多具体信息?谢谢。
最佳答案
这与语法文字的工作方式有关。特别是,如果满足以下条件,则语法文字被视为匹配:
- 文字在宏定义时没有绑定(bind),在宏使用时也没有绑定(bind)。
- 文字在宏定义时具有绑定(bind),并且在宏使用时也具有相同的绑定(bind)。
define
案例适合您,因为您可能将 define
放在与宏相同的模块中。这意味着条件 2 匹配:in
在宏定义和使用方面具有相同的绑定(bind)。但是,如果您在一个模块中定义了宏(没有 in
的 define
),并在您所在的另一模块中定义了 in
使用宏,事情不会那么顺利。 :-)
let
情况为 in
创建一个新的绑定(bind)。这永远不会匹配顶级宏定义中 in
的绑定(bind)。
关于macros - Define 和 let w.r.t. 之间的区别语法规则关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37644555/