Why does Clojure at times use Java classes as their base type?

269 views
Skip to first unread message

Mark Gandolfo

unread,
Feb 2, 2014, 5:50:01 PM2/2/14
to clo...@googlegroups.com
I tried asking this on twitter and wasn't getting my question across in 140 characters so I decided to post here. 
I'm curious as to why Clojure as a language hasn't abstracted/hidden all of Java's classes and created their own in the Clojure. namespace. 

For example

Big Ints are of type and class Clojure.lang.BigInt. 

user=> (type 10000N)
clojure.lang.BigInt
user=> (class 10000N)
clojure.lang.BigInt

Although a Long is a java.lang.Long both in type and class

user=> (class 1)
java.lang.Long
user=> (type 1)
java.lang.Long

Similarly a character is of type java.long.Character

user=> (type \a)
java.lang.Character
user=> (class \a)
java.lang.Character

Again with Java strings

user=> (class "string")
java.lang.String
user=> (type "string")
java.lang.String

Although a Strings have a few functions in the clojure.strings namespace which can be accessed. Why wouldn't clojure.lang.string be the type? And somehow inherit/remap all of the java string functions?
Was this design decision made during the languages conception to clean up the clojure namespaces? Or is there another reason that I'm not seeing?


Aaron France

unread,
Feb 2, 2014, 6:07:27 PM2/2/14
to clo...@googlegroups.com

Hi,


What's the benefit of hiding/abstracting the underlying platform away?
There are reams of documentation about the Java classes and simply
renaming them to say they are Clojure classes would seem to reduce the
discoverability of those docs.

JMTC

Aaron
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Mikera

unread,
Feb 2, 2014, 8:47:41 PM2/2/14
to clo...@googlegroups.com
It would be a bad idea to wrap up everything in custom types:

a) It would add a performance overhead. Better to use the Java types directly - they are very well optimised on the JVM
b) It would make it much harder to use Java libraries and APIs. Java APIs expect the correct Java type, and wouldn't understand clojure.lang.String  for example
c) There's no real advantage to reinventing the wheel. The Java types are already pretty good for what they are designed for, e.g. String is fast and immutable.
d) It would be a lot of extra work. People have better things to do in this community, I think!

The clojure.lang.BigInt is a special case - There was probably some good reason to reimplement java.math.BigInteger (perhaps: performance? getting a consistent hashcode?)

Likewise clojure.lang.Ratio doesn't have a good equivalent in the Java API, so needed to be a new implementation.

Janne Lemmetti

unread,
Feb 3, 2014, 1:19:08 AM2/3/14
to clo...@googlegroups.com
There's a nice explanation on why Clojure has BigInt in Clojure Programming (page 428). Like Mikera wrote, there were two reasons: one was that Java's BigInteger's hashCode is not consistent with Long's hashCode. Secondly Clojure BigInts have been optimized for performance: "while all operations involving BigIntegers must be performed using its (slower) software-based implementations, Clojure optimizes math involving BigInts to use primitive (much faster) operations when possible, as long as the values involved are withing the range of primitive 64-bit longs."

Adrian Mowat

unread,
Feb 3, 2014, 3:04:27 AM2/3/14
to clo...@googlegroups.com
In a broader sense, it's because Clojure was designed to embrace the underlying runtime. As well as eliminating problems with leaky abstractions (as others have pointed out), it also encourages post to other runtimes like the CLR and JavaScript (clojurescript)

Does anyone have a link to a Rich Hickey video or article where he covers this off? I know I've seen a few but I haven't stored the links

Cheers

Adrian

Brian Craft

unread,
Feb 4, 2014, 2:59:00 PM2/4/14
to clo...@googlegroups.com


On Sunday, February 2, 2014 3:07:27 PM UTC-8, Aaron France wrote:
What's the benefit of hiding/abstracting the underlying platform away?


The obvious answer to this is it limits exposure to the complexity of the underlying platform, and provides a stable platform. That's usually why people abstract platforms.

The trade-off of embracing the platform is that the complexity of using clojure is not just the complexity of clojure. It is the complexity of the jvm plus the complexity of java plus the complexity of clojure plus the complexity of the interface between clojure and java, which is intricate. Thus, you need to know that in java 6 you have to make defensive copies of substrings, but on java 7 you don't; that on some jvm you will have abstract path manipulation, on others you won't; that (map #(+ 1 %) (float-array [1 2 3])) will run but (map #(+ 1 %) (byte-array [1 2 3])) will throw an error, and so-on, in unending detail.

Probably the size of this looks different if you've already internalized the complexity of the platform from previous experience.
Reply all
Reply to author
Forward
0 new messages