Guards redux

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


----- Mail original -----
> De: "Gavin Bierman" <gavin.bierman at oracle.com>
> À: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Mercredi 10 Mars 2021 15:47:30
> Objet: Guards redux

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

Using & between patterns is unfortunate given that if if first pattern is not total and does not match, we will not "execute" the second pattern.
So the semantics is lazy but currently '&' means non-lazy on expressions.

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


More information about the amber-spec-experts mailing list