Published: pattern matching
Brian Goetz
brian.goetz at oracle.com
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))
or
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