acmp again !
forax at univ-mlv.fr
forax at univ-mlv.fr
Wed Feb 20 21:55:14 UTC 2019
----- Mail original -----
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>, "valhalla-spec-experts" <valhalla-spec-experts at 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
>>
>>
More information about the valhalla-spec-observers
mailing list