Can anyone show me place in Kotlin docs (or maybe ...
# getting-started
g
Can anyone show me place in Kotlin docs (or maybe even in Kotlin spec) where full description of deferred assignment usage rules is placed? All I found about deferred assignment is short mention in "Basic syntax" page. But obviously the rules are not trivial...
🤔 1
j
it is trivial deferred assignment only means that a variable isn’t initialized in it’s declaration but at a later point. What’s in the basic syntax is everything for that topic.
g
Well, the question occurred because of unusual usage I just found out:
Copy code
val k: Int

if (...) k = 57
else error("Something bad occured.")

k + 179 // It compiles!
Here it could be OK to throw a compilation error because if you forgive about
error
then
k
is not definitely asssigned (like in some unusual use cases involving Kotlin syntax and Nothing). But it does compiles!
a
the compiler knows that
error
throws and k will always be set if it reaches the last line, so that seems safe to me 🙂
g
@August Lilleaas Well, consider such snippet (sandbox):
Copy code
val kek: Int =
    if (Random.nextBoolean()) 57
    else {
        error("Something bad happened!!!")
        readln()
    }
It does not compile because output type of
else
block is
String
when
Int
is expected although this block never returns any value. So it means sometimes compiler is extra smart (as in my first example) and sometimes it is not (as in this second example). That's what shocked me.
h
In the last sample you will get a warning
readln(): Unreachable code
. So yeah, the data flow analysis should remove unreachable code first, then you should get a better error message. But it will never compile because the types don't match. Although it will always throw at runtime, at compile time the types must match.
e
it's not specific to what you've written. this compiles because
Nothing
is recognized as unreachable,
Copy code
fun foo(): Int {
    TODO()
}
but this does not compile, as all returns must be of the right type.
Copy code
fun foo(): Int {
    TODO()
    return readln()
}
now, this does compile because the unreachable code is ignored,
Copy code
fun foo(): Int {
    TODO()
    readln()
}
but your
if
-
else
is not like this; the last expression is "returned" from the else branch, even if it's unreachable.
K 1
👌 1
g
Thank you, @ephemient! It's another eye opening.