
Clojure vs Java, pt. 1 - DanielRibeiro
http://tech.puredanger.com/2011/04/18/clojure-vs-java/
======
jcromartie
Clojure Protocols are really a great way to extend types. I think it's a nice
fit with both the functional and dynamic nature of Clojure, and it is
carefully designed to allow "open" types while completely avoiding monkey-
patching. It just seems like the perfect balance, even if it's hard to
understand at first. I think it might even lead to "better" OOP in Clojure
than in Java.

I would love to have this in Ruby, so that classes could be extended but not
in surprising ways.

~~~
abp
_Clojure Protocols are really a great way to extend types. I think it's a nice
fit with both the functional and dynamic nature of Clojure, and it is
carefully designed to allow "open" types while completely avoiding monkey-
patching. It just seems like the perfect balance, even if it's hard to
understand at first. I think it might even lead to "better" OOP in Clojure
than in Java._

Exactly. Funny thing. Better OOP in a functional language than in a OOP-
language.

But i don't think it's hard to understand. I've seen a lot of good
explanations in presentations and articles. Also the concept is really easy.

------
cygwin98
I keep hearing that current JVM implementation prevents tail call
optimizations [1]. Is it still the case nowadays? Kind of curious on that
since there seem to be lots of folks on HN use Clojure in production systems.

[1] [http://stackoverflow.com/questions/105834/does-the-jvm-
preve...](http://stackoverflow.com/questions/105834/does-the-jvm-prevent-tail-
call-optimizations)

~~~
sbochins
You use recur in clojure for tail optimization. Don't think the jvm has tail
optimization support currently.

~~~
cygwin98
Is recur kind of workaround? Any performance penalty?

Please bear with me as I'm not familiar with Lisp family languages. I'm
interested in ML languages. There is a project to port OCaml to JVM, but I
don't see any sign of progress, so I thought it may be something on JVM to
hold them back.

~~~
jcromartie
I actually like the 'recur' better than implicit tail-call optimization. It
does what it says on the tin. If you don't use recur, you get unoptimized
recursion, and more importantly: where you _can't_ make a function tail-
recursive, you _can't_ use 'recur', because it is a compiler error.

------
pdhborges
Is it possible to implement the same protocol for a particular type in
multiple ways?

~~~
puredanger
No, as a reimplementation will effectively replace the prior implementation.
But I think you should ask whether that question makes sense.

If you're dispatching based on something other than just type (some
information that would allow you to choose one of multiple implementations)
than you should probably either a) put that logic inside the protocol
implementation for that type or b) use multimethods which let you use an
arbitrary dispatch function that can take both type and other information into
account. If you choose a), you could actually layer another protocol or other
dispatch mechanism under the initial call if you need to.

~~~
pdhborges
Imagine I have a JSONfiable protocol and I have a generic function to traverse
a structure that uses the protocol to make a JSON document. It would be nice
if the caller had a way to change the format.

~~~
puredanger
You can _change_ the implementation of the protocol, but then it's changed (in
that it replaces the prior version). When you see something of type X, the
protocol says what to do when you encounter a function on X. If you want more
than one kind of thing to happen, then you shouldn't use a protocol.

For instance, it would be perfectly feasible to use a multimethod that
dispatches on both type and output format. Or a protocol that dispatches on
type, then dispatches a different function on format.

