Is Clojure object-oriented at its heart? (Polymorphism in seqs)
Asked Answered
B

4

32

Clojure is a functional lisp, reportedly not at all object-oriented, even though it runs on the JVM, a VM designed for an object oriented language. Clojure provides identical interfaces for iterating over lists and vectors by abstracting them to an interface called seq. This is even implemented internally using a Java interface called ISeq. Is this not an example of object-oriented abstraction? How can it be claimed that Clojure is not object-oriented?

I guess a corollary to this question--- when can polymorphism be considered distinct from object orientation?

Bradytelic answered 10/10, 2009 at 15:20 Comment(4)
A link to a source for "reportedly not at all object-oriented" would be helpful in figuring out whether the argument is technical vs political...Immunotherapy
clojure.org/rationale talks about OOP and why Clojure avoids it.Tarpley
blog.thinkrelevance.com/2009/8/12/… is an interesting article which discusses how Clojure actually allows the use of all the major OO principals. However I find that it is difficult to combine them. For instance using closure encapsulation excludes extension by inheritance. The general approach seems to be to forgo encapsulation in favour of extensibility.Sitka
There's only a small difference between an object that implements some interface and a Clojure protocol which effectively relates a set of function names to a type: the latter are not attached to a class/prototype. The mechanism varies but the concept is nearly the same.Unshackle
M
31

Idiomatic Clojure favors defining independent functions that operate on a very small set of core data structures; this unbundling of methods and data is a strong statement against object orientation and in favour of a functional style. Rich Hickey (creator of Clojure) has repeatedly stated the importance of this; for example here: "Clojure eschews the traditional object-oriented approach of creating a new data type for each new situation, instead preferring to build a large library of functions on a small set of types.".

The reliance on the core data structures is even more important in Clojure than in other functional languages because you'll only reap the full benefits from Clojure's STM when you are using Clojure's persistent data structures.

I guess a corollary to this question--- when can polymorphism be considered distinct from object orientation?

I'm using Clojure's multimethods (i.e. polymorphic facilities) to dispatch to different implementations based on a filename's extension - not at all object oriented, but polymorphic.

Metapsychology answered 10/10, 2009 at 16:59 Comment(2)
"It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures." -- Alan J. PerlisStamford
Ahhh, I see that quote here: clojure.org/about/rationaleMeasurable
S
19

I guess a corollary to this question--- when can polymorphism be considered distinct from object orientation?

Polymorphism has absolutely no relation to object-orientation. It simply means that the same operation can behave differently depending on the type(s) of its operands.

Functional languages like ML or Haskell have had polymorphism for more than 30 years, and someone with a better knowledge of PL history can probably point out some examples pre-1962 (i.e. pre-OO).

Christopher Strachey described the distinction between parametric polymorphism and ad-hoc polymorphism in 1967, so polymorphism must have already existed then. Since polymorphism was only introduced in OO in Simula-67, my guess is that polymorphism must have existed before it was introduced in OO.

Sadye answered 10/10, 2009 at 20:59 Comment(0)
S
7

Keep in mind that things like ISeq are Java.

In Clojure the seq abstraction is really just 'something' that you can supply to the first, rest and nth functions (note you don't call first on a seq, you call first with a seq argument). The Clojure language core functions all operate on collections, seqs, or primitive types. There is no data bundled with methods in the exposed interfaces. So the implementation of Clojure is in Java and all interop with JVM is going to involve Classes/Objects, but Clojure the language itself does not.

Bundling methods with data structures is what Clojure discourages.

Having said all that... the reality is that functions do have limitations on what arguments they will work with. first rest and nth will only work on something that can be a seq. From this perspective there isn't much difference whether the data structures are bundled with methods or not - you still have to match them up correctly. The big wins come from the flexibility. Functions can be written to take any arguments and then composed with higher order functions without defining classes etc:

(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
Sitka answered 13/10, 2009 at 0:27 Comment(0)
C
4

Clojures Polymorphism is a natrual extension of Java. In java methods are dispatched according to class. In clojure this is extended to allow you to dispatch calls based on anything you want. Its still really easy to dispatch on class, infact the majority of the time thats how its done. If you want something else then you can write your own dispatcher. The built in function derive to create hierarchy based on anything you want and then dispatch on isa.

more goodness at: http://clojure.org/multimethods

Contumacious answered 12/10, 2009 at 20:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.