方案语法规则 - (let) 和 (define) 之间变量绑定的差异

发布于 2024-12-13 16:16:34 字数 943 浏览 0 评论 0原文

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

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

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

(define var 'original)

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

我希望以下代码如果立即执行,将计算为 original,它确实如此:

(test-var var)

我希望这个代码是 no -match 因为在 test-var 之前引入作用域的 var 与宏定义中 var 的绑定不匹配:

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

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

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

在“鸡计划”中,这计算为新变量。出于与前面的 (let) 示例相同的原因,我本以为它是 no-match 的。我认为这可能是使用两次 define 的问题,但即使我使用 (set!var 'new-var )

有人知道这里发生了什么吗?每个 R5RS 会发生什么?

The R5RS spec states that as part of the requirements for a macro defined using syntax-rules:

If a macro transformer inserts a free reference to an identifier, the reference refers to the binding that was visible where the transformer was specified, regardless of any local bindings that may surround the use of the macro.

I am trying to understand how this works in practice. So for example, if I have the following code:

(define var 'original)

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

I would expect the following, if executed immediately after, to evaluate to original, which it does:

(test-var var)

And I would expect this one to be no-match since the var introduced into scope prior to test-var does not match the binding of var at macro definition:

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

However the following example has me puzzled:

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

In Chicken Scheme, this evaluates to new-var. I would have expected it to be no-match for the same reasons as the previous (let) example. I thought that perhaps this was an issue with using define twice, but the result is still new-var even if I use (set! var 'new-var)

Does anyone have any insight as to what is going on here? What should happen per R5RS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

揽月 2024-12-20 16:16:34

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

This is the usual trick that Schemes have when dealing with redefinitions on the REPL -- treating them as a mutation for the existing binding. So the second define is not really creating a new binding, and instead it just set!s the existing one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文