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 版本进行测试。
解决方案
在这种情况下,R 6 RS的 Racket 实现并非不兼容。事实上,如果有的话,它更严格地遵守标准:您编写的程序对导入阶段并不小心。问题是define-syntax
在扩展时间评估其右侧,如第11.2.2 节语法定义所述:
将 <keyword> 绑定到 <expression> 的值,该值必须在宏扩展时对转换器求值。
与其他 Scheme 标准不同,R 6 RS 小心区分阶段,因为它允许在编译时进行任意编程(而其他 Scheme 标准则不允许)。因此,第7.1 节库形式指定了如何在特定阶段导入库:
每个 <import spec> 指定一组要导入到库中的绑定、它们可用的级别以及知道它们的本地名称。<import spec> 必须是以下之一:
<import set> (for <import set> <import level> ...)
<import level> 是以下之一:
run expand (meta <level>)
其中 <level> 表示一个精确的整数对象。
因此,(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 实现,但如果它们符合标准,它应该可以。
推荐阅读
- php - 如何在 Laravel 8 中实现记住我?
- python - Python Bs4表打印(行)不显示行
- typescript - 应用于与 Record 相交的类型时,Keyof 会丢失已知属性
并导致与 Omit 一起使用的类型不正确 - javascript - Fade out 淡入表格行
- c# - 如何在活动目录中获取用户可以管理(添加/删除用户)的组列表
- python - Python - 升级到 3.9.1 后 bson 导入错误
- excel - 如何从 Google Analytics(分析)报告中获取真实数量的用户
- terraform - icmp 协议入口规则 aws_security_group 资源的 from_port 和 to_port 值?
- arrays - 文件指针数组的分段错误
- google-sheets - 根据所选月份填充日期行