<C# proposal for type unions> - good read. While "...
# language-evolution
d
C# proposal for type unions - good read. While "union classes/structs" are essentially sealed classes, they are also supporting "ad-hoc unions" with erasure. Is something like this still under consideration for Kotlin?
2
c
"ad-hoc unions" with erasure. Is something like this still under consideration for Kotlin?
No, because: • having ad-hoc unions makes the typesystem much much more complex, which will make the debugger much slower than it is • erasure means no interoperability with Java
d
having ad-hoc unions makes the typesystem much much more complex, which will make the debugger much slower than it is
I think there are solutions to this, right? Maybe making them less useful, but you can limit the amount of inference involved and require explicit types when unions are involved, and so forth. Why does C# not consider this a problem?
erasure means no interoperability with Java
True, but I think we're at a point where that's not as big of a concern. Inline value classes, coroutines, and so forth also have this problem but the idea there is that you don't use those in Java-facing APIs.
c
Why does C# not consider this a problem?
No idea, but the Kotlin team has said multiple times that this is the main blocker.
b
For what it's worth, it looks like they are planning to foregoing Java interop for the sake of a better Kotlin experience. And this makes me think they are opting for erasure to implement unions, though that is me reading into it a little.

https://youtu.be/3uNpmhHwkuQ?t=44m2s

And in general, this video is a fantastic overview of where the design for unions is currently at for Kotlin, including type system algorithms and the pragmatic decisions that are guiding the design :)
m
This proposal is very, very rough. Their motivation is not clear and use cases are not provided. The proposal jumps straight to the solutions section, trying to find generic applications of unions while it should be vice versa. Not to mention that a few sections, like type inference, are empty. It's a very early stage of the proposal, so I'd wait a bit before discussing it in detail.
having ad-hoc unions makes the typesystem much much more complex
Maybe making them less useful
Exactly. But to do so, we have to be sure about our use cases. It's easy to bring a feature to the language, but it's way harder to find the right balance between complexity and usefulness; otherwise, we can get accidental complexity. What exactly do we want to make better with unions in a particular language? For now, in Kotlin, where we have overloads, defaults, sealed types, and type inference, I believe the best fit for unions is for handling errors, and this is the design we're exploring right now. But again, we have to discuss the whole picture of handling errors. What options do we have right now, how unions will integrate with the rest and so on. --- And to give you some intuition why unions aren't good for the type checker. The main problem is type variables. These are crucial for us because we want to write generic functions and reuse existing library methods for collections that work with union data types, for example. Let's imagine I get the following constraint in my system: X | Y <: A | B (<: means subtype) Where X and Y are type variables; A and B are regular types. In order to solve it, we have to simplify it first:
Copy code
X <: A | B
Y <: A | B
=>
X <: A OR X <: B
Y <: A OR Y <: B
And here's the problem. 'X' is not a regular type but a type variable. So to fairly solve our constraint system, we have to try to fix the type variable X := A and try to solve the rest of the system. This is the so-called "fork point". After we solve the rest of the system, we have to go back and try to solve the system when X := B. And, of course, we have to fork the constraint system for 'Y' as well. So, if the complexity for type checking of regular union types is O(n * m) (n — number of components on the left, m — components on the right), then the story with generics is way worse. Very-very rough we have to solve our constraint system m^type_vars times or m^n times here. Unfortunately, when m is higher than 1, it can already be painful, as solving the whole constraint system more than once and performing collateral computations can be too much
thank you frog 1
❤️ 2