Totality at switch statements

Hunor Szegi hunor.szegi at gmail.com
Sat Jun 18 22:42:12 UTC 2022


Hi All,

I really like the progress of adding pattern matching to Java (and a lot of
other features). I can not wait to use it in productive code (non-preview).
But I would like to give you feedback about a tiny detail, about the
totality of switch statements.

Surely, the totality is necessary at switch expressions, but forcing it at
a statement is questionable.

It can be helpful for the programmers to check the totality in those cases
when the intent is that. But it is quite common to create a switch
statement that doesn't handle all of the possibilities. Why would it be
different using patterns? Why is it beneficial to force totality? This
check can be an IDE feature. (Or the programmer can try adding a default
clause, and the duplicated totality will be shown as an error. But I know
it isn't convenient.)

Honestly I feel that the rule, when the totality is forced, is dictated
simply by the necessity of backward compatibility. What will happen if a
new type (for example double) will be allowed for the selector expression?
The backward compatibility wouldn't be an issue, but it would be weird
behaving differently with an int compared to a double, so I guess the
totality won't be forced. What would happen if the finality requirement was
removed, and the equality could be checked for all types? What about the
totality check in this imagined future?

Of course the best would be to allow the totality check somehow if the
intent is that. A warning could be a solution, but that can be annoying. It
will force the programmers to suppress it, or to add a default clause (what
is the current solution). Adding a default clause could be treated as
marking the intent: we don't want totality. But the actual syntax does not
represent it clearly.

Additionally, there are issues with the "empty" default clause. In the JEP
the "default: break;" was recommended, but interestingly it doesn't work
with the arrow syntax. ("default -> break;" is a compile time error, only
the "default: {break;}" is possible.) We can use both the "default: {}" and
"default -> {}", which is fine. But while the "default:" is
possible (without body), the "default ->" is an error. I don't know what is
the reason behind it. Allowing an empty body with the arrow syntax would
make the actual solution a little bit cleaner.

I think forcing the totality at statements is partly an intent for
uniformity. The best would be if the same rules were applied to all cases,
regardless if it is a statement or expression, old or arrow syntax. But
backward compatibility can't allow full uniformity, it moves the separation
into the middle of a box, instead of a clear distinction between a
statement and expression. It creates more cases.

It would be possible, forcing the totality only at the arrow syntax. But
that would move some of the programmers using the old syntax, which may be
less fortunate.

It would be possible to allow the programmer to mark the intended totality.
Maybe a new keyword would be too much for this purpose. Alternatively I can
imagine allowing annotations at a switch statement/expression in the
future. For example:

@total
switch (x) {
...
}

If this syntax isn't possible, the annotation could be added right before
the opening curly bracket. Alternatively a warning suppress annotation
could be used specifically for the switch.
But this is only a brainstorming. My main point is that I don't think the
totality should be forced at switch statements. Or it should cause only a
warning.

I hope my feedback isn't pointless. I'd be very interested to hear other
people's opinions.

Thank you in advance,

Regards,
Hunor
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20220618/ed1c05b6/attachment.htm>


More information about the amber-dev mailing list