Next up for patterns: type patterns in switch
Brian Goetz
brian.goetz at oracle.com
Fri Aug 14 11:24:10 UTC 2020
>
> Is the following what you mean by "mangle your switch badly" ?
>
> switch (o) {
> case A: ...
> case B: do some B-ish stuff ... also, if (g) {...}
> case C: ...
> ...
> case Z: ...
> case Object: if (o instanceof B && !g) { do the B-ish non-g thing }
> }
Worse! What I meant is that if you do not have guards, you have to move such stuff OUTSIDE of the switch. Instead of:
case B & g: …
case B: b-logic
case Object: default-logic
you have to do
switch (x) {
case B:
if (!g) { break out of the switch! }
B logic;
case Object:
default-logic;
}
if (it was B but not G) {
do the default logic again
}
The problem with a guard-less switch is that you get exactly one chance to fall into one of the buckets, and once you’re in a bucket, your only choice is to fall out of the switch.
> Is a guard (a) part of the `case` construct, or (b) part of the pattern operand for a `case` construct?
Good question. We went back and forth a few times on this.
My initial preference was to make the guard logic part of the pattern; ideally, to make “Pattern && boolean-expr” a pattern. But this is messy, since it invites ambiguities, and not really needed in the other primary consumer of patterns, since boolean expressions can already be conjoined with &&, and flow scoping already does everything we want. The real problem is switch is too inflexible, a problem revealed when its case labels are made more powerful. So it seems that the sensible t hing to do is to make guards a feature of switch, and say a case label is one of:
case <constant>
case <pattern>
case <pattern> when <guard>
> The original mail introduced "guard expression" as "a boolean expression that conditions whether the case matches", which sounds like (a). However, the purpose of a `case` construct is to enumerate one or more possible values of the selector expression, and if a `case` construct has a post-condition `& g()` then it's not just enumerating, and it isn't a `case` construct anymore. I mean, we don't want to see guards in the `case` constructs of legacy switches, right? (`switch (i) { case 100 & g():`) So, is the answer (b) ?
Does the above grammar suggestion answer your question?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200814/5dc66971/attachment.htm>
More information about the amber-spec-experts
mailing list