这个简单的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:变换器中的未绑定标识符 环境;
此外,没有绑定#%app语法转换器
我的问题是,R6RS是否已损坏,还是我必须做其他事情?我正在使用6.12版进行测试。
答案 0 :(得分:4)
在这种情况下,R 6 RS的Racket实现不是不合规的。事实上,如果有的话,它更贴近标准:你编写的程序对导入阶段并不谨慎。问题是define-syntax
在扩展时评估其右侧,如11.2.2 Syntax definitions部分所述:
绑定< keyword>到< expression>的值,它必须在宏扩展时评估变换器。
与其他Scheme标准不同,R 6 RS注意区分阶段,因为它允许在编译时进行任意编程(而其他Scheme标准则不允许)。因此,第7.1 Library form部分指定了如何在特定阶段导入库:
每个< import spec>指定要导入到库中的一组绑定,它们可用的级别以及用于知道它们的本地名称。 < import spec>必须是以下之一:
<import set> (for <import set> <import level> ...)
&lt; import level&gt;是以下之一:
run expand (meta <level>)
其中&lt; level&gt;表示一个精确的整数对象。
因此,您需要在(rnrs base)
和run
阶段导入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实现,但它应该符合标准。