在Racket程序中使用Scheme库

时间:2019-03-19 13:38:36

标签: scheme racket

我用Racket编写了一个程序(源代码在.rkt文件中,#lang racket在顶部)。我还用(主要)便携式R7RS Scheme写了一个库。我可以以干净的方式在程序中使用该库吗?

我的目标是使该库在Scheme实现之间具有广泛的可移植性(至少是与R7RS兼容的实现,理想情况下也应如此)。有第三方R7RS shim for Racket,但据我所知,它要求我在源文件顶部键入#lang r7rs。我猜想这个#lang指令会使Racket之外的Scheme感到困惑。

我可以将库的核心放在一个或多个可移植的.scm源文件中,然后使用.rkt伪指令让一个#lang r7rs文件告诉Racket以某种方式包括可移植文件? Racket是否了解某种库定义文件,例如snow-fort上使用的.sld

我尝试浏览了整个Racket文档,但在任何地方都找不到。我也找不到通用的Scheme可移植性常见问题解答或最佳做法文档。

1 个答案:

答案 0 :(得分:1)

在实际工作中,我设法混合了Racket和R7RS代码,并举例说明了on GitHub技术。

这是该仓库中自述文件的副本:


Racket R7RS Shim

球拍不附带R7RS支持。在第三方包装中 r7rs,作者:亚历克西斯·金(Alexis King):https://github.com/lexi-lambda/racket-r7rs 尽管它不是Racket的正式组成部分,但对于 我(我使用一个中等复杂的库进行HTML解析并编写 一些烦人的事涉及字符串处理和在其上行走的树, 因此这对于实际工作绝对是有用的。)

您可以通过raco pkg install r7rs安装垫片。另请注意 info.rkt在依赖项中列出r7rs,这是Heroku所需的 等等。

模块

  • app-一个Racket应用程序
  • libapp
  • 使用的R7RS库
  • subliblib
  • 使用的R7RS库

模块由什么文件组成

所以app只需要一个文件app.rkt,就像任何普通的球拍一样 模块。

但是libsublib分别需要3个文件。 lib.scm是计划 码。 lib.sld是Scheme库定义。 lib.rkt是一个 球拍包装纸。从技术上讲,您可以结合使用lib.sldlib.scm合并到一个文件中,但将它们分开更干净。您 也可以将您所有的Scheme代码直接复制到lib.rkt中,然后 您不能将其导入其他计划。

请注意,lib.scm的顶部没有(import ...)形式。 导入位于define-library中的lib.sld表单中。的 define-library表单使用(include ...)包含实际代码 在lib.scm中。

lib.rkt的工作只是向球拍说#lang r7rs,然后 包括计划的东西。首先需要(import (scheme base)) 这样我们就可以使用includeexport。包含的.sld文件 从该库的Scheme标准中导入其他所有内容 需求。

请注意,lib依赖于sublib,但sublib不是由 define-library中的lib.sld形式。相反,lib.rkt必须加载 lib 及其所有依赖项:它包含(include "sublib.sld") 除了显而易见的(include "lib.sld")

因此lib.sld仅从Scheme标准中导入内容,而 lib.rkt导入我们所有的自定义库。我不得不诉诸于此 hack是因为我无法通过Racket模块查找器来找到sublib 如果我将其放在(define-library ...)导入中。我没有努力 根本没有,所以很可能有一种方法可以使它工作。

可变列表与不可变列表

Racket使用不变的con单元格(由Racket的cons制造,满足 pair?),而R7RS使用可变的cons单元(由 球拍的mcons满足mpair?)。也就是说,当您致电cons 在方案方面,它实际上可以使球拍看起来很像 就像您在球拍那边打过mcons一样。可变的缺点意味着 您可以使用Scheme的set-car!set-cdr!对其进行更改, 而一成不变的缺点的汽车和cdr以后不能更改 最初的cons

默认情况下,“球拍”显示使用 {curly braces},而不是(ordinary parentheses)。这会咬 您在R7RS-球拍边界上传递列表时。您可以列印 通过更改print-mpair-curly-braces使用普通括号 参数,但在很多情况下,转换列表可能会更容易 (和树木)从可变到不变。

我不知道Racket R7RS垫片是否可以使您一成不变 在方案方面。可以选择 使用方案cons来实现不变的约束(在这种情况下,set-car!set-cdr!会导致错误,这对于仅使用代码的情况很好 不变的数据结构)。

在哪里可以找到R7RS库

许多R7RS库由Alex Shinn在以下位置收集 http://snow-fort.org/

底线

所有这些的结果是您可以将R7RS和Racket与 很少的工作,您的代码库就保持整洁(至少对于简单 情况)。