Yes, “union” are not necessarily disjoint. See the not-very-good wikipedia page where it is called “tagged union”. Basically an enumeration where each case can carry (typed) parameters, not just a name.
If you don’t know of this feature, you are missing a fundamental concept about programming, which should be as primitive and regularly-used as pairs/tuples, but isn’t well-known because many programming languages ignore it completely, which is a shame. You should have a look!
Yep, dynamic languages don’t have the syntax for it, but the use case of course exists, e.g. discriminating with a “kind” or “type” field. Thanks for the pointer though.
Not-directly-related note: Some languages argue that because they already have constructs that enable dispatch-on-case, typically Go interfaces, they “don’t need tagged unions” which are a strict subset of their feature. I understand the argument (in the good cases, the dispatching constructs allow an encoding of typical pattern-matching that is tolerable, although it’s easy to overlook nested matching and other niceties). But I think it misses the point that tagged unions enables static exhaustiveness checking (does this switch/match cover all cases?), which is a huge win usability-wide: when I add a new case, the checker walks me through all the definitions that need to be updated. (Just like adding a new method in a class.) Scala realized this early, encoding algebraic datatypes as sealed classes. (Of course, this argument is moot for languages whose users are averse to static checking of their code.)
First class Enums are exciting - I will not miss making arrays of constants, or constants that are arrays of constants, to fill in the gap Enums would have filled.
I can’t help but think the implementation is over-complicated. Do we really need enum types that have methods and static methods, and can implement interfaces? Many languages have enums without any of these features and this is more than enough.
I guess variants / disjoint-sum-types / algebraic datatypes will have to wait for PHP 81.0.
PHP has unions since 8.0: https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.union
(I realise that one cannot name such a union yet.)
Did you mean something different by “disjoint sum type”?
Yes, “union” are not necessarily disjoint. See the not-very-good wikipedia page where it is called “tagged union”. Basically an enumeration where each case can carry (typed) parameters, not just a name.
If you don’t know of this feature, you are missing a fundamental concept about programming, which should be as primitive and regularly-used as pairs/tuples, but isn’t well-known because many programming languages ignore it completely, which is a shame. You should have a look!
Yep, dynamic languages don’t have the syntax for it, but the use case of course exists, e.g. discriminating with a “kind” or “type” field. Thanks for the pointer though.
Looking more into it, PHP has an RFC for tagged unions: https://wiki.php.net/rfc/tagged_unions and it seems that there is a larger effort to bring more features for algebraic types to PHP: https://wiki.php.net/rfc/adts
Not-directly-related note: Some languages argue that because they already have constructs that enable dispatch-on-case, typically Go interfaces, they “don’t need tagged unions” which are a strict subset of their feature. I understand the argument (in the good cases, the dispatching constructs allow an encoding of typical pattern-matching that is tolerable, although it’s easy to overlook nested matching and other niceties). But I think it misses the point that tagged unions enables static exhaustiveness checking (does this switch/match cover all cases?), which is a huge win usability-wide: when I add a new case, the checker walks me through all the definitions that need to be updated. (Just like adding a new method in a class.) Scala realized this early, encoding algebraic datatypes as sealed classes. (Of course, this argument is moot for languages whose users are averse to static checking of their code.)
Russ Cox’s post and the GitHub issue show some of the difficulties with adding sum types to Go.
First class Enums are exciting - I will not miss making arrays of constants, or constants that are arrays of constants, to fill in the gap Enums would have filled.
I can’t help but think the implementation is over-complicated. Do we really need enum types that have methods and static methods, and can implement interfaces? Many languages have enums without any of these features and this is more than enough.
The same could be said of classes; why should structs have methods!