[pattern-switch] Guards

Brian Goetz brian.goetz at oracle.com
Wed Aug 26 20:57:34 UTC 2020


This inclination (guards are simple, continue is complicated) is also 
supported by the following observation: we just went through a big 
exercise for (optimistic) totality, but any pattern that is guarded 
(imperatively or declaratively) can't be assumed to cover anything.  It 
is far easier to spot a pattern with a guard (even if the guard is `&& 
false`) and know it doesn't contribute to totality, than to scan the 
imperative body looking for a `continue`.



On 8/26/2020 4:53 PM, Kevin Bourrillion wrote:
> I think it will usually be easy for users to keep guards simple, by 
> just extracting out a method when they're not, and the aesthetics will 
> even motivate them to do that.
>
> With `continue`, there might be any amount of complexity, even state 
> changes, in the statement group before the `continue` is hit, and it's 
> not necessarily extractable.
>
> Really, it just seems like we now have two different kinds of 
> fall-through layered on top of each other. The silent continue is for 
> going to the next group, while the explicit continue goes back to 
> checking for a match. Why that way and not the other way around? Just 
> legacy reasons.
>
> I like the guards.
>
>
>
> On Fri, Aug 14, 2020 at 10:21 AM Brian Goetz <brian.goetz at oracle.com 
> <mailto:brian.goetz at oracle.com>> wrote:
>
>>
>>      - Guards.  (John, Tagir) There is acknowledgement that some sort
>>     of "whoops, not this case" support is needed in order to maintain
>>     switch as a useful construct in the face of richer case labels,
>>     but some disagreement about whether an imperative statement
>>     (e.g., continue) or a declarative guard (e.g., `when
>>     <predicate>`) is the right choice.
>
>     This is probably the biggest blocking decision in front of us.
>
>     John correctly points out that the need for some sort of guard is
>     a direct consequence of making switch stronger; with the current
>     meaning of switch, which is "which one of these is it", there's no
>     need for backtracking, but as we can express richer case labels,
>     the risk of the case label _not being rich enough_ starts to loom.
>
>     We explored rolling boolean guards into patterns themselves (`P &&
>     g`), which was theoretically attractive but turned out to not be
>     all that great. There are some potential ambiguities (even if we
>     do something else about constant patterns, there are still some
>     patterns that look like expressions and vice versa, making the
>     grammar ugly here) and it just doesn't have that much incremental
>     expressive power, since the most credible other use of patterns
>     already (instanceof) has no problem conjoining additional
>     conditions, because it's a boolean expression.  So this is largely
>     about filling in the gaps of switch so that we don't have
>     fall-off-the-cliff behaviors.
>
>     There are two credible approaches here:
>
>      - An imperative statement (like `continue` or `next-case`), which
>     means "whoops, fell in the wrong bucket, please backtrack to the
>     dispatch";
>
>      - A declarative clause on the case label (like `when
>     <predicate>`) that qualifies whether the case is selected.
>
>     Most of the discussion so far has been on the axis of "continue is
>     lower-level, and therefore better suited to be a language
>     primitive" vs "the code that uses guards is easier to read and
>     reason about."  Assuming we have to do one (and I think we do), we
>     have three choices (one, the other, or both.)  I think we should
>     step away from the either/or mentality and try to shine a light on
>     what goes well, or badly, when we _don't_ have one or the other.
>
>     For example, with guards, we can express fine degrees of
>     refinement in the case labels:
>
>         case P & g1: ...
>         case P & g2: ...
>         case P & g3: ...
>
>     but without them, we can only have one `case P`:
>
>         case P:
>             if (g1) { ... }
>             else if (g2) { ... }
>             else if (g3) { ... }
>
>     My main fear of the without-guards branches is that it will be
>     prohibitively hard to understand what a switch is doing, because
>     the case arms will be full of imperative control-flow logic.
>
>     On the other hand, a valid concern when you have guards is that
>     there will be so much logic in the guard that you won't be able to
>     tell where the case label ends and where the arm begins.
>
>
>
>
> -- 
> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com 
> <mailto:kevinb at google.com>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200826/5f7c5362/attachment.htm>


More information about the amber-spec-experts mailing list