On Sat, Oct 22, 2011 at 5:42 PM, Luc Prefontaine <
lprefonta...@softaddicts.ca> wrote:

> What's missing from your shortened example ?
>

I think what you want is the example I posted originally:

user=> (get {(Long. -1) :here} (Integer. -1))
:here

That works fine because you are actually creating an PersistentArrayMap,
which does not care about hash codes. However, when you use a
PersistentHashMap you see were things break down because the hashing
function and the equality function that PersistentHashMap is using are not
congruent (i.e. they break the hashing contract):

user=> (get (clojure.lang.PersistentHashMap/create {(Long. -1) :here})
(Integer. -1))
nil
user=> (get (clojure.lang.PersistentHashMap/create {(Long. 0) :here})
(Integer. 0))
:here

This happens because PersistentHashMap does not use .equals to compare keys,
however it does use .hashCode to hash the keys. So it's fine to not use
.equals and define Clojurey semantics for integer comparisons, but if we're
not using .equals, then we should not be using .hashCode, and instead
redefine .hashCode with Clojurey semantics as well. The contract that is
being broken is the contract for hashing, not equality.

This problem has nothing to do with Java interop. I has nothing to do with
the Java language or the JVM. It has nothing to do with whether ints are
boxed as Integers or Longs. What is happening is PersistentHashMap is
supposed to be an implementation of an abstract Computer Science data
structure called a hash table, and for a hash table to work correctly the
following must be true: if two keys are equal, then their computed hash
values for those keys should be equal.

The reason we wandered into this is because one of the objections that has
been raised against boxing ints as Integers is that doing so would break
Clojure's collections. What I have been trying (unsuccessfully I gather) to
communicate is that PersistentHashMap is broken in and of itself, and boxing
ints as Longs only hides the issue. Boxing ints as Longs makes it less
likely that you would actually be using an Integer as a key, because you
have to explicitly ask for an Integer. However, if you explicitly ask for an
Integer you still get the broken behavior, because PersistentHashMap needs
to be fixed.

Bottom line: changing Clojure to box ints as Integers would not break
Clojure's collection, but Clojure's collections need to be fixed to use a
hashing function that is congruent with their equality function.


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