acmp again !

forax at forax at
Thu Feb 21 09:04:41 UTC 2019

----- Mail original -----
> De: "John Rose" <john.r.rose at>
> À: "Brian Goetz" <brian.goetz at>
> Cc: "Remi Forax" <forax at>, "valhalla-spec-experts" <valhalla-spec-experts at>
> Envoyé: Jeudi 21 Février 2019 04:25:27
> Objet: Re: acmp again !

> On Feb 20, 2019, at 5:48 PM, Brian Goetz <brian.goetz at> wrote:
>>> It doesn't match my experience, currently people have no expectation of what ==
>>> means on a value type, if you explain that a value type has no identity, that
>>> == doesn't work on a value type, most people are ok with that.
>> I think this is fantasy.
>> Value types are OBJECTS.  People think they know what == means on an Object, and
>> for most users, the word "identity" does not come to mind.  Further, we've told
>> people that "values have only state, no identity -- if two values have the same
>> state, they are the same." For such values not to be == will be astonishing.
> I think I have to agree with Brian here.  The key idea here is
> "will be astonishing", emphasis on "will".  I can believe that
> at first introduction to non-reflective equality people might
> shrug, but actually living with it in the long term is surely
> a different matter.  If my car makes a funny noise in the
> used car lot, I might shrug it off and buy the car, but if it
> makes it every time I drive to work I will start to pay
> attention, with some buyer's regret.  I am afraid we will
> regret non-reflexive op==.  Imagine a world where
> many numbers act like NaN (n!=n).  That's kind of what
> we would be signing up for.

I like the car metaphor, the problem here is that there are only two types of cars available, one that reliably does a funny noise when you turn the windscreen wipers on and the other that drive you out of the road when you turn on the wipers on but only on particular roads (your O(N) case below). Again pick your poison.

NaN is interesting because it creates another corner case where the == will be surprising if it's implemented has a component wise comparison,
  value record Box(double value);

  var box = new Box(Double.NaN);
  box == box   // false

so both semantics are not reflective.

>> Consider:
>>      value class UnsignedInt {
>>         public static UnsignedInt ZERO = ...
>>         private int i;
>>         public static add(UnsignedInt a, UnsignedInt b) { ... }
>>     }
>>     UnsignedInt x = ...
>>     if (x != UnsignedInt.ZERO) { ... }
>> People will never, ever, ever get used to the idea that test is always false.
>> Its a fantasy to think otherwise.  And the WHOLE POINT of L-World is to allow
>> people to not sweat the small details between values and refs.  This is asking
>> them to be acutely aware all the time.
> To put it another way, in terms of buyer's remorse:  If people
> shrug off op== anomalies on first glance, it can only get worse
> in the future, as they hit bugs in their code coming from those
> anomalies.

acmp on value types will be source of anomalies whatever semantics we are choosing, because in both case, it's not the reference semantics, but == on a value type doesn't have to be mapped to acmp.

> This last example reminds me of another mitigating
> circumstance with structural acmp:  Just as many comparisons
> of references today are against null, and that's cheap
> no matter what odd stuff is going on under the JVM,
> many value comparisons will be against initial or
> default values.  In those cases, one of the two compared
> values will have little or no deep structure, so the
> comparison will be O(1).  The O(N) comparisons will
> show up only when pairs of deeply structured values
> are being compared.  If those are places where
> Object.equals (part of LIFE) is also in play, then
> we can neglect the O(N) comparison as a constant
> multiplier on Object.equals, or even merge it into
> Object.equals as I suggested previously.

deeply recursive values will sometimes drove you out of the road, because not all acmps are part of a LIFE pattern, so you have no guarantee that there is no acmp somewhere that will trigger a recursive structural comparison at a location your program can not shallow it. 


More information about the valhalla-spec-observers mailing list