我是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绑定内失败的原因是什么,而对定义却很好?另外,在哪里可以获得有关此差异的更具体的信息?谢谢。
最佳答案
这与语法文字的工作方式有关。特别地,如果满足以下条件,则认为语法文字是匹配的:
文字在宏定义时没有绑定,在宏使用时也没有绑定。
文字在宏定义时具有绑定,并且在宏使用时也具有相同的绑定。define
案例对您有用,因为您可能将define
放在了与宏相同的模块中。这意味着符合条件2:in
在宏定义和用法上具有相同的绑定。但是,如果在一个模块中定义了宏(对于define
没有in
),并且在使用宏的另一个模块中定义了in
,那么事情将无法正常进行。 :-)let
案例为in
创建新的绑定。这将永远与顶级宏定义中in
的绑定不匹配。