[pattern-switch] Guards

Guy Steele guy.steele at oracle.com
Fri Jan 8 20:54:12 UTC 2021



> On Jan 8, 2021, at 12:45 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> Picking up on this topic: there's a third possibility, which I'm starting to like better.  
> 
> ... 
> 
> Now, how to spell __AND?  We can't spell it `&&`, since we'd have an ambiguity with:
> 
>     if (x instanceof P && Q)
> 
> (is that the pattern conjunction P&&Q, or `x instanceof P` && `Q`?) 

I can answer this question, at least: for better or worse, the Java grammar was originally designed along the lines of C, in which all operators have a specific linear order of precedence.  For Java we chose to express that order of precedence by using extra productions within the LALR grammar, rather than mapping operators to integers and then using those integers in a precedence-style parser, but the principle is still there.

And in the original Java grammar and to this day, `instanceof` has higher precedence than either `&` or `&&`.  Right now this precedence principle is relevant only for the left-hand operand of `instanceof`; but if this parsing principle is to be preserved consistently, it will also be applied to the right-hand operand of `instanceof`, and it will therefore be necessary to use parentheses around an __AND expression that is the right-hand operand of `instanceof` if __AND is spelled as either `&` or `&&`:

    if (x instanceof P && Q)    should be interpreted as     if ((x instanceof P) && Q)

and if Q turns out to be a type or other pattern but not a valid expression, tough noogies: the parsing decision got made when you saw the ‘&&’ (remember, the parser is LALR(1)).

    if (x instanceof (P && Q))     should be used if you want a conjunctive pattern

We could choose to violate the parsing principle, and say that `instanceof` higher precedence than a `&` or `&&` to its left but lower precedence than a `&` or `&&` to its right, but I predict that such a move would cause enormous confusion among both implementors and users, so I strongly counsel against such a move.

Therefore I don’t see much need for `&` in patterns, but then again allowing it for conciseness (and to indicate that variables matched on its LHS are _not_ in scope on its RHS?) would do no harm.  Same for `|`.

> But I think we can use `&`.  We don't need it much in instanceof, since we already have &&, but we can in switch:
> 
>     case P(var x) & true(x > 0): 
>     case P(var x) & false(x > 0): 

And so for consistency, I would recommend that this example be rendered using `&&`, because using `&` would be an indication that the binding of `x` in `var x` is not in scope within the expression `x > 0`.

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


More information about the amber-spec-experts mailing list