The “as” pattern which binds a value before doing
more pattern matching
Note that for all the patterns we have right now, there is no need: type
patterns, record/deconstruction patterns, and array patterns all take an
identifier (optional in the last two) which is the as-slot. I believe
users will find:
case Point(var x, var y) p:
much more natural than
case Point(var x, var y) & var p:
and, additionally, if we intend to generalize local declaration / method
parameters to support total patterns, then we will want this extra
syntax anyway:
void m(Point(var x, var y) p) // p is surely required here
So the "as" slot right now is a theoretical concern, but, your point is
taken, that a conjoined `var` pattern can act as an "as".
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.)
I think what you're saying is that if P has a target-type of T, and Q
has a target-type of U, then in
x instanceof (P & Q & var x)
and, given x : X, then, since we won't even try to match `var x` unless
P and Q already match, we seed inference with constraints x <: X, x <:
T, and X <: U, and will generally get out (some normalization of) x <:
T&U&X.
You noted that array patterns sometimes want to
refer into the middle of the array.
I think this is relatively low on the priority list; matching the whole
array, or an initial segment of the array, seem natural use cases for
the language, but I'm not sure I want to embed a comprehension-query
language to pick up the rest of the use cases.
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.
The array syntax is closely related to declared patterns with varargs
(of which varargs records are already on the docket.)
You mention constraints that force switches to be
either pattern switches or non-pattern switches.
(This is near the example with “error1”.)
This was intended as a transitional ("Preview 1") simplification. A
constant case `case L` can be desugared to `case var x && x == L`
relatively easy.
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.
Yep, good catch.