Scheme 方案中依赖于实现的代码

Scheme 方案中依赖于实现的代码,scheme,lisp,common-lisp,racket,language-features,Scheme,Lisp,Common Lisp,Racket,Language Features,在Common-Lisp中,当我想根据Common-Lisp实现使用不同的代码段时,我可以使用*功能*和提供的+和-符号来检查给定功能的可用性并相应地进行操作。例如(摘自Peter Seibel的PCL): 有人知道类似的计划机制吗?Scheme的不同实现之间有时会有细微的差异,当您试图实现可移植性时,最好将其抽象出来。我想到的一个例子是,Racket默认情况下不提供可变配对。您必须使用设置mcdr!而不是编写例如(设置cdr!lst'(1 2 3))并且仅在您运行(需要球拍/mpair)之后。

Common-Lisp
中,当我想根据
Common-Lisp
实现使用不同的代码段时,我可以使用
*功能*
和提供的
+
-
符号来检查给定功能的可用性并相应地进行操作。例如(摘自Peter Seibel的PCL):


有人知道类似的计划机制吗?Scheme的不同实现之间有时会有细微的差异,当您试图实现可移植性时,最好将其抽象出来。我想到的一个例子是,
Racket
默认情况下不提供可变配对。您必须使用
设置mcdr!而不是编写例如
(设置cdr!lst'(1 2 3))
并且仅在您运行
(需要球拍/mpair)
之后。当然,这些东西可以通过函数和/或宏来抽象,但我认为
公共Lisp
方法在这方面很好

最接近的是
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)))

该方案有几个标准规范,最常见的是R5RS、R7RS。选择一个你想问的,在问之前先研究一下。在球拍上,
设置mcdr
仅适用于完全独立的数据结构,而该数据结构不受
map
foldl
filter
或库中任何需要列表的函数的支持。Racket的运行库只支持不可变列表。@ThrowawayAccount3Million您是指Racket语言中的ThrowawayAccount3Million,它不是Scheme。Rackets rnrs实现对可变对的支持非常好。@ThrowawayAccount3Million,这正是您所指出的,但问题的核心是区分实现的机制。谢谢,这实际上回答了我的问题。我为Racket找到了
cond expand
的一个实现,但实际上,它只能使Racket适合
else
分支,这可能还不够。@WojciechGac您也有。AFAIK Racket已将其列入其已实施的SRFI列表。谢谢@Sylvester,我会看一看。
(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)))