macros - Define 和 let w.r.t. 之间的区别语法规则关键字

标签 macros scheme racket

我是 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)中失败的原因是什么,而它对于定义却工作得很好?另外,我在哪里可以获得有关这种差异的更多具体信息?谢谢。

最佳答案

这与语法文字的工作方式有关。特别是,如果满足以下条件,则语法文字被视为匹配:

  1. 文字在宏定义时没有绑定(bind),在宏使用时也没有绑定(bind)。
  2. 文字在宏定义时具有绑定(bind),并且在宏使用时也具有相同的绑定(bind)

define 案例适合您,因为您可能将 define 放在与宏相同的模块中。这意味着条件 2 匹配:in 在宏定义和使用方面具有相同的绑定(bind)。但是,如果您在一个模块中定义了宏(没有 indefine),并在您所在的另一模块中定义了 in使用宏,事情不会那么顺利。 :-)

let 情况为 in 创建一个新的绑定(bind)。这永远不会匹配顶级宏定义中 in 的绑定(bind)。

关于macros - Define 和 let w.r.t. 之间的区别语法规则关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37644555/

相关文章:

c - 如何使用以下预处理器语句

python - 关于从非常不相关的语言(在本例中是 Scheme 到 Python)翻译代码的建议?

macros - SICP:可以或在 lisp 中定义为没有 gensym 的句法转换吗?

macros - Racket:由定义为macroname.0的宏生成的宏

c++ - 打印宏连接失败

iphone - 如何编写一个可以带参数的宏?

scheme - SICP - 程序与过程

scheme - 替换(可能嵌套的)列表中第一次出现的符号

scheme - Racket Scheme 是否提供类似 Smalltalk 的基于图像的环境?

macros - Clojure defmacro 丢失元数据