Possible Pattern Matching for switch (Third Preview) bug

Brian Goetz brian.goetz at oracle.com
Mon Aug 1 14:27:53 UTC 2022


The switch behavior is as intended.  The instanceof behavior is slightly 
surprising, but harmless -- basically like a dead local variable.  But 
in both cases, a dead binding is unlikely to mean what you intend.

As you surmise, the restriction for switch has more to do with bindings 
than with patterns; the case label is unable (or unwilling) to define 
bindings that cannot be used in the case block.  Currently we express 
this restriction with the grammar (one pattern per case), but we may 
relax this in the future and instead enforce the restriction based on DA 
of bindings, in which case you might be able to do something like:

     case Foo _, Bar _:

A related possibility is that it may be possible to _merge_ bindings:

     case Box(String x), Bag(String x): System.out.println(x);

Here, we would match one pattern or the other, and either way, one of 
them would bind `String x`.  We discussed this for a while but deferred 
it for later.  The main challenge here is: "where's the declaration of 
x?"  This may be confusing to both humans and tools, to have two 
declarations for a common use.



On 8/1/2022 7:58 AM, Jordan Zimmerman wrote:
> There doesn't seem to be a way to have a switch case pattern for 
> multiple related patterns. Given that it works in an instanceof 
> pattern I would think it might work in a switch pattern. But, maybe 
> not. Anyway here's what I found.
>
> Given:
>
>     public interface MyFace {}
>
>     public record MyEye() implements MyFace {}
>     public record MyNose() implements MyFace {}
>
>     public void examine(Object face) {
>     switch (face) {
>     case MyEye eye, MyNose nose -> System.out.println("part of my face");
>     default -> System.out.println("Not part of my face");
>     }
>     }
>
> This produces: "illegal fall-through to a pattern".
>
> However, this works with an instanceof pattern. E.g.
>
>     public void examine(Object face) {
>     if ((face instanceof MyEye eye) || (face instanceof MyNose nose)) {
>     System.out.println("part of my face");
>     }
>     else {
>     System.out.println("Not part of my face");
>     }
>     }
>
>
> Of course, the instanceof test is not very useful as the bound 
> variables "eye" or "nose" are only scoped to the immediate test (and 
> not in the if block). So, this may not be a bug? Anyway, I thought I'd 
> mention it. For the switch it would be useful to have common behavior 
> for several related patterns without having to use a method to do it. 
> The bound variables would be ignored (maybe via an upcoming wonderbar 
> "_").
>
> Cheers.
>
> -Jordan
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20220801/4c68acc0/attachment.htm>


More information about the amber-dev mailing list