I did careful pass over the docs and here are a couple more comments. You anticipated them at the end with the “here’s what else we might do” section.
The “as” pattern which binds a value before doing more pattern matching on it should can be synthesized from “var” and “&”, as “P & var x”. The rules for inferring “var” types should take into account left context as much as possible; I don’t think that’s all there yet. (I think “var x & P” is a novice’s error, since the inferred type is poor.) To make it easy to use I suggest that “var x = P” be sugar for “P & var x”, and the same if “var” is replaced by a type name. I think you want don’t-care patterns, and “var _” recommends itself pretty strongly. Perhaps bare “_” is sugar for “var _”, or maybe there’s no need. You noted that array patterns sometimes want to refer into the middle of the array. I think that you can do this with the array-index designator syntax you mention, but perhaps it can bye done more economically by allowing the ellipsis “…” to take an optional anchoring index, to its right: { …[8], eightElement, ninthElement, … } int[] a & { first, second, …[a.length-2], penult, last } In some cases (including that last one) the [N] can be inferred, and should be. Thus, the trailing … your document supports now is revealed to be …[a.length-N], where N is the (statically determined) length of everything before the ellipsis. I think I like adding an anchor to “…” better than having an ad hoc random access { [n] -> P } syntax, because it makes visual accounting of the whole array, from left to right. But I can see arguments for the random-access form (it doesn’t have to be left-to-right). If and when we do special construction expression syntax for list, map, set, and 99 other user-defined types (I’m serious about the 99; that’s a lower limit) then we will want to make associated pattern syntaxes available. The array stuff is a harbinger of this, since (as is rightly so) the construction syntax new int[]{stuff} is associated with the deconstruction syntax which is exactly the same, except (a) the “new” is gone, and (b) the “stuff” is pattern-land instead of expression-land. Regarding the switch-case syntax, I think you have done a good job finely dividing out the syntaxes. You mention constraints that force switches to be either pattern switches or non-pattern switches. (This is near the example with “error1”.) Maybe this could be expressed by documenting three super-classes of switch cases: pattern, non-pattern, and either. Then the rule boils down to saying that a switch may not have cases which are pattern cases and also cases which are non-pattern cases. At present there are wordy lists, which are hard to keep straight. For a non-pattern switch, you conservatively left out “case null,1,2,3:”. I think that’s too conservative. I won’t always want to route null to the default case. By adding “default” as a pseudo-case-label, you made me remember that sometimes I write switches like this: switch (color) { case RED: return “red”; case BLUE: return “blue”; case NO_COLOR: //beware fallthrough default: return “nothing of interest”; } Adding “case NO_COLOR” here is purely for show, but sometimes you need some extra show, to help the reader reason about special values (such as NO_COLOR). Converting to the rule form to avoid fall through, I want: switch (color) { case RED -> return “red”; case BLUE -> return “blue”; case NO_COLOR, default -> return “nothing of interest”; } Now null is also a special value, so I might also want: switch (color) { case RED -> return “red”; case BLUE -> return “blue”; case null, NO_COLOR, default -> return “nothing of interest”; } (You started it, and I’m rounding up a few more use cases.) > 2. The scope of a pattern variable declaration occurring in a case label of a > switch labeled statement group, where there are no further switch labels that > follow, includes the block statements of the statement group suggest s/follow/immediately follow/ > On the other hand, falling through a label that does not declare a pattern > variable is safe. You might want to point out that in “test6” that “s” is no longer in scope after the default label. I didn’t see it clearly explained, though it must be true. Thanks for this great work! — John