【问题标题】:Implementation dependent code in SchemeScheme中的实现依赖代码
【发布时间】: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,你说的没错,但问题的核心是区分实现的机制。

标签: scheme lisp common-lisp racket language-features


【解决方案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,我去看看。
猜你喜欢
  • 2011-07-14
  • 1970-01-01
  • 2011-04-14
  • 2018-12-20
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多