> 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.