Racket R6RS支持:语法大小写

时间:2018-06-12 15:43:30

标签: scheme racket r6rs

这个简单的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版进行测试。

1 个答案:

答案 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实现,但它应该符合标准。