JEP 455: Non-enhanced switch statements
Brian Goetz
brian.goetz at oracle.com
Wed Oct 25 16:25:09 UTC 2023
We have two not-great choices here:
- Treat otherwise-boring switches on long/float/double/boolean (and
their boxes) as legacy primitive switches, omitting the enhanced
exhaustiveness checking;
- Treat switching on float/double/boolean and their boxes as
triggering the enhanced exhaustiveness checking.
It is unfortunate that we have to have a carve-out for "old" switches,
because this means an irregular and possibly-surprising boundary in the
language, which users will have to learn (sometimes learning the hard
way.) But we do, and we accepted it as the cost of turbo-charging
switch (new selector types, new case labels, better exhaustiveness,
guards, null support, etc.) Ideally we will have a path to gently
guiding users away from the legacy behavior to the point where we are
eventually comfortable promoting some warnings to errors, and this issue
goes away, but that will surely take a long time, and I won't dwell on
it here.
In the meantime, we have a choice of "which of these two irregular
boundaries do we want the user to reason about":
- A statement switch is exempt from exhaustiveness checking if it does
not use patterns, null cases, guards, or switch on anything other than
{byte,char,short,int}, their boxes, enums, or strings, or
- A statement switch is exempt from exhaustiveness checking if it does
not use patterns, null cases, guards, or switch on anything other than a
primitive, their boxes, enums, or strings.
Remi makes the argument for the first path, on the basis of "let's
freeze the legacy behavior to the legacy rules." This is a reasonable
argument. However, the opposite argument is also reasonable; that
"typical user intuition" about "old switch" is closer to "primitives,
boxes, enums, and strings", and that allowing the remaining primitive
types to fit into the old model may minimize cognitive load on the
user. (It is easier to keep track of "primitives" than "the primitives
that we thought were reasonable to switch over in 1995", since that set
is kind of arbitrarily chosen.)
So while I don't have an answer, I do think that both possible answers
have merit :)
On 10/25/2023 4:50 AM, Remi Forax wrote:
>
>
> ------------------------------------------------------------------------
>
> *From: *"Angelos Bimpoudis" <angelos.bimpoudis at oracle.com>
> *To: *"amber-spec-experts" <amber-spec-experts at openjdk.org>
> *Cc: *"Yuriy Maslyanko" <yuriy.maslyanko at oracle.com>
> *Sent: *Wednesday, October 25, 2023 12:49:18 AM
> *Subject: *Fw: JEP 455: Non-enhanced switch statements
>
> Hello all!
>
>
> Hello Angelos,
>
>
> Yuriy pointed out a valid point.
>
> 1) Should we treat float/double/boolean/longs as a new addition to
> the non-enhanced switch (old switch) and support anything new that
> comes with that?
>
> or
>
> 2) Should we treat those data types equally with all the
> pre-existing ones?
>
> I am strongly in favour of the 2) for the shake of symmetry and
> uniformity in what the user will assume, thus I will fix the bug.
>
> What do others think?
>
>
> We have already discuss that, when we have introduce the switch on
> objects.
> The question is not what our current users will assume now but how the
> whole semantics of switch will be see let say 5 years from now, when
> people are used to use the switch on objects.
> The old switch is not a feature used a lot, we expected the new switch
> on objects to be used a lot more, so at some points, most of the
> switches will be switches on object so the semantics of the old switch
> will be the outlier.
> So the switch on float/double should behave like on objects, i.e. be
> hexaustive by default.
> It's the same reason why adding a "case null" or a "where" condition
> transforms the switch to the new semantics.
>
> And there is another reason to make the switch on float/double
> exhaustive, the matching of a cases on primitive types can be partial,
> when we discussed that feature this is was obvious for some of us (me
> included).
> By making the switch exhaustive, we actually help users to understand
> the actual semantics, because the compiler will requires a "default"
> if the pattern matching is not total.
>
> regards,
> Rémi
>
>
> ------------------------------------------------------------------------
> *From:* Yuriy Maslyanko <yuriy.maslyanko at oracle.com>
> *Sent:* 24 October 2023 21:57
> *To:* Angelos Bimpoudis <angelos.bimpoudis at oracle.com>
> *Cc:* compiler-dev at openjdk.org <compiler-dev at openjdk.org>
> *Subject:* JEP 455: Non-enhanced switch statements
>
> Hi Angelos,
>
> Section 14.11.2 of
> https://cr.openjdk.org/~abimpoudis/instanceof/jep443-20231010/specs/instanceof-jls.html#jls-14.11.2
> <https://cr.openjdk.org/~abimpoudis/instanceof/jep443-20231010/specs/instanceof-jls.html#jls-14.11.2>
> has this note:
>
> For compatibility reasons, |switch| statements that are not
> enhanced |switch| statements are not required to be exhaustive.
>
> Noticed that if the switch selector statement is
> float/double/boolean (in this case it’s a non-enhanced switch
> statement), the code shown below fails with “error: the switch
> statement does not cover all possible input values”:
>
> static boolean check = false;
>
> public static boolean testMethod() {
>
> double v1 = 1d;
>
> switch ( v1 ) {
>
> case 1d:
>
> check = true;
>
> break;
>
> }
>
> return check;
>
> }
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20231025/d81045a2/attachment-0001.htm>
More information about the amber-spec-experts
mailing list