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
方法在这方面很简洁。
【问题讨论】:
方案有几个标准规范,最常见的是R5RS、R6RS、R7RS。选择你想问的问题,在问之前研究它。 在 Racket 上,set-mcdr!
仅适用于 完全独立的数据结构,而这不是 map
、foldl
、filter
或基本上不支持的数据结构库中需要列表的任何函数。 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代码解析