https://kotlinlang.org logo
Title
f

Frankie Murillo

05/19/2023, 12:26 AM
Hello, I have an awaitAll() question, I am passing it two deferred values of type
Deferred<String>
,
Deferred<Boolean>
and am expecting it to return a List, but the result type seems to be of
List<{Comparable<{Boolean & String}> & java.io.Serializable}>
is there something I am missing here?
j

Jacob

05/19/2023, 12:57 AM
There's no such thing as a list[string, boolean]
j

Joffrey

05/19/2023, 1:10 AM
If you really want to have both values typed properly, you can also simply await both of them sequentially. It's not 100% equivalent (because if the second fails quickly you'll still wait for the first to complete, which may be needlessly long), but it does the job much better in terms of types:
val s = stringDeferred.await()
val b = booleanDeferred.await()
If you still want to return them both as one object, use a dedicated data class (or a
Pair<String, Boolean>
) instead of a list. Lists are meant for homogeneous types of items.
f

Frankie Murillo

05/19/2023, 1:29 AM
@Jacob should of said that better meant just a List, with those two item types inserted.
@Joffrey Thank you for the detailed explanation!
j

Jacob

05/19/2023, 1:35 AM
I'm sure you got a list with a string and a boolean but the common interfaces between them is a complicated concatenation of comparable and serializable, and that becomes the type of the list
f

Frankie Murillo

05/19/2023, 1:47 AM
@Jacob Correct, unfortunately the function signature would seem like it would return the same type as the deferred, but it seems that is not that case.
public suspend fun <T> awaitAll(
    vararg deferreds: Deferred<T>
): List<T>
j

Jacob

05/19/2023, 1:49 AM
It returns the same type as the type parameter T.
e

ephemient

05/19/2023, 5:29 AM
T
must be a single type. Kotlin tries to infer the narrowest type (least upper bound) it can: https://kotlinlang.org/spec/type-inference.html#local-type-inference https://kotlinlang.org/spec/kotlin-type-constraints.html#finding-optimal-constraint-system-solution which leads to this intersection type
even without reading the specification directly, you can see that •
String
and
Boolean
are both
Serializable
(on JVM) •
String
is
Comparable<String>
and
Boolean
is
Comparable<Boolean>
, so they are both
Comparable<Boolean & String>
◦ e.g. comparable to something which is simultaneously both a boolean and a string at the same time. no such value exists, but that doesn't matter for typechecking • those are all of the common supertypes of
String
and
Boolean
(other than `Any`/`Object`) • so the least upper bound is
T = Comparable<Boolean & String> & Serializable
you can't actually write that type in code, https://youtrack.jetbrains.com/issue/KT-13108/Denotable-union-and-intersection-types but the compiler can infer it just fine