Racket R6RS 支持:语法大小写
Racket R6RS support: syntax-case
这个简单的 R6RS 程序:
#!r6rs
(import (rnrs base)
(rnrs syntax-case)
(rnrs io simple))
(define-syntax stest
(lambda (x)
(syntax-case x ()
((_ z) #'(z 0)))))
(stest display)
适用于 Chez、Guile 和 Ypsilon,但不适用于 Racket。它给了我这个:
test.scm:7:3: lambda: unbound identifier in the transformer
environment;
also, no #%app syntax transformer is bound
我的问题是,R6RS 是否坏了,还是我必须做其他事情?我正在测试 6.12 版。
R6RS 的 Racket 实现在这种情况下并非不兼容。实际上,如果有的话,它更严格地遵守标准:您编写的程序不注意导入阶段。问题是 define-syntax
在扩展期间评估其右侧,如 11.2.2 Syntax definitions:
部分所述
Binds <keyword> to the value of <expression>, which must evaluate, at macro-expansion time, to a transformer.
与其他 Scheme 标准不同,R6RS 会注意区分阶段,因为它允许在编译时进行任意编程(而其他 Scheme 标准则不允许)。因此,第7.1 Library form节指定了如何在特定阶段导入库:
Each <import spec> specifies a set of bindings to be imported into the library, the levels at which they are to be available, and the local names by which they are to be known. An <import spec> must be one of the following:
<import set>
(for <import set> <import level> ...)
An <import level> is one of the following:
run
expand
(meta <level>)
where <level> represents an exact integer object.
因此,在run
和expand
阶段都需要导入(rnrs base)
,在expand阶段需要导入(rnrs syntax-case)
。您可以使用以下程序执行此操作:
#!r6rs
(import (for (rnrs base) run expand)
(for (rnrs syntax-case) expand)
(rnrs io simple))
(define-syntax stest
(lambda (x)
(syntax-case x ()
((_ z) #'(z 0)))))
(stest display)
此程序适用于 Racket。我没有测试它是否也适用于您列出的其他 Scheme 实现,但如果它们符合标准,它应该可以。
这个简单的 R6RS 程序:
#!r6rs
(import (rnrs base)
(rnrs syntax-case)
(rnrs io simple))
(define-syntax stest
(lambda (x)
(syntax-case x ()
((_ z) #'(z 0)))))
(stest display)
适用于 Chez、Guile 和 Ypsilon,但不适用于 Racket。它给了我这个:
test.scm:7:3: lambda: unbound identifier in the transformer environment;
also, no #%app syntax transformer is bound
我的问题是,R6RS 是否坏了,还是我必须做其他事情?我正在测试 6.12 版。
R6RS 的 Racket 实现在这种情况下并非不兼容。实际上,如果有的话,它更严格地遵守标准:您编写的程序不注意导入阶段。问题是 define-syntax
在扩展期间评估其右侧,如 11.2.2 Syntax definitions:
Binds <keyword> to the value of <expression>, which must evaluate, at macro-expansion time, to a transformer.
与其他 Scheme 标准不同,R6RS 会注意区分阶段,因为它允许在编译时进行任意编程(而其他 Scheme 标准则不允许)。因此,第7.1 Library form节指定了如何在特定阶段导入库:
Each <import spec> specifies a set of bindings to be imported into the library, the levels at which they are to be available, and the local names by which they are to be known. An <import spec> must be one of the following:
<import set> (for <import set> <import level> ...)
An <import level> is one of the following:
run expand (meta <level>)
where <level> represents an exact integer object.
因此,在run
和expand
阶段都需要导入(rnrs base)
,在expand阶段需要导入(rnrs syntax-case)
。您可以使用以下程序执行此操作:
#!r6rs
(import (for (rnrs base) run expand)
(for (rnrs syntax-case) expand)
(rnrs io simple))
(define-syntax stest
(lambda (x)
(syntax-case x ()
((_ z) #'(z 0)))))
(stest display)
此程序适用于 Racket。我没有测试它是否也适用于您列出的其他 Scheme 实现,但如果它们符合标准,它应该可以。