Scheme中的实现依赖代码

Posted

技术标签:

【中文标题】Scheme中的实现依赖代码【英文标题】:Implementation dependent code in Scheme 【发布时间】:2015-05-30 05:35:28 【问题描述】:

Common Lisp 中,当我想根据Common Lisp 实现使用不同的代码时,我可以使用*features* 以及提供的#+#- 表示法来检查给定功能的可用性并据此进行。例如(取自 Peter Seibel 的 PCL):

(defun foo ()
  #+allegro (do-one-thing)
  #+sbcl (do-another-thing)
  #+clisp (something-else)
  #+cmu (yet-another-version)
  #-(or allegro sbcl clisp cmu) (error "Not implemented"))

有人知道 Scheme 的类似机制吗? Scheme 的不同实现之间有时存在细微差别,当您尝试可移植时,最好将其抽象掉。我想到的一种情况是Racket 默认情况下不提供可变对。而不是写例如(set-cdr! lst '(1 2 3)) 你必须使用set-mcdr! 并且只有在你运行(require racket/mpair) 之后。当然,这些东西可以通过函数和/或宏来抽象,但我认为Common Lisp 方法在这方面很简洁。

【问题讨论】:

方案有几个标准规范,最常见的是R5RSR6RSR7RS。选择你想问的问题,问之前研究它。 在 Racket 上,set-mcdr! 仅适用于 完全独立的数据结构,而这不是 mapfoldlfilter 或基本上不支持的数据结构库中需要列表的任何函数。 Racket 的运行时库仅支持不可变列表。 @ThrowawayAccount3Million 你的意思是Racket 语言不是Scheme。 Rackets rnrs-implementations 支持可变对就好了。 @ThrowawayAccount3Million,你说的没错,但问题的核心是区分实现的机制。 【参考方案1】:

最接近的是cond-expand(又名SRFI 0),它在某些方案中可用,但在其他方案中不可用(例如,Racket 没有它,如果您尝试,您的代码将无法编译使用它)。对于那些确实有它的方案,它看起来像一个cond 表单,除了你测试告诉你关于编译器/解释器的事情的布尔值。在某些方案上,您可以检测您正在运行哪个方案,而在其他方案上,您只能检查 SRFI:

(cond-expand (chicken
              'bok-bok-bok!)
             ((and guile srfi-3432)
              'this-guile-is-full-of-SRFI!)
             (else
              '(might be MIT Scheme, whose cond-expand only tests for SRFIs)))

【讨论】:

谢谢,这实际上回答了我的问题。我为 Racket here 找到了 cond-expand 的实现,但实际上它只能使 Racket 适合 else 分支,这可能还不够。 @WojciechGac 你也有SRFI-7。 AFAIK Racket 将其列在已实施的 SRFI 列表中。 谢谢@Sylwester,我去看看。

以上是关于Scheme中的实现依赖代码的主要内容,如果未能解决你的问题,请参考以下文章

关于 Scheme (plt-scheme) 中的“If..”

Mina中的基于DLG的Plonk polynomial commitment scheme代码解析

IDEA插件开发(25)--Color Scheme Management

帮助理解 Scheme 中的 Continuations

Scheme中的冒泡排序

Scheme中的向量