----- Mail original ----- > De: "Brian Goetz" <brian.go...@oracle.com> > À: "Remi Forax" <fo...@univ-mlv.fr>, "valhalla-spec-experts" > <valhalla-spec-experts@openjdk.java.net> > Envoyé: Mercredi 20 Février 2019 21:52:01 > Objet: Re: acmp again !
> Yes, it's a tempting direction. John and I both walked that road, in > the hope that there was a reasonable place to cut off the regress. (And > we both walked back disappointed.) > > One problem is that with erased generics, all Ts become Object: > > /* erased */ value class Box<T> { > T t; > } > > translates to > > value class Box { > Object t; > } > > So no two boxes would be == to each other -- in fact, a given Box would > not be == to itself. I think users would find > > Optional<Point> o = Optional.of(p); > o == o // false > > to be surprising! Similarly, classes like > > value record Twople<T,U>(T t, U u); > > Twople<String, String> x = new Twople("a", "b"), > y = x; > x == x // false > x == y // false > > > Whereas the non-generic version: > > value record TwoStrings(String a, String b); > > TwoStrings x = new TwoStrings("a", "b"), > y = x; > x == x // true > x == y // true > > So I think what this does is just move the surprise to where you don't > trip over it 100% of the time, but you still trip often enough that you > curse it. I'm still not sure allowing == when the compiler knows that the operands are value types is a good idea, whatever the semantics of acmp is. All your examples works BTW if they are declared as reified generics var x = new Twople("a", "b"); x == x // true, will compare the reference "a" and "b" respectively var x = new Twople(2, 3); x == x // true, will compare 2 and 3 respectively I think we can agree that no solution will be perfect, you have to pick your poison. And yes, always returning false is perhaps the lesser evil after all. Rémi > > > > On 2/20/2019 3:33 PM, Remi Forax wrote: >> I still think we have not finished exploring how to implement acmp for value >> types. >> >> We currently have two semantics for value types: >> - always return false, >> - recursively compare each components >> >> Support of acmp like the support of synchronized or System.identityHashcode >> is >> not a part of the original model where we can just say, it should work like >> an >> int because it's a consequence of lworld, making value types subtypes of >> Object, not something inherent to the concept of value types. or said >> differently, if it should work like an int, a == on value types at Java level >> should be converted to a vcmp (like there is an icmp_*) which is not an >> answer >> to how acmp is supposed to work. >> >> The issue with the first semantics is that it will be very surprising and >> will >> not be compatible with all the existing codes that only use == instead of a >> == >> followed by a call to equals(). >> The issue with the second semantics is that it's an unbounded computation, >> shaking the Java performance model everybody has in mind by moving == from >> one >> of the fastest operation to a potentially very slow operation. >> >> I wonder if there is not a intermediary semantics, return false if one field >> is >> an Object or an interface or do a component wise comparison otherwise ? >> >> For value types like Point, Complex, == is the component wise comparison, >> for a >> value type that works like Optional, == return false. >> >> It seems not that bad but it means that doing an == on a wildcard of a >> reified >> generics like Atomic<T> depends on the class of T at runtime ? >> >> Rémi >> >>