```interface Foo class A(val a: String?) : Foo cla...
# getting-started
c
Copy code
interface Foo
class A(val a: String?) : Foo
class B(val b: String) : Foo

val f = listOf(A("1"), A("2"), B("3"))

val d = f.mapNotNull {
    when (it) {
        is A -> it.a
        is B -> it.b
    }
}
Without looking it up, what do you think is the type of
d
?
very nice 2
s
List<String?>
?
c
Nope,
List<Unit>
🤡
💯 2
🤦 1
It's
List<String>
if you make
Foo
sealed
👍 1
s
Or if you make
when
exhaustive?
c
Yes
If you add an
else
, it's
List<String>
too
Just a bit of weirdness I found
s
Yeah makes sense 🙂
c
It does, but I can see people from other languages clowning on us for that 😅
😅 1
j
Is it because there is no explicit
return
? Without it the compiler is maybe auto inserting
Unit
?
c
Yes, because the
when
is not exhaustive it's an instruction and not an expression, and a lambda that ends with an instruction returns
Unit
j
a lambda that ends with an instruction returns
Unit
TIL
y
At least return value checking will warn/error on this lol
👍 2
s
so my first reaction to understanding that the issue is that the when-expression is non-exhaustive, was that "well, you could check at compile-time that A and B are all implementations of Foo, but that would be very implicit which is not very Kotlin-y", but then I remembered "actually, the JDK can load new classes at runtime, and those classes might implement Foo as well, so it would be false to assume that the when-expression is exhaustive".
c
That, but a much simpler case is: I'm writing a module that is a dependency of another one, and that one has a new class of that interface