> On Jan 8, 2021, at 4:26 PM, Brian Goetz <brian.go...@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.

Reply via email to