Published: pattern matching

Brian Goetz brian.goetz at
Wed Apr 19 14:34:31 UTC 2017

> so i've mostly syntactic comments:

Augh!  No!  :)

> - I was wondering if matches can be spelled instanceof ?

This would work if all we were ever going to do was type-test patterns.  
But when it gets to destructuring patterns, structural patterns, regex 
patterns, etc -- all reasonable possibilities in the future -- then 
instanceof starts to feel more strained.

But we might consider a loosening of instanceof to accept a binding 
variable *also*.

> - the var pattern: i'm sure you have considered removing the 'var'
>    int eval(Node n) {
>        return exprswitch(n) {
>            case IntNode(i) -> i;
>            case NegNode(v) -> -eval(v);
>            ...
>        };
>    }
>    but reject it because
>      - from the compiler perspective, you have to wait the typechecking pass (or a pass just before) to know if a symbol 'v' is a parameter or variable access.

Yes, we considered it.  But the reason for preferring var here is not 
necessarily just compiler complexity; it's that it's weird for

     if (x matches Foo(y))

to be a _declaration_ for y.  Java developers are not used to that. 
Having the slightly more verbose

     if (x matches Foo(int y))


     if (x matches Foo(var y))

makes it more obvious that y is being declared, not used.  This seems a 
good tradeoff of clarity for verbosity.

> - exhaustiveness,
>    if the class is sealed/closed, i think all data class should be declared into the interface
>      sealed interface Node {
>        data class IntNode(int value) { }
>        data class NegNode(Node node) { }
>        ...
>      }
>    It makes more clear the fact that you can not open the interface Node to add a new subtype and you do not need to declare that each subtype implements the sealed class.

This is definitely one of the contenders.  Without branching out into 
the design space of sealing too much -- the mention in the doc was 
mostly intended to suggest that its on the table -- there's a spectrum 
of flexibility for sealing (both at the language and VM level).  The 
simplest is that sealing means "nestmates only", as you suggest.  Of the 
candidates, I think this is probably the best choice at the language 
level.  It's on my list (but several entries down) to write up a more 
detailed summary of our explorations here.

>    It also means that the real name of IntNode is now Node.IntNode (so you can remove the Node suffix !), but you mostly don't care because when you use the exprswitch, you're switching over a Node so the compiler can infer the right name the same way the compiler infer the right name of an enum constant.

Like enums.  (BTW, when we get to expression switches, we'll have to 
tweak our treatment of exhaustiveness for enum switches.)
>    And more or less like Scala, the compiler can add a bunch of static factory methods so instead of new Mode.IntNode(0), one can write Node.IntNode(0), IntNode being the name of a factory method that creates an IntNode.

Possibly.  Data classes are a whole separate feature, about which people 
will have strong opinions...  let's come back to that later.

More information about the amber-spec-experts mailing list