我设法将 Racket 和 R7RS 代码混合用于实际工作,并以on GitHub 技术为例。
这是该仓库的自述文件的副本:
球拍 R7RS 垫片
Racket 不支持 R7RS。它在第三方包中
r7rs 亚历克西斯·金:https://github.com/lexi-lambda/racket-r7rs
尽管不是 Racket 的官方组成部分,但它对
我(我使用了一个中等复杂的库来做 HTML 解析并写了
一些涉及字符串处理和树在其上行走,
所以这对实际工作绝对有用)。
您可以通过raco pkg install r7rs 安装垫片。另请注意
info.rkt 在依赖项中列出 r7rs,这是 Heroku 所需的
之类的。
模块
-
app -- 一个 Racket 应用程序
-
lib -- app 使用的 R7RS 库
-
sublib -- lib 使用的 R7RS 库
模块由哪些文件组成
所以app 只需要一个文件,app.rkt,就像任何普通的球拍一样
模块。
但是lib 和sublib 分别需要 3 个文件。 lib.scm 是方案
代码。 lib.sld 是 Scheme 库定义。而lib.rkt 是一个
球拍包装。从技术上讲,您可以结合 lib.sld 和
lib.scm 放在一个文件中,但将它们分开会更干净。你
也可以将您的所有 Scheme 代码直接复制到 lib.rkt 但随后
您不能将其导入其他方案。
请注意,lib.scm 顶部没有 (import ...) 表单。
导入位于lib.sld 中的define-library 表单内。这
define-library 表单使用 (include ...) 包含实际代码
在lib.scm。
lib.rkt 的工作只是对 Racket 说#lang r7rs 然后
包括方案的东西。首先需要(import (scheme base))
这样我们就可以使用include 和export。包含的.sld 文件
从库的 Scheme 标准中导入所有其他内容
需要。
请注意 lib 依赖于 sublib 但 sublib 不是由
lib.sld 中的 define-library 表单。相反,lib.rkt 必须加载
lib 及其所有依赖项:它包含(include "sublib.sld")
除了明显的(include "lib.sld")。
所以lib.sld 只从 Scheme 标准中导入东西,而
lib.rkt 导入我们所有的自定义库。我不得不求助于这个
hack,因为我无法让 Racket 模块查找器找到 sublib
如果我把它放在(define-library ...) 进口中。我没有努力
完全没有,所以很可能有办法让它发挥作用。
可变与不可变列表
Racket 使用不可变的 cons 单元(由 Racket 的 cons 制作,满足
pair?) 默认情况下,而 R7RS 使用可变的 cons 单元格(由
球拍的mcons,满足mpair?)。也就是说,当你打电话给cons
在 Scheme 方面,它实际上做了一些看起来像 Racket
就好像您在球拍端调用了mcons。可变的缺点意味着
你可以使用 Scheme 的 set-car! 和 set-cdr! 来改变它,
而不可变 cons 的 car 和 cdr 之后无法更改
最初的cons。
默认情况下,Racket 显示由可变 conses 组成的列表,使用
{curly braces} 而不是 (ordinary parentheses)。这会咬人
当您通过 R7RS--Racket 边界传递列表时。你可以打印
通过更改print-mpair-curly-braces 使用普通括号
参数,但对于许多事情,转换列表可能更容易
(和树)从可变到不可变。
我不知道 Racket R7RS shim 是否允许您将其设为不可变
方案方面的缺点。有一个选项会很好
计划cons 制作不可变的conses(在这种情况下set-car! 和
set-cdr! 会导致错误,这对于仅使用的代码很好
不可变的数据结构)。
在哪里可以找到 R7RS 库
Alex Shinn 收集了很多 R7RS 库
http://snow-fort.org/
底线
这一切的结果是您可以将 R7RS 和 Racket 与
很少的工作,你的代码库保持很干净(至少对于简单的
例)。