3

R 5 RS 规范指出,作为使用定义的宏的要求的一部分syntax-rules

如果宏转换器插入对标识符的自由引用,则该引用指的是在指定转换器时可见的绑定,而不管可能围绕宏的使用的任何本地绑定。

我试图了解这在实践中是如何工作的。例如,如果我有以下代码:

(define var 'original)

(define-syntax test-var
 (syntax-rules (var)
   ((_ var)
    var)
   ((_ pattern-var)
    'no-match)))

我希望以下内容(如果在之后立即执行)评估为original,它确实如此:

(test-var var)

我希望这是no-match因为var之前引入的范围与at 宏定义test-var的绑定不匹配:var

(let ((var 1)) (test-var var))

但是下面的例子让我很困惑:

(define var 'new-var)
(test-var var)

在 Chicken Scheme 中,计算结果为new-var。我本来预计它no-match的原因与前面的(let)示例相同。我认为这可能是使用define两次的问题,但结果仍然new-var是即使我使用(set! var 'new-var)

有没有人知道这里发生了什么?每个 R 5 RS 应该发生什么?

4

1 回答 1

5

这是 Schemes 在处理 REPL 上的重新定义时常用的技巧——将它们视为现有绑定的突变。所以第二个define并不是真正创建一个新的绑定,而是它只是set!现有的。

于 2011-11-03T18:14:31.497 回答