Pattern matching: next steps after JEP 405
Brian Goetz
brian.goetz at oracle.com
Wed May 18 19:18:01 UTC 2022
JEP 405 has been proposed to target for 19. But, it has some loose ends
that I'd like to refine before it eventually becomes a final feature.
These include:
- *Inference for record patterns. *Right now, we make you spell out
the type parameters for a generic record pattern, such as:
case Box<String>(String s):
We also don't allow parameterizations that are not consistent with the
match target. While this is clear, it is verbose (and gets worse when
there is nesting), and also, because of the consistency restriction, the
parameterization is entirely inferrable. So we would like to allow the
parameters to be inferred. (Further, inference is relevant to GADTs,
because we may be able to gather constraints on the pattern from the
nested patterns, if they provide some type parameter specialization.)
- *Refined type checking for GADTs. *Given a hierarchy like:
sealed interface Node<T> { }
record IntNode(int i) implements Node<Integer> { }
record FloatNode(float f) implements Node<Float> { }
we currently cannot type-check programs like:
<T> Node<T> twice(Node<T> n) {
return switch (n) {
case IntNode(int x) -> new IntNode(x*2);
case FloatNode(float x) -> new FloatNode(x*2);
}
}
because, while the match constraints the instantiation of T in each arm
of the switch, the compiler doesn't know this yet.
-*Varargs patterns. * Records can be varargs, but we have an asymmetry
where we can use varargs in constructors but not in deconstruction.
This should be rectified. The semantics of this is straightforward; given
record Foo(int x, int y, int... zs) { }
just as
new Foo(x, y, z1, z2)
is shorthand for
new Foo(x, y, new int[] { z1, z2 })
we also can express
case Foo(var x, var y, var z1, var z2)
as being shorthand for
case Foo(var x, var y, int[] { var z1, var z2 })
This means that varargs drags in array patterns.
- *Array patterns. * The semantics of array patterns are a pretty
simple extension to that of record patterns; the rules for
exhaustiveness, applicability, nesting, etc, are a relatively light
transformation of the corresponding rules for record patterns. The only
new wrinkle is the ability to say "exactly N elements" or "N or more
elements".
- *Primitive patterns. * This is driven by another existing asymmetry;
we can use conversions (boxing, widening) when constructing records, but
not when deconstructing them. There is a straightforward (and in
hindsight, obvious) interpretation for primitive patterns that is
derived entirely from existing cast conversion rules.
Obviously there is more we will want to do, but this set feels like what
we have to do to "complete" what we started in JEP 405. I'll post
detailed summaries, in separate threads, of each over the next few days.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220518/0caf18b8/attachment.htm>
More information about the amber-spec-experts
mailing list