Guards redux

Remi Forax forax at univ-mlv.fr
Wed Mar 10 16:33:03 UTC 2021


> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Gavin Bierman" <gavin.bierman at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Envoyé: Mercredi 10 Mars 2021 16:02:10
> Objet: Re: Guards redux

> This feels like we landed in a good place. It preserves the underlying goal of
> the original approach -- that we can compose patterns with patterns, and
> patterns with boolean expressions, and doesn't require nailing bags onto switch
> (yay). The main difference is that it creates a distinguished "guarded pattern"
> operator rather than asking users to compose guarded patterns from an
> expression-to-pattern operator and pattern-AND.

You nail the guard to a pattern, which is equivalent until we have nested patterns (and "or"/"and" patterns). 

I see a lot of advantages of using && to link a guard to a pattern, 
- the symbol is heavy so there is a clear visual separation 
- without any supplementary parenthesis, && after the type pattern in an instanceofis the && between expression, it's almost like you can not have a guard with an instanceof, in practice, few instanceof will have a guard. 

I still think that using a guard inside a nested pattern is ugly but it can be just that, ugly. Someone may want a short-circuit in a deeply nested patterns . 

> The main objections to the `P & true(e)` approach were the aesthetic reaction to
> this use of `true` (which was one of those first-five-minutes reactions, and
> people might well have gotten over it in the next five minutes), and the more
> serious discoverability problem of having to compose two (currently unfamiliar)
> features to get guarded patterns. The current proposal seems a lower energy
> state, while deriving from the same basic principles.

> FTR, the key observation that broke the jam was the observation that, if we
> treat & and && as:

> (&) :: Pattern -> Pattern -> Pattern
> (&&) :: Pattern -> Expression -> Pattern

> we can, with parentheses, achieve arbitrary orderings of patterns and guard
> expressions, and are not forced to push all guards to the end (which was where
> we got stuck the last time we looked at &&.)
As i said to Gavin, i'm not at ease with using the symbol '&' in between patterns. 

Rémi 

> On 3/10/2021 9:47 AM, Gavin Bierman wrote:

>> Okay, so it seems like our initial stab at guards and a pattern conjunction
>> operator needs some finessing.

>> Here's another take, inspired by Guy's emails.

>> Step 1. Let's use `p && e` as the way to guard a pattern p with a boolean
>> expression e.

>> Step 2. [Now or later] Let's use `&` (and `|`) as the conjunction and
>> disjunction operators on patterns.

>> There are a couple of immediate parsing puzzlers:

>> * e instanceof String s && s.length() > 2

>> This parses as `(e instanceof String s) && s.length() > 2` today. We need to be
>> careful that our grammar continues to make this the case (see below). We will
>> also introduce a parenthesized pattern, which you can use if you want the
>> dangling `&& s.length() > 2` to parse as a guard for the `String s` type
>> pattern. (It is extremely fortuitous that the functional behavior of both
>> expressions is the same, but either way I think this is a simple rule.)

>> * case p && b -> c -> b

>> Now we have some ambiguity from the `->` in a lambda expression and in a switch
>> rule. Fortunately, again I think we can just lean into the grammar to get what
>> we want. At the moment, the grammar for expressions is:

>>     Expression:
>>         LambdaExpression
>>         AssignmentExpression

>> As a lambda expression can never be a boolean expression it can never
>> meaningfully serve as a guard for a pattern. Great!

>> So, I'd like to suggest this grammar for patterns (including pattern conjunction
>> and pattern disjunction operators for completeness but we can drop them from the
>> first release):

>> Pattern:
>> : ConditionalOrPattern
>> : ConditionalOrPattern `&&` Guard

>> ConditionalOrPattern:
>> : ConditionalAndPattern
>> : ConditionalOrPattern `|` ConditionalAndPattern

>> ConditionalAndPattern:
>> : PrimaryPattern
>> : ConditionalAndPattern `&` PrimaryPattern

>> PrimaryPattern:
>> : TypePattern
>> : RecordPattern
>> : ArrayPattern
>> : `(` Pattern `)`

>> Guard:
>> : AssignmentExpression

>> Along with the following change to the grammar for instanceof:

>> InstanceofExpression:
>> : RelationalExpression `instanceof` ReferenceType
>> : RelationalExpression `instanceof` PrimaryPattern      <-- Note!

>> Some consequences:

>> p1 & p2 & p3 && g1 && g2 parses as ((p1 & p2) & p3) && (g1 && g2), yay!

>> p1 && g1 & p2 && g2 needs to be bracketed as (p1 && g1) & (p2 && g2) to parse
>> properly. But that's okay, as I think the second is much clearer.

>> Let me know what you think.

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


More information about the amber-spec-experts mailing list