adding general types like
String | Int
brings a lots of complications. One of the main problems is that it makes type checking blow up in terms of complexity, because to check something like "`A | B` is a subtype of `C | D`", you would need to check whether "`A` is a subtype of
C
and
B
is a subtype of `D`", or "`A` is a subtype of
D
and
B
is a subtype of
C
". A few steps later and you have a very large amount of constraints to check... which heavily impact the compiler and the IDE response times.
There are also a few other technical complications, like what is the type of that value in the JVM. Think of something like
String | Int
. Is it a
Comparable<*>
? is it an
Object
(and then we need to box the int)? This feels more surmountable, but still complicated.
The problem becomes much easier if you only admit types of the form
<Normal Type> | <Error>
where
<Error>
is a special kind of type with a few restrictions imposed on those. There will be a talk about how all of this looks at next KotlinConf
https://kotlinconf.com/schedule/?day=2025-05-22&session=a35f03c7-3d57-5874-a20e-8d7518ded091