Inheritance 为什么Clojure核心库使用具体的派生?

Inheritance 为什么Clojure核心库使用具体的派生?,inheritance,clojure,Inheritance,Clojure,在报告中,声明 具体推导是不好的 不能从具体类派生数据类型,只能从接口派生数据类型 但是,有些使用具体的派生(还有其他示例,但这些是超类是clojure.lang的一部分的唯一情况): ARef扩展AReference AgentextendsARef Atom扩展ARef 名称空间扩展引用 Ref扩展ARef Var扩展ARef 此外,还有许多抽象类。然而,在Clojure中无法创建抽象类的等价物,在我看来,抽象类的扩展似乎与常规的具体派生具有相同的缺点 为什么在这里使用具体的推导

在报告中,声明

  • 具体推导是不好的
    • 不能从具体类派生数据类型,只能从接口派生数据类型
但是,有些使用具体的派生(还有其他示例,但这些是超类是
clojure.lang
的一部分的唯一情况):

  • ARef
    扩展
    AReference
  • Agent
    extends
    ARef
  • Atom
    扩展
    ARef
  • 名称空间
    扩展
    引用
  • Ref
    扩展
    ARef
  • Var
    扩展
    ARef
此外,还有许多抽象类。然而,在Clojure中无法创建抽象类的等价物,在我看来,抽象类的扩展似乎与常规的具体派生具有相同的缺点


为什么在这里使用具体的推导?

当谈到哲学的东西时,我觉得自己不够权威,但这是我的两分钱

您引用的文本出现在此处的原因是警告滥用
defrecord
deftype
。Clojure不鼓励将记录/类型公开为API。相反,应该尽可能公开接口。毕竟,OO语言公开类,FP语言公开函数/方法/接口


另一方面,您提到clojure的实现本身使用抽象类并继承它们。我宁愿把这些看成是“有些人必须做的肮脏工作”。JVM的设计使得它在OO世界中对原语的效率最高。OO世界虚拟机和FP世界语言之间的鸿沟必须有人来填补。

这是有道理的,但我需要看到更多的人支持你的论点,相信这里使用抽象类只是一种“必要的罪恶”,没有JVM的性能特征,将不如使用纯接口。Rich Hickey在这里似乎有一个非常深思熟虑的原因。同一页还警告不可更改性和封装,但是
clojure.lang
中的类包含大量可更改的私有字段。不要混淆语言的内部实现细节和它的预期用途。@Alex我关心的唯一原因是扩展
clojure.lang
中的接口是在clojure中实现与
clojure.core
中的函数兼容的新数据结构的唯一方法。如果包中的所有内容都只是实现细节,那么这种扩展就不需要了解它的工作原理。