Does anyone know where on the roadmap union types ...
# getting-started
m
Does anyone know where on the roadmap union types are?
c
The youtrack is https://youtrack.jetbrains.com/issue/KT-13108/Denotable-union-and-intersection-types, I don't know if it's in the roadmap yet
m
That's a shame, so the best way to do this is to just accept
Any
and do type checks at runtime?
c
What are you trying to do exactly?
m
I have a class that takes an
initializer
method, but it should either be
(Int) -> Number
or
(Int) -> Complex
. I can't make Complex extend Number as that would cause ambiguity in a lot of the math functions I defined. Since the above isn't possible due to type erasure, I tried making them functional interfaces to have them backed by different types, but this still results in ambiguity according to the compiler, unless I explicitly specify it as
NDArray(2, 2, initializer = NumberInitializer { 0 })
rather than
NDArray(2, 2) { 0 }
.
c
You can either create a sealed class with both options (the closest to what a union would be), or introduce a factory instead of overloading the constructor
m
How would you do the former? I'm not sure I understand. Ideally I would be able to add some shared interface to Number and Complex, but it seems that won't be possible for a variety of reasons.
c
Is
Complex
a type you created?
m
Yes.
c
Copy code
sealed interface SomeCommonName {
    @JvmInline value class Number(val number: kotlin.Number): SomeCommonName
}

class Complex(…) : SomeCommonName {
    // …
}
I'm not mathematician enough to come up with an accurate name for the interface, but you get the idea
m
Unfortunately that still does not work:
c
You have to explicitly call the constructor
m
Hmm, that doesn't sound like a great solution unfortunately
c
test(SomeCommonName.Number(…))
That's why people want proper union types However, now, the signatures don't clash anymore so you can create overloads
j
Why this is not valid for you?
m
Because I cannot add an interface to Number to my knowledge
j
I don’t follow you, an union type doesn’t add a interface to some of the types, until real union types exist you need to use a sealed interface/class
s
You have to explicitly call the constructor
@martmists you do have to call the constructor but there's no runtime overhead (unless you put it in a collection) since it's an inline class.
c
@Stephan Schröder that's not entirely true, as soon as you upcast the value (e.g. here, to the sealed class), it has to be wrapped (so
is
checks etc work). It would be the same with proper unions though.
If you make an overload for each variant however there won't be boxing involved.
s
you're right. thanks for the clarification 👍