scheme - 在 Racket 程序中使用 Scheme 库

标签 scheme racket

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

我的目标是让库在 Scheme 实现之间具有广泛的可移植性(至少是符合 R7RS 的实现,理想情况下也包括其他实现)。有第三方R7RS shim for Racket但据我所知,它需要我输入 #lang r7rs在我的源文件的顶部。我猜这个 #lang指令会混淆 Racket 以外的 Scheme。

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

我试图查看整个 Racket 文档,但在任何地方都找不到讨论的内容。我也没有找到一般的 Scheme 可移植性常见问题解答或最佳实践文档。

最佳答案

我设法在实际工作中混合使用 Racket 和 R7RS 代码,并制作了该技术的示例 on GitHub .

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

Racket 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 ,就像任何普通的 Racket 一样
    模块。

    但是libsublib每个需要3个文件。 lib.scm是方案
    代码。 lib.sld是 Scheme 库定义。和 lib.rkt是一个
    它的 Racket 包装。从技术上讲,您可以结合 lib.sldlib.scm合并到一个文件中,但将它们分开会更干净。你
    也可以将你所有的 Scheme 代码直接复制到 lib.rkt但是之后
    你不能将它导入到其他 Schemes 中。

    请注意 lib.scm没有 (import ...)在顶部形成。
    进口在 define-library 内表格在 lib.sld .这define-library表格用途 (include ...)包含实际代码
    lib.scm .
    lib.rkt的工作只是说#lang r7rs到 Racket 然后
    包括计划的东西。它首先需要(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 使用不可变的 cons 单元(由 Racket 的 cons 制作,满足pair? ) 默认情况下,而 R7RS 使用可变的 cons 单元格(由
    Racket 的mcons ,满足mpair? )。也就是说,当您拨打 cons
    在 Scheme 方面,它实际上做了一些看起来像 Racket 的东西
    好像你打过电话 mcons在 Racket 一侧。可变的缺点意味着
    您可以使用 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做出不可变的结论(在这种情况下 set-car!set-cdr!会导致错误,这对于仅使用的代码很好
    不可变的数据结构)。

    在哪里可以找到 R7RS 库

    许多 R7RS 库由 Alex Shinn 在
    http://snow-fort.org/

    底线

    所有这一切的结果是,您可以将 R7RS 和 Racket 与
    很少工作,您的代码库保持非常干净(至少对于简单的
    案例)。

    关于scheme - 在 Racket 程序中使用 Scheme 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55242394/

    相关文章:

    list - 使用参数评估 Racket 中的列表

    racket - sub1的类型不匹配问题

    scheme - 方案中嵌套定义的体面方式

    console - 如何使用控制台作为Guile Scheme的输入和输出?

    list - Scheme中获取树中元素的总和

    recursion - 如何从方案、 Racket 中的列表制作 HTML

    scheme - Scheme 和 Racket 中嵌套引号的行为

    functional-programming - 是否有支持可移植延续的快速语言?

    Racket 。识别宏观图案中的特殊符号

    racket - 需要使用项目根目录中的模块路径吗?