[pattern-switch] Guards

Guy Steele guy.steele at oracle.com
Fri Jan 8 22:40:15 UTC 2021



> On Jan 8, 2021, at 4:26 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> 
> 
>> 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.
> 
> I agree such a move would be poor.  That was my motivation for suggesting & for "pattern conjunction" instead of &&; to relegate these concerns to irrelevance.  So
> 
>     if (x instanceof P & X) 
> 
> says X is a pattern and we're testing x against the composite pattern P AND X, and
> 
>     if (x instanceof P && X)
> 
> says X is a boolean expression.  

And I am saying, yes we can do that and make it work, but only by violating Java's ancient implicit design rule that operator precedence obeys a total order.

If I understand correctly, your proposal is that 


    if (x instanceof P & X)    means the same as     if (x instanceof (P & X))     if X is a pattern

but

    if (x instanceof P & X)    means the same as     if ((x instanceof P) & X)     if X is an expression

(which has always been true, and I’m assuming you are not proposing a big, incompatible change here).

That would mean that you have to commit to a grammar in which patterns can in fact be distinguished from expressions.

Note that if that latter fact is true, then you don’t need to say

	case P(var x) & true(x > 0):

It should suffice to say

	case P(var x) & x > 0:


>> 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`.
> 
> The intent of this example was that the `x` from `var x` would be in scope for `x > 0` -- I'm trying to represent the "guarded" pattern "P(var x) when x>0".  So I'm a little confused what you are suggesting -- is it that && is better for pattern conjunction than &, or something else?

Sorry, I got confused here.  Sure, in an expression (P & Q), all pattern variables bound in P are in scope within Q.  Sorry I got that wrong.  Please ignore everything I said about that.

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


More information about the amber-spec-experts mailing list