scheme - Racket R6RS支持: syntax-case

标签 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: 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.

因此,在runexpand阶段都需要导入(rnrs base),并且需要导入 (rnrs 语法案例) 在扩展阶段。您可以使用以下程序来完成此操作:

#!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 - Racket R6RS支持: syntax-case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50821083/

相关文章:

Scheme Factorial (fact* l) 问题

scheme - Racket (方案)错误: expected the name of the symbol after the quote,但找到了零件

scheme - minikanren 中的特征结构统一

scheme - 自由标识符=之间的区别?和边界标识符=?

list - Racket 列表与 r6rs 不兼容?

scheme - 实现 yield 并在 Scheme 中发送

scheme - 列表和数字之间的最小值

lisp - 如何在方案中获取列表(子列表)的一部分?

scheme - 反转整数

file - 在Scheme R6RS中是否可以有效地从磁盘加载整个文件?