> On Jan 8, 2021, at 12:45 PM, Brian Goetz <[email protected]> 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`.