It's just too bad they could not come up with an extended enum-as-tagged-union syntax. Using sealed classes for that pattern works but is still messy to write. It feels like writing enums with classes back in JDK 1.4 days.
I think "sealed interface" with implementations used by "records" gets you pretty close though right? This is usually what I do, something like:
sealed interface Tree {
record Leaf(int value) implements Tree {}
record Node(Tree left, Tree right) implements Tree {}
}
var tree = new Tree.Node(new Tree.Leaf(1), new Tree.Leaf(2));
This is what I was talking about. With pattern matching I now expect this exact pattern will be 98% of usage of `sealed` anything. It would be nice to have some sugar like
tagged-union Tree {
Leaf(int value),
Node(Tree left, Tree right)
}
I used `tagged-union` because for backward compat I think using `enum` would not be possible but really it could be anything.
While I agree that some syntax sugar would be welcome here (AFAIK the best you can currently do is
sealed interface Tree permits Tree.Leaf, Tree.Node {
record Leaf(int value) extends Tree {}
record Node(..) extends Tree {}
}
), it is not too terrible. Also note that rust really mixed up the nomenclature here with their enums, these were known in every language previously simply as ADTs. It makes sense for these to not have identity, while java enums are always a single instance.