The contract in Clojure is clear, they are only long integer values except if 
you cast
them accordingly for Java interop purposes. Anything else is a long so there 
are no
contract breaches.

It's not a platform issue, it's a Java issue. Equality is implemented by Java 
for objects.
It has nothing to do with Clojure which uses primitive types like long for 
numeric representation.

user=> (= 1 (int 1))
true
user=> (.equals 1 (int 1))
true
user=> (.equals (long 1) (int 1))
true
user=> (.equals (Long.  "1") (Integer. "1"))
false

Where's the contract breach here ? Don't mention breaking the Java contract in 
the two first
examples. You are in Clojure's playground here, arithmetic primitive types (not 
classes) are getting promoted
according to Clojure's rules.

The third one starts in Clojure's playground were the same promotion occurs and 
both values get boxed to Long for interop purposes (.equals on java objects) 
and the result
satisfies the Java contract.

The fourth one is not in Clojure's playground, it's pure Java and it also 
respects the Java contract
between comparing objects, not primitive jvm types.

Were's the problem ? The Java contract is respected as soon as you dive in Java.

It's the same here:

user=> (class (key (first { (int 1) :a})))
java.lang.Long

You create a Clojure map with a numeric key, the key gets promoted from 
primitive int to primitive long.
As soon as you jump in interop, you get a Long object key. Obviously, the map 
comes from the Clojure's
playground but java cannot cope with primitive types in keys, you need an 
object so Clojure boxes
accordingly to a Long object.

user=> (class (key (first { (Integer. 1) :a})))
java.lang.Integer
user=> 

Here you decide to create a key type from the Java world (a Java object) and it 
gets preserved so you
ship the map to a Java call for interop.

Were are the contract breaches ? Aside from the fact that Clojure implements a 
contract of its own
and respects it, there are no breaches.

You have been mixing Java objects with primitive types defined by the JVM since 
you entered this
discussion. It's two different things.


On Sat, 22 Oct 2011 16:06:04 -0400
Paul Stadig <p...@stadig.name> wrote:

> Luc,
> 
> On Sat, Oct 22, 2011 at 3:40 PM, Luc Prefontaine <
> lprefonta...@softaddicts.ca> wrote:
> 
> > All the contracts you mention are language centric, each of them
> > defined their contract according
> > to their own needs. Clojure should have the right to do so.
> >
> 
> The contract is required for implementing any kind of hash map
> anywhere. This is not Java or the JVM influencing Clojure to do
> something it wouldn't have otherwise. The references were examples to
> show that widely varied languages/platforms agree: if you want to
> implement a hash map in any language on any platform, then when two
> objects are equal their hashCodes should be equal.
> 
> I'm fine with changing the Java semantics with respect to Integer and
> Long equality, BUT if we're going to change equality, then the
> hashing function has to be congruent with that equality function. If
> equals and hashCode are not congruent, on any platform, in any
> language, anywhere, then you do not have a hash map, you have a
> broken hash map. You can see the brokenness in the example code I
> posted.
> 
> 
> > Clojure prefers to avoid having different rules than Java regarding
> > number handling ? Be so, it's legitimate.
> >
> 
> I'm not arguing against that. I'm saying make the equality different,
> BUT you also have to make the hashCode function congruent.
> 
> If people like you were free to take these decisions we would end up
> with
> > three different languages, one on the
> > jvm, one on CLR and one on JS. Nonsense. Having to deal with three
> > different interops and trying to
> > unify them a bit is enough work by itself.
> >
> > Interop stuff is low level and should remain there. If a single
> > interop implementation starts to influence
> > the Clojure language and result in such short term and narrow scope
> > decisions, we will all have a problem
> > in the future.
> >
> 
> I mean, again, I don't understand why you're saying this. I agree
> interop needs to exist and to be at a low level. The question is,
> given that some form of interop must exist, how should it work?
> Right. The discussion that we're having here is about how Java
> interop should work. I don't think it makes sense to come in and say,
> that we can't let Java and the JVM influence how we interop with Java
> and the JVM. Perhaps you are misunderstanding me, or I you.
> 
> I'm saying given that there must be some form of interop, it does not
> make sense to box ints as Longs. And the decision to box them as
> Integers instead should not have any effect on the semantics of
> anything. Two objections have been raised against boxing ints as
> Integers so far: 1) it breaks Clojure's collections, and 2) it would
> have bad effects on the new faster primitive maths.
> 
> I'm saying: 1) Clojure's PersistentHashMap is broken because it is
> using incongruent equals and hashCode methods, auto-promoting ints to
> Longs only hides this, and if you explicitly create an Integer (or
> get one from Java) PersistentHashMap will still behave badly.
> Promoting ints to Longs only masks the issue.
> 
> 2) autoboxing ints to Integers would not have any bad effects on the
> new faster primitive maths.
> 
> And as a third point, ints being boxed to Longs stands out as
> inconsistent with the way all the other primitive integer types are
> handled.
> 
> 
> Paul
> 



-- 
Luc P.

================
The rabid Muppet

-- 
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