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