Oop Clojure是面向对象的吗?(seqs中的多态性)

Oop Clojure是面向对象的吗?(seqs中的多态性),oop,jvm,clojure,polymorphism,sequences,Oop,Jvm,Clojure,Polymorphism,Sequences,Clojure是一个功能性的lisp,据说根本不是面向对象的,即使它运行在JVM上,JVM是为面向对象语言设计的虚拟机。Clojure通过将列表和向量抽象到一个名为seq的接口,为迭代列表和向量提供了相同的接口。这甚至是使用一个名为ISeq的Java接口在内部实现的。这不是一个面向对象抽象的例子吗?Clojure不是面向对象的,这怎么能说呢 我想这是这个问题的必然结果——什么时候多态性可以被视为不同于面向对象?惯用的Clojure倾向于定义在非常小的核心数据结构集上运行的独立函数;这种方法和数据

Clojure是一个功能性的lisp,据说根本不是面向对象的,即使它运行在JVM上,JVM是为面向对象语言设计的虚拟机。Clojure通过将列表和向量抽象到一个名为seq的接口,为迭代列表和向量提供了相同的接口。这甚至是使用一个名为ISeq的Java接口在内部实现的。这不是一个面向对象抽象的例子吗?Clojure不是面向对象的,这怎么能说呢


我想这是这个问题的必然结果——什么时候多态性可以被视为不同于面向对象?

惯用的Clojure倾向于定义在非常小的核心数据结构集上运行的独立函数;这种方法和数据的分离是一种强烈反对面向对象和支持函数式风格的声明。里奇·希基(Clojure的创造者)反复强调了这一点的重要性;例如这里:

在Clojure中,对核心数据结构的依赖甚至比在其他函数式语言中更为重要,因为只有在使用Clojure的持久数据结构时,才能从Clojure的STM中获得全部好处

我想这是这个问题的一个推论——多态性何时可以被认为与面向对象不同

我使用Clojure的multimethods(即多态工具)根据文件名的扩展名分派到不同的实现中——完全不是面向对象的,而是多态的

我想这是这个问题的一个推论——多态性何时可以被认为与面向对象不同

多态性与面向对象绝对没有关系。这仅仅意味着同一个操作可以根据其操作数的类型而表现出不同的行为

像ML或Haskell这样的函数式语言具有多态性已经有30多年了,对PL历史有更好了解的人可能会指出1962年以前(即OO之前)的一些例子


Christopher Strachey在1967年描述了参数多态性和特殊多态性之间的区别,因此多态性当时肯定已经存在。由于多态性只在Simula-67的OO中引入,我猜想多态性在引入OO之前一定存在。

Clojures多态性是Java的自然扩展。在java中,方法根据类进行调度。在clojure中,这是扩展的,允许您根据任何需要分派呼叫。它仍然很容易在课堂上发布,事实上大部分时间都是这样做的。如果您需要其他东西,那么您可以编写自己的调度器。内置函数
derivate
,根据需要创建层次结构,然后在
isa
上调度


更多好处在于:

请记住,像ISeq这样的东西都是Java

在Clojure中,seq抽象实际上只是一种“东西”,可以提供给first、rest和nth函数(注意,不是先调用seq,而是先用seq参数调用)。Clojure语言的核心函数都对集合、seq或基元类型进行操作。在公开的接口中没有与方法绑定的数据。因此Clojure的实现是在Java中,与JVM的所有互操作都将涉及类/对象,但Clojure语言本身并不涉及

Clojure不鼓励将方法与数据结构捆绑在一起

说了这么多。。。现实情况是,函数在使用什么参数时确实存在限制。first rest和nth将只处理可以是seq的内容。从这个角度来看,数据结构是否与方法捆绑在一起并没有太大区别——您仍然需要正确地匹配它们。巨大的胜利来自灵活性。函数可以编写为接受任何参数,然后在不定义类等的情况下与高阶函数组合:

(def farms [{:name "Swansea", :value 100}
            {:name "Broadmarsh", :value 200, :produce [:corn :wheat :rye]}
            {:name "Snug", :value 50, :animals [:goats :pigs]}])
(reduce + (map :value farms))
-> 350
(reduce + (map :value (filter :animals farms)))
-> 50

“让100个函数在一个数据结构上运行比让10个函数在10个数据结构上运行要好。”——Alan J.PerlisAhhh,我在这里看到了这句话:链接到“据说根本不面向对象”的源代码将有助于弄清楚这一论点是技术还是政治。。。讨论OOP以及Clojure为什么要避免它。这是一篇有趣的文章,讨论Clojure实际上如何允许使用所有主要的OO原则。然而,我发现很难将它们结合起来。例如,使用闭包封装可以通过继承排除扩展。一般的方法似乎是放弃封装而支持可扩展性。实现某个接口的对象和有效地将一组函数名与类型关联的Clojure协议之间只有一点区别:后者不附加到类/原型。机制各不相同,但概念几乎相同。