On Wednesday, October 19, 2011 10:38:56 AM UTC-4, stuart....@gmail.com 
wrote:
>Integers and longs are going to be painful no matter what because they are 
broken in Java, e.g.

It is incorrect to say that "Integers and longs...are broken in Java."

user=> (.hashCode (Integer. -1))
-1
user=> (.hashCode (Long. -1))
0
user=> (.equals (Integer. -1) (Long. -1))
false

This is consistent with the contract for hashCode. Java would be broken only 
if equals returned true, but the hashCodes were different. If anything 
Clojure was (and in fact still is) broken, since Clojure makes Long and 
Integers in the same range equal, but does not make their hashCodes equal:

user=> (hash (Integer. -1))
-1
user=> (hash (Long. -1))
0
user=> (= (Integer. -1) (Long. -1))
true

Henceforth referred to as "the hashCode problem".

On Thursday, October 20, 2011 9:00:23 AM UTC-4, stuart....@gmail.com wrote:
>Somebody has to work hard: either users of collections, or interop callers. 
The current behavior makes things "just work" for collections, at the cost 
of having to be explicit for some interop scenarios.
>
>There are two reasons to favor collection users over interop users:
>
>   (1) Interop problems are local, and can be resolved by checking the type 
signature at the point of the problem. Collection key problems are global 
and break the composability of collections. It is a *huge* benefit of 
Clojure that collections are sane.

Munging the data as it goes into a collection does not fix the hashCode 
problem.

PersistentArrayMaps don't have the hashCode problem, because they don't 
actually bother with hashCodes:

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

But boxing ints as Long doesn't actually fix the hashCode problem for 
PersistentHashMaps.  Big 'I' Integers still hash differently than big 'L' 
Longs, yet Clojure considers Longs in the Integer range to be equal to 
Integers, and this is the fundamental problem with Clojure's collections. 
E.g.

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

Since Clojure isn't making the hashCodes for Integers and Longs the same, 
the collection experience is still broken.  One could say, "Yes, Paul, but 
it is less broken now, because you will only see this issue if you 
explicitly create a big 'I' Integer."

Then I could say, "Yes, One, that may be true, but in that case presumably I 
have a reason to explicitly ask for a big 'I' Integer, and I should 
understand the implications. Similarly, I probably have a reason for asking 
for a little 'i' int.  Clojure may think it knows best by boxing ints as 
Longs, but I'm pretty sure I know what's best in this particular situation 
in my code."

Then One could say, "But using only longs makes math much faster, and makes 
the collection experience more consistent."

Then I could say, "One, you are complecting two different issues. Making 
Clojure literals always longs is fine, it's great.  Making the Clojure 
compiler generate fast code for little 'l' longs is great. That means that 
you should only run into this collection brokenness if you are explicitly 
asking for and creating big 'I' Integers. However, the collection experience 
not being consistent is a problem with the collection implementation.  
PersistentHashMap should not be using Integer's hashCode method if it is not 
using Integer's equals method."

>   (2) There are a lot more lines of code working with collections than 
doing interop.

I think the issue with interop is that I am explicitly asking for ints 
and/or Integers, and when I'm doing interop I expect that Java semantics be 
preserved, which means that ints get boxed into Integers.  I don't believe 
that boxing ints as Integers should harm any of the primitive math 
enhancements, nor would it harm the concept of Clojure "as a language unto 
itself" having only 64-bit math.  Those are orthogonal issues.


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