编写可移植方案代码。除了 R5RS 本身还有啥“标准”吗?

Posted

技术标签:

【中文标题】编写可移植方案代码。除了 R5RS 本身还有啥“标准”吗?【英文标题】:Writing portable scheme code. Is anything "standard" beyond R5RS itself?编写可移植方案代码。除了 R5RS 本身还有什么“标准”吗? 【发布时间】:2012-06-19 05:04:00 【问题描述】:

我正在学习计划,直到现在一直在使用诡计。我真的只是在学习一种自学函数式编程语言的方法,但我想发布一个开源项目以加强这项研究——还不确定是什么......我是一名网络开发人员,所以可能是网状的。

很明显,发布方案代码并不是一件容易的事,因为所有这些不同的实现以及超出语言本身核心 (R5RS) 的真正标准。例如,我几乎肯定需要在磁盘上和通过 TCP 套接字进行基本 IO,以及字符串操作,例如扫描/正则表达式,这似乎没有被 R5RS 覆盖,除非我没有看到它在文档中。似乎 Scheme 更像是一种“概念”而不是实用语言……这是一个公平的评估吗?如果我想学习一种更适合在开源项目中使用的函数式编程语言,也许我应该看看 Haskell 之类的东西?

实际上,当您想要发布一个开源项目时,不同的方案实现会带来多大的痛苦?我真的不喜欢在各种主流实现(Chicken、guile、MIT、DrRacket)下维护 5 个不同的函数来处理基本的事情,比如字符串操作。有多少人真正为跨实现兼容性编写方案,而不是与只存在于他们自己方案中的库函数紧密耦合?

我读过http://www.ccs.neu.edu/home/dorai/scmxlate/scheme-boston/talk.html,这并没有让我充满信心;)

编辑 |让我们将“标准”重新定义为“普通”。

【问题讨论】:

您的问题似乎使您认为 R5RS 是 Scheme 的最新标准,但事实并非如此。 R6RS 可以处理您所询问的更多事情,它于 2009 年发布,是当前的 Scheme 标准 R6RS 仍然太小而无法完成很多事情,因此您可能希望坚持使用特定的实现。我使用(和开发)Racket,但 Guile 也是一个合理的选择。 【参考方案1】:

我相信在Scheme中,可移植性是一件傻事,因为Scheme实现的不同之处多于相似之处,并且没有其他实现试图模仿的单一实现(不像Python和Ruby ,例如)。

因此,Scheme 中的可移植性类似于使用软件渲染来编写游戏,“因为它位于 OpenGL 和 DirectX 之间的公共子集中”。换句话说,它是一个最小的公分母——它可以做到,但您无法访问该实现提供的许多功能。

因此,虽然 SRFI 通常具有可移植的参考实现(在可行的情况下),但其中一些还附有说明,即高质量的 Scheme 实现应定制库以使用特定于实现的功能,以实现最佳功能。

一个典型的例子是case-lambda (SRFI 16);它可以移植地实现,参考实现演示了它,但与内置的 case-lambda 相比,它肯定不是最优的,因为您必须在“用户”代码中实现函数调度。 另一个例子是stream-constant 来自SRFI 41。参考实现使用循环列表的 O(n) 模拟来实现可移植性,但任何体面的实现都应该调整该函数以使用真正的循环列表,以便它是 O(1)。

名单还在继续。 Scheme 中的许多有用的东西是不可移植的——SRFI 有助于使更多的功能可移植,但 SRFI 不可能涵盖所有内容。如果您想有效地完成有用的工作,您很有可能必须使用非便携式功能。我认为,你能做的最好的事情就是编写一个外观来封装那些 SRFI 尚未涵盖的功能。

实际上有now a way to implement stream-constant in an O(1) fashion 根本没有使用循环列表。便携、快速,助您一臂之力!

【讨论】:

您对 r7rs small/large 有何看法?你认为他们“解决”了傻瓜的跑腿问题吗?【参考方案2】:

难题。

大多数人决定务实。如果实现之间的可移植性很重要,他们会在标准 Scheme 中编写大部分程序,并将非标准部分隔离在(小型)库中。有多种方法可以准确地做到这一点。最近的一项努力是 SnowFort。

http://snow.iro.umontreal.ca/

一个较老的尝试是 SLIB。

http://people.csail.mit.edu/jaffer/SLIB

如果您查找 - 或要求 - 正则表达式和词法分析器/解析器库,您会很快找到一些。

由于 R5RS 的理念是只包含所有实现者都同意的语言特性,因此标准很小 - 但也非常稳定。

但是,对于“现实世界”编程,R5RS 可能不是最合适的。 因此,R6RS(和 R7RS?)包含更多“真实世界”的库。

也就是说,如果您只需要可移植性,因为它似乎是正确的事情,那么如果您真的想要付出努力,请仔细考虑。 我会简单地在我最了解的实现上编写我的程序。然后如果有必要之后移植它。这通常比预期的要容易。

【讨论】:

很好的答案,谢谢。我会再开一会儿。我使用 guile 的原因之一是因为它不需要 Java 并且是用 C 编写的(我没有 JVM,也不想安装)。不幸的是,我不相信 guile 有符合 R6RS 的版本,而 MIT-Scheme 表示他们不打算编写一个。鸡还是R5RS。可能需要搜索其他具有 R6RS 的 C 实现 :) 雪看起来很有趣。听起来像是 ruby​​gems 或 NPM。 Snow 适用于可移植代码。另请参阅 planet.racket-lang.org 和 wiki.call-cc.org/chicken-projects/egg-index-4.html 了解更多软件包。即使包裹在球拍或鸡肉页面上,中间也有一些便携式包裹。不幸的是,您需要查看源代码才能找到答案。【参考方案3】:

我写了一个blog,它使用Scheme 作为它的实现语言。因为我不想疏远任何特定 Scheme 实现的用户,所以我使用基于 R5RS 加上语法大小写宏以及我的 Standard Prelude 的 Scheme 的受限方言编写。对于我编写的算法程序,我认为这并没有过度限制,但您的需求可能会有所不同。如果您查看博客上的各种练习,您会发现我编写了自己的正则表达式匹配器,我已经完成了大量的字符串操作,并且我已经从互联网上抢走了文件wget(我使用 Chez Scheme——如果他们使用其他任何东西,用户必须提供他们自己的非便携式 shell 机制);我什至通过编写 ANSI 终端序列完成了一些有限的图形工作。

我有点不同意 Jens。我发现从一开始就更容易构建可移植性,而不是事后移植。我以前不这么想,但我过去三年的经验表明它是有效的。

【讨论】:

有趣的博客。将不得不密切关注它。你的意思是博客是用 Scheme 写的,还是 WordPress? o_O 博客是 WordPress。解决方案在 Scheme 中实现。 LOL 一开始我以为是用 Scheme 写的 =)【参考方案4】:

值得指出的是,现代 Scheme 实现本身是相当可移植的;您通常只需携带适当的方案即可将整个程序移植到新环境。不过,这对库程序员没有多大帮助,而这正是最新的 Scheme 定义 R7RS-small 的用武之地。它尚未广泛实施,但它提供了比 R5RS 更大的通用核心。

【讨论】:

R7RS-small 提供比 R7RS 更大的通用内核?当然你的意思是R5RS。 :-D

以上是关于编写可移植方案代码。除了 R5RS 本身还有啥“标准”吗?的主要内容,如果未能解决你的问题,请参考以下文章

编写可移植C/C++程序的要点

除了乘法和求幂,星号在 Python 中还有啥作用? [复制]

除了实例化 DAL 的 BLL 之外,还有啥选项允许在 n 层解决方案中进行单元测试,而不会将 DAL 暴露给 UI 或将 BLL 暴露给 DAL?

使我的 SSIS 包可移植 - 如何做到这一点?

malloc 和 HeapAlloc 之间是不是存在根本区别(除了可移植性)? [复制]

什么时候装配比C快?