我听说有人声称:
Scala 的类型系统令人惊叹(存在类型、变体、协变)
由于宏的强大功能,Clojure 中的一切都是库:(模式匹配、逻辑编程、非确定性……)
问题:
如果两个断言都是真的,为什么 Scala 的类型系统不是 Clojure 中的库?是不是因为:
类型是不能作为库工作的这些东西之一?[即,更改必须以某种方式贯穿每个现有的 clojure 库,包括 clojure.core?]
Scala 的类型概念与 clojure 协议/记录根本不兼容吗?
... ?
这是一个有趣的问题。
关于 Scala 有一个惊人的类型系统,关于 Clojure 在元编程和语言扩展方面非常出色(尽管这不仅仅是宏......),你当然是对的。
我能想到的几个原因:
在没有对 Clojure 本身进行重大更改(我认为这不太可能)的情况下,一个有趣的可能性是在 Clojure 中创建一个 DSL,为特定域提供 Scala 样式的类型推断,并将此 DSL 直接编译为优化的 Java 字节码. 我可以看到这是针对特定问题域的有用方法(例如,使用大矩阵处理大规模数值数据)。
简单回答您的问题“......为什么 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?” 我完美地回答了这个问题。