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