9

我听说有人声称:

  • Scala 的类型系统令人惊叹(存在类型、变体、协变)

  • 由于宏的强大功能,Clojure 中的一切都是库:(模式匹配、逻辑编程、非确定性……)

问题:

如果两个断言都是真的,为什么 Scala 的类型系统不是 Clojure 中的库?是不是因为:

  • 类型是不能作为库工作的这些东西之一?[即,更改必须以某种方式贯穿每个现有的 clojure 库,包括 clojure.core?]

  • Scala 的类型概念与 clojure 协议/记录根本不兼容吗?

  • ... ?

4

2 回答 2

12

这是一个有趣的问题。

关于 Scala 有一个惊人的类型系统,关于 Clojure 在元编程和语言扩展方面非常出色(尽管这不仅仅是宏......),你当然是对的。

我能想到的几个原因:

  1. Clojure 是一种动态类型语言,而 Scala 是一种静态类型语言。强大的类型推断在您可以对输入类型假设相对较少的语言中并没有多大用处。
  2. Clojure 已经有一个非常有趣的项目将类型添加为一个库(Typed Clojure),这看起来非常有前途 - 但是它与 Scala 的方法非常不同,因为它从一开始就是为动态语言设计的(我相信更多的是受Typed Racket的启发)。
  3. Clojure 哲学实际上不鼓励某些 OOP 概念(特别是实现继承、可变对象和数据封装)。支持这些东西的类型系统(如 Scala 所做的那样)并不适合 Clojure 惯用语——充其量它们会被忽略,但它们很容易鼓励一种会导致人们以后遇到严重问题的开发风格。
  4. Clojure 已经提供了一些工具,可以解决您通常使用其他语言的类型解决的许多问题——例如,使用多态性协议。
  5. Clojure 社区非常关注简单性(从出色的视频“Simple Made Easy”的意义上说- 尤其参见 39:30 的幻灯片)。虽然 Scala 的类型系统确实令人惊叹,但我认为将其描述为“简单”有点牵强
  6. 放入 Scala 风格的类型系统可能需要完全重写 Clojure 编译器,并使其变得更加复杂。到目前为止,似乎没有人愿意接受这一特定挑战……而且即使有人愿意并且能够做到这一点,也有可能由于上述各种文化/技术原因而拒绝更改。

在没有对 Clojure 本身进行重大更改(我认为这不太可能)的情况下,一个有趣的可能性是在 Clojure 中创建一个 DSL,为特定域提供 Scala 样式的类型推断,并将此 DSL 直接编译为优化的 Java 字节码. 我可以看到这是针对特定问题域的有用方法(例如,使用大矩阵处理大规模数值数据)。

于 2012-08-14T06:29:55.130 回答
5

简单回答您的问题“......为什么 Scala 的类型系统不是 Clojure 中的库?”:

因为类型系统是 scala 编译器的一部分,而不是 scala 库的一部分。scalas 类型系统的全部功能只存在于编译时。JVM 不支持这样的事情,因为类型擦除,也因为它只会减慢执行速度。而且也没有必要。如果你有一个静态类型的语言,你在运行时不需要类型信息,除非你想做一些肮脏的事情。

编辑:

@mikera jvm 肯定能够运行 scala 编译器,我没有说那样的话。我刚才说过,jvm 不支持这样的类型系统。它甚至不支持泛型。在运行时,所有这些类型都消失了。编译器检查程序的正确性并删除所有更高种类的类型/泛型。

例子:

val xs: List[Int] = List(1,2,3,4)
val x1: Int = xs.head

在运行时将如下所示:

val xs: List = List.apply(1,2,3,4)
val x1: Int = xs.head.asInstanceOf[Int]

不过没关系,因为编译器之前检查过了。当您使用反射时,您只会在这里遇到麻烦,因为您可以将任何值放入列表中,并且它会在运行时准确地在值被强制转换为Int.

这也是为什么 scala 类型系统不是 scala 库的一部分,而是内置在编译器中的原因之一。

OP 的问题也是“......为什么 Scala 的类型系统不是 Clojure 中的库?” 而不是“是否可以为 clojure 创建类型系统,例如 scalas?” 我完美地回答了这个问题。

于 2012-08-14T09:07:44.020 回答