在Clojure 1.2中观看了Protocols,并且对Clojure知之甚少之后,我对Clojure Protocols有一些疑问:
-
他们是否打算在Scala中执行与Structural Types相同的操作?协议对结构类型(性能,灵活性,代码清晰度等)有什么好处?它们是通过反思实现的吗?
-
与Scala的互操作性问题:可以使用协议代替Scala中的结构类型吗?它们可以在Scala中扩展(如果'extension'术语可以应用于协议)吗?
在Clojure 1.2中观看了Protocols,并且对Clojure知之甚少之后,我对Clojure Protocols有一些疑问:
他们是否打算在Scala中执行与Structural Types相同的操作?协议对结构类型(性能,灵活性,代码清晰度等)有什么好处?它们是通过反思实现的吗?
与Scala的互操作性问题:可以使用协议代替Scala中的结构类型吗?它们可以在Scala中扩展(如果'extension'术语可以应用于协议)吗?
4 回答
完全不相关 .
Scala是一种静态类型语言 . Clojure是一种动态类型语言 . 这种差异从根本上影响了它们 .
结构类型是静态类型,周期 . 它们只是让编译器静态证明一个对象具有特定结构的一种方式(我说在这里证明,但是铸造可能会像往常一样导致虚假证明) .
Clojure中的协议是一种创建动态调度的方法,它比反射或在 Map 中查找更快 . 从语义上讲,它们并没有真正扩展Clojure的功能,但在操作上它们比以前使用的机制要快得多 .
与Java接口一样,Scala特性更接近协议,但同样存在静态与动态问题 . Scala特征必须在编译时与类关联,类似于Java接口 . 在事实之后,甚至可以由第三方将Clojure协议添加到数据类型中 .
像Java和Scala这样的Clojure协议可以通过包装器/代理模式或动态代理(http://download.oracle.com/javase/1.4.2/docs/guide/reflection/proxy.html)等机制实现 . 但是这些将比Clojure协议更加笨拙,并且获得对象身份也很棘手 .
Clojure中协议的目的是以有效的方式解决表达式问题 .
[见:Simple explanation of clojure protocols.]
Scala对表达式问题的解决方案是隐含的 . 因此,从语义上讲,这是与Scala中Clojure协议最接近的等价物 . (在Haskell中,它将是Typeclasses或类型系列 . )
据我所知,封闭协议更接近Scala Traits,而不是结构类型(因此,不能用它来代替它们,回答我的第二个问题):
其他答案更好地说明了问题的其他部分,但是:
否 - 协议被编译为JVM接口 . 实现协议(reify,defrecord等)的东西被编译为实现协议接口的JVM类,因此对协议函数的调用与标准JVM方法调用相同 .
这实际上是协议的激励因素之一 - 由于速度原因,很多Clojure的内部数据结构都是用Java编写的,因为在纯Clojure中无法进行全速多态分派 . 协议提供了这一点 . Clojure的源代码中仍然有很多Java,但现在可以在Clojure中重写所有内容而不会损失性能 .