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