On Sat, Oct 22, 2011 at 9:48 AM, Chas Emerick <cemer...@snowtide.com> wrote:

> If Clojure's primary objective were Java interop, I might agree with you.
>  However, it's not, and it's bizarre to see someone argue that this is not
> broken:
>
> user=> (.equals (Integer. -1) (Long. -1))
> false
>
> Sure, not broken according to the Java object model and its equality
> semantics, but damn well broken if your standard is something other than
> what was canonized in java.lang.Object 20 years ago.  1 == 1 all the time —
> or, it should — regardless of the containers such integers incidentally find
> themselves within.
>

>From the beginning Clojure's story has been, "why reinvent the wheel when
there's this great JVM with a million man-months of engineering," and I do
believe interop has been a huge objective. There are lots of existing
libraries that can be used, and the whole "Clojure integers are
java.lang.Integers, and Clojure Strings are java.lang.Strings" always seemed
to me to be about interop and being a good, integrated citizen on the JVM.

Of course I was not saying that 1 should not equal 1. I was saying that to
be on the JVM you should adhere to the hashCode contract. And it's not the
java.lang.Object equality semantics that are broken. The hashCode contract
is a mathematical contract that you must follow if you want to implement a
hash table in any language. Sure, Integer and Long seem to be weird in that
they are not equal to each other when they are in the same range, but that's
a problem with Integer and Long semantics, not java.lang.Object semantics.
And you can't fix that problem by essentially rewriting/overriding the
equals method for Integer and Long, and not also rewriting/overriding the
hashCode method for those same classes. If you don't also override hashCode,
then you get broken behavior as I demonstrated.

Thus, Clojure's notion of equivalence, which leads to pleasantly consistent
> behaviour, e.g. (== (Integer. 1) 1 1N). Which, of course, doesn't preclude
> one using .equals if you truly want Java math semantics instead of = or ==
> (neither of which have ever been advertised as adhering to the
> hashcode/.equals contract, at least since Clojure 1.0 IIRC).
>

Clojure PersistentHashMaps are java.util.Maps, and to whatever extend
Clojure defines new types on the JVM and implements an equals method for
those types, it should also implement a hashCode method that adheres to the
contract.


> If there are some common rough spots in the interop for certain use cases,
> perhaps those can be smoothed out with a library, maybe contributed by
> someone that acutely feels that pain.
>

I don't intend to muddle the discussion, but only to point out that there
are two separate issues:

1) the way collections behave when you use Longs that are in the Integer
range. This is a problem with the implementation of PersistentHashMap, and
unrelated to boxing ints as Longs. Boxing ints as Longs only hides the
underlying issue that PersistentHashMap should not be using the default
implementation of hashCode, but it's own implementation of equals.

2) ints being boxed as Longs. When you looks a Chris Perkin's post it
certainly seems broken that ints are the *only* primitive that is not boxed
into its java.lang equivalent. Also, AFAICT boxing ints as Integers would
have no effect on the faster numeric maths.


Paul

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to