Draft JEP on Primitive types in patterns, instanceof, and switch
Brian Goetz
brian.goetz at oracle.com
Thu Jan 26 14:36:22 UTC 2023
Everything about floating point is difficult and fiddly and resists a
one-size-fits-all treatment. Joe recently did some work to characterize
the various ways floats can be compared -- representational equivalence,
bitwise equivalence, and the traditional `==`, and put these in the spec
of Float/Double, so we would have a vocabulary to discuss them.
The main differences between these treatments are the treatment of NaN
and signed zeroes. (And for $REASONS, there are multiple NaN bit
patterns.)
Representational equality means "same number", where all NaN values are
the same. Float::equals uses representational equality.
Bitwise equality means "same bit pattern".
The `==` operator says that 0 == -0 and that NaN is equal to nothing,
not even itself.
For comparing a variable to a constant, representational equality is the
obvious interpretation; `case nnn` means "is it the number nnn". This
allows you to say `case NaN` and `case -0` and get the right answer (all
of these relations agree on what to do about 1.0).
For Valhalla's `==`, which we've decided means "substitutible" or
"indistinguishable from", then bitwise equality is the obvious answer.
Its sad that these are all different, and each case requires getting
experts in a room to hash it out, but that's life with floating point.
Your claim about refactoring anomalies is not right; the refactoring you
offer will work for your example which uses 3.14, because `==` agrees
with r.e. at the "regular" floating point values. Where it will fail is
for NaN, as `==` has its own weird opinions about NaN. But `== NaN` is
intrinsically useless anyway, since it folds to false, and anyone who
knows what NaN is already knows this (probably by having been bitten by
it).
On 1/26/2023 9:25 AM, forax at univ-mlv.fr wrote:
>
>
> ------------------------------------------------------------------------
>
> *From: *"Angelos Bimpoudis" <angelos.bimpoudis at oracle.com>
> *To: *"Remi Forax" <forax at univ-mlv.fr>
> *Cc: *"amber-spec-experts" <amber-spec-experts at openjdk.org>
> *Sent: *Thursday, January 26, 2023 2:55:31 PM
> *Subject: *Re: Draft JEP on Primitive types in patterns,
> instanceof, and switch
>
> Thanks for the quick reply.
>
> I think there is one important factor here. By quickly inspecting
> the issues in the links, IIUC, the semantics of floating-point
> constants there follow the semantics of |==|. So -0 and 0 compare
> equal there (e.g.,
> https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182).
>
>
> The JEP follows the road of "representation equivalence" as
> described in
> https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq
> <https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq>
>
>
> In terms of semantics Double::equals may be better than double ==
> double, this seems to be the direction that Java is choosing
> (Valhhalla also used Double::equals for value types containing a double).
>
> But it means that introducing a "when" is not a valid refactoring
> case double 3.14 -> ...
> can not be refactored to
> case double x when x == 3.14 -> ...
>
> Most of my students thinks in terms of equivalence, breaking this kind
> of refactoring make the proposed semantics not intuitive.
>
> That's why i think it's better to not allow double/float constants, so
> people have to be explicit about the semantics they want.
>
> regards,
> Rémi
>
>
>
> ------------------------------------------------------------------------
> *From:* Remi Forax <forax at univ-mlv.fr>
> *Sent:* 26 January 2023 14:16
> *To:* Angelos Bimpoudis <angelos.bimpoudis at oracle.com>
> *Cc:* amber-spec-experts <amber-spec-experts at openjdk.org>
> *Subject:* [External] : Re: Draft JEP on Primitive types in
> patterns, instanceof, and switch
> > From: "Angelos Bimpoudis" <angelos.bimpoudis at oracle.com>
> > To: "amber-dev" <amber-dev at openjdk.org>
> > Sent: Thursday, January 26, 2023 10:48:47 AM
> > Subject: Draft JEP on Primitive types in patterns, instanceof,
> and switch
>
> > Hello all,
>
> > I would like to share this draft JEP with you about primitive
> types in patterns,
> > instanceof, and switch:
>
> > https://openjdk.org/jeps/8288476
>
> > "Enhance pattern matching by allowing primitive types to appear
> anywhere in
> > patterns. Extend instanceof to support primitive types, and
> extend switch to
> > allow primitive constants as case labels."
>
> > Comments very much welcomed!
>
> > Many thanks,
> > Angelos
>
> I still think that the semantics proposed for pattern matching on
> primitive types is useless complexity with the perverse side
> effect of normalizing the usage of "default" in pattern matching
> (too many examples of this JEP are using "default") but we already
> discussed that.
>
> Allowing switching on double and float constants is just wrong.
> Rust is actually trying to remove that feature
> [
> https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$
> |
> https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$
> ]
>
> I see no point to make the same mistake.
>
> Otherwise, the rest is fine.
>
> Rémi
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20230126/98a1ca99/attachment-0001.htm>
More information about the amber-spec-experts
mailing list