【问题标题】:How is Racket different from Scheme?Racket 与 Scheme 有何不同?
【发布时间】:2011-03-21 16:45:33
【问题描述】:

Racket 是 Scheme 的后代。 Racket 与 R6RS 有何不同?它增加了什么,减少了什么,或者只是不同?

我知道 Racket 不仅仅是一种语言,它还是一个语言平台。但我指的是主要的球拍方言。

【问题讨论】:

    标签: scheme lisp racket


    【解决方案1】:

    Racket 包含许多 R6RS 方案中未包含的非常好的语言结构,例如 "match"

    【讨论】:

    • 为什么“匹配”是一个不错的功能?至少,在发表意见的时候,应该对它做一个简短的解释,让不熟悉Racket的人能够理解为什么“匹配”在理论上是有益的。
    • 模式匹配是许多具有函数式编程背景的语言真正需要的功能,不幸的是,即使 R6RS 或 Common Lisp 默认情况下也没有实现这一点,所以是的,这是 Racket 提供的一个非常好的和差异化的功能.例如,Haskell、Elixir、Rust 和 F# 等语言提供了这种类型的结构并且被大量使用。我个人主要使用 Common Lisp 进行 Lisp 编程,但在很多情况下我都想念缺少模式匹配实现。
    • match 非常好,但幸运的是它只是一个宏,所以它可以很容易地添加到没有它的 Lisps 中。 Common Lisp 可以通过destructuring-bind 对列表进行光模式匹配。基于它写一个destructuring-case宏很简单,很多人都有。对于 Scheme,有可移植的 match 库。 Clojure 有core.match
    • 宏会使代码难以阅读,因为它们通常具有特殊的语义,因此该语言应该始终标准化所有通用宏,这样每个人都不会构建自己的宏。模式匹配应该是默认的,就像在 Arc & Clojure & Racket & Ocaml & Haskell 中一样,因为它更直接地指定了意图。 Caddr 级别太低。
    【解决方案2】:

    Racket 最终基于 R5RS,而不是 R6RS,也不是两者的严格超集。我认为它不能被称为“Scheme”,因为它不向后兼容任何 Scheme 标准。

    大多数实现都提供扩展,但在其他方面向后兼容,当然,Racket 附带的编译器也可以在 R5RS 或 R6RS 模式下运行。在球拍模式下运行的有效 R5/6RS 方案可能会被拒绝、导致运行时错误或行为与应有的不同。话虽如此,它不向后兼容的要点是:

    • Racket 没有 set-cdr!set-car!,而是 set-mcar!,它只适用于专门创建为可变的对。
    • Racket 调用 letrec 在 R6RS 中称为 letrec* 而在 R5RS 中不存在,R5RS 和 R6RS 调用 letrec 在 Racket 中不存在。
    • 在 Racket 中,很多东西都是自我评估的,这会在 R5RS 中引发错误,最重要的是空列表
    • Racket 区分大小写,但 R6RS 也区分大小写
    • Racket 将 ( ... )[ ... ] 视为等效,R5RS 没有,但 R6RS 可以。

    可能还有更多,但在大多数其他部分,球拍是 Scheme 的超集。

    【讨论】:

    • 在球拍中() 无效,不能自我评估。此外,Racket 确实 具有更受限制的 letrec ——例如,r5rs 语言中的那个;在默认语言中使用类似letrec* 的版本是有意的选择。
    • @Eli,哎呀,你说得对,在 Swindle 模式下运行的球拍似乎考虑了 () 自我评估,我对那个感到困惑。我从来没有真正明白为什么 () 在 Scheme 中不像在 Common Lisp 中那样自我评估。
    • @Zorf 可以通过重载#%app 轻松更改,不过:#lang racket (require (rename-in racket [#%app old])) (define-syntax #%app (syntax-rules () [(_) '()] [(_ . rest) (old . rest)])) (null? ()) ;; => #t
    • 这个答案应该更新。 Racket 的功能集远远超过了现在的 Scheme,模块和语言定义等。
    • @MaliRemorker 我不明白你的意思,但是Scheme 目前在R7RS 上并且在R6RS 上。但 Racket 仍然胜过 R6RS 功能集。
    【解决方案3】:

    关于 Scheme 编程语言的语言规范 R5RS 基于多个 Scheme 实现者之间的共识。这意味着该语言非常稳定。这也意味着许多有用的功能不是 R5RS 标准的一部分。

    Racket 建立在 R5RS 的基础上并对其进行了极大的扩展。有些扩展被定义为宏,但有些功能需要运行时系统的支持。

    仅通过宏无法实现 Racket 中的功能:

    • 分隔延续(比 call/cc 更通用)
    • 继续标记
    • 线程
    • 地点

    模块和宏系统比 RnRS 规范更通用。 与#lang 阅读器/语言规范一起,可以定义自定义语言(使用自定义语法)并将它们与普通 Racket 程序一起使用。

    在少数情况下,Racket 具有行为偏离 R5RS 的构造。最明显的是让cons 构造一个不可变对(mcons 构造一个可变对)。具有不可变对的一个优点是 length 现在在 O(1) 摊销时间内运行。

    【讨论】:

    • ... 但它使 O(1) 列表无法追加。
    【解决方案4】:

    将名称从 PLT Scheme 更改为 Racket 的理由已在 on the Racket site 讨论。

    【讨论】:

      【解决方案5】:

      如上所述,它包含不可变列表。它还包含一个比 R6RS 记录系统更干净的结构系统。它有一个面向对象的类和对象系统。它对按合同进行设计具有本机支持。它有一个让人联想到 ML 模块系统的单元系统,以及一个非常类似于 R6RS 模块系统的模块系统。我确定我已经忘记了很多我提到的东西。

      除了营销噱头之外,我不确定重命名是否有用,但球拍绝对是一种独特的方案方言。

      【讨论】:

      • 我认为重命名是因为他们不想成为带有一堆非标准添加的 Scheme 的方言——他们希望成为一种基于 Scheme 的语言,带有更多标准的东西。将 PLT Scheme 归类为“只是”Scheme 的一种方言就像将 Ruby 归类为 Mirah 的一种方言——这不是不准确,但它有点低估了该语言的优势。
      • 我认为使用不同的名称是一个明智的决定:对具有共同起源的不同语言使用相同的名称会使 IMO 混淆。即使该语言包含 Scheme 作为一个子集,但我会更改名称,但包含如此多的附加内容,以至于它会鼓励一种非常不同的编程风格。
      【解决方案6】:

      举一个重要的例子,Racket 列表默认是不可变的,而 Scheme 是可变的。 Racket 还包含许多其他方案没有的标准库(例如 Web 服务器)。

      【讨论】:

        猜你喜欢
        • 2011-08-06
        • 2012-10-24
        • 2011-10-31
        • 2018-11-10
        • 2014-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多