考虑 R7RS 方案中的以下宏定义:
(define-syntax foo
(syntax-rules ()
((_ bar)
(begin
(define baz 42)
(define-syntax bar
(syntax-rules ()
((_) baz)))))))
我已将此文件加载到 chibi-scheme
的 repl 中并输入:
>(福吧)
>(巴)
而不是预期的输出42
,我得到了:
错误:未定义的变量:baz
为什么会这样,如何将外部宏中定义的baz
值传递给内部宏?
这是赤壁方案中的错误。 宏定义需要捕获其环境;对于bar
,环境由bar
本身和baz
组成。 然后,当您在另一个环境中展开bar
时,宏扩展需要识别baz
绑定在定义环境中。 赤壁方案显然没有认识到baz
实际上是定义的。
此外,另一个您在帖子中没有看到的相关问题是,即使bar
的扩展将baz
识别为绑定,代码的加载/运行也需要找到baz
的值。
这是R6RS的Ikarus方案:
> (define-syntax foo
(syntax-rules ()
((_ bar)
(begin
(define baz 42)
(define-syntax bar
(syntax-rules ()
((_) baz)))))))
> (foo bar)
> (bar)
42
>
我已经在我的测试套件中支持语法规则的所有方案上运行了它,它仅在 Chibi 和 MIT 上失败。 我看不出有什么理由为什么它不应该起作用,但我承认宏观学对我来说仍然是一门黑艺术。 特别是,它适用于 Foment,这是一个 R7RS 系统。 我无法建造射手座,所以我无法在那里测试它。