<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<font size="+1"><font face="monospace">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. <br>
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. <br>
FTR, the key observation that broke the jam was the observation
that, if we treat & and && as:<br>
(&) :: Pattern -> Pattern -> Pattern<br>
(&&) :: Pattern -> Expression -> Pattern<br>
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 &&.) <br>
<div class="moz-cite-prefix">On 3/10/2021 9:47 AM, Gavin Bierman
<blockquote type="cite" cite="mid:7EB71CD0-E0F7-4FCD-87EA-5AEEE3643D15@oracle.com">
<pre class="moz-quote-pre" wrap="">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
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:
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
: ConditionalOrPattern `&&` Guard
: ConditionalOrPattern `|` ConditionalAndPattern
: ConditionalAndPattern `&` PrimaryPattern
: `(` Pattern `)`
Along with the following change to the grammar for instanceof:
: RelationalExpression `instanceof` ReferenceType
: RelationalExpression `instanceof` PrimaryPattern <-- Note!
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.