Most languages have a way you can kinda-sorta define these. One common method in OO is an abstract base class with shallow inheritance. But it is a lot of code overhead versus the concise definition above. And it is also not particularly idiomatic to OO. People probably wouldn't bat an eye at using case on an enum, but type checking for a derived class is often considered a code smell.
You can also represent these choices as nullable fields in a single class, but then you have to write a bit of code to control access and protect against the case where none or multiple of them are set at once. Doable, but annoying enough that people usually don't.
Value equality by default is very nice for testing. It means I can do things like this:
If the actual has the same values as expected (1 and "One" here), then it will return true. And it works for union types too. In most languages, these things have reference equality by default. So the last line would only return true if actual and expected were pointing to the same memory location, which is not super helpful. You can usually get value equality in any language, but it might be a pain. In C# for example, you can override the default implementations of GetHashCode and Equals to get value equality. It adds an extra 8+ lines of code to every class definition (and each field adds more lines of code potentially). I believe a lot of people use tools to add them in automatically and then code folding to hide them. Or just manually check for equality when needed.
And I could go on: no nulls, immutability by default, pattern matching, composable asyncs, sequences, etc. Then I need to go fix something in our VB code base, and it's 😬😬😬. Well, one thing VB has that most others don't is XML literals. So there's that.
I don't like when languages call abstract data types "union". Because it is technically not true. They are disjoint unions, which makes them nice to use. The only language that I know that has actual union types is typescript.
F# calls them discriminated unions, technically. For the purposes of my comment I called them union types to keep it conceptually simple. The extra adjective "disjoint" or "discriminated" is more technically correct, but for many people it automatically biases them to react with "too complex; didn't read". When really it is a simple concept.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Two things I think are really powerful in F# that are not found in most languages.
Union types are a way to represent one of multiple different possibilities. It is a bit like an enum type that can have extra data with it.
Most languages have a way you can kinda-sorta define these. One common method in OO is an abstract base class with shallow inheritance. But it is a lot of code overhead versus the concise definition above. And it is also not particularly idiomatic to OO. People probably wouldn't bat an eye at using
case
on an enum, but type checking for a derived class is often considered a code smell.You can also represent these choices as nullable fields in a single class, but then you have to write a bit of code to control access and protect against the case where none or multiple of them are set at once. Doable, but annoying enough that people usually don't.
Value equality by default is very nice for testing. It means I can do things like this:
If the
actual
has the same values asexpected
(1 and "One" here), then it will return true. And it works for union types too. In most languages, these things have reference equality by default. So the last line would only return true ifactual
andexpected
were pointing to the same memory location, which is not super helpful. You can usually get value equality in any language, but it might be a pain. In C# for example, you can override the default implementations ofGetHashCode
andEquals
to get value equality. It adds an extra 8+ lines of code to every class definition (and each field adds more lines of code potentially). I believe a lot of people use tools to add them in automatically and then code folding to hide them. Or just manually check for equality when needed.And I could go on: no nulls, immutability by default, pattern matching, composable asyncs, sequences, etc. Then I need to go fix something in our VB code base, and it's 😬😬😬. Well, one thing VB has that most others don't is XML literals. So there's that.
I don't like when languages call abstract data types "union". Because it is technically not true. They are disjoint unions, which makes them nice to use. The only language that I know that has actual union types is typescript.
F# calls them discriminated unions, technically. For the purposes of my comment I called them union types to keep it conceptually simple. The extra adjective "disjoint" or "discriminated" is more technically correct, but for many people it automatically biases them to react with "too complex; didn't read". When really it is a simple concept.