> De: "Brian Goetz" <brian.go...@oracle.com> > À: "Gavin Bierman" <gavin.bier...@oracle.com>, "amber-spec-experts" > <amber-spec-experts@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