[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