Nothing Is a Type: How Kotlin's Bottom Type Eliminates '!!' in Android Code
Declaring throw-only helpers as : Nothing trades '!!' for smart casts, eliminating a class of null-safety boilerplate and letting the compiler verify which code paths never return.
Kotlin's type system places Any at the top of all non-null types, Unit in the middle as a type whose only value indicates 'done, no result', and Nothing at the very bottom as a subtype of every type. Nothing expresses code that never finishes normally: functions that always throw, expressions like error() or TODO(), and the throw keyword itself.
On Android, this matters in practice. A helper that always throws can be declared with return type Nothing, and the compiler then knows the subsequent code is unreachable when that helper is called along a null-check path. That turns a null-check failure into a smart cast, so developers stop sprinkling '!!' throughout the code. UiState<Nothing> in sealed interfaces work because Nothing is a subtype of every type, letting an empty loading state be assigned to any generic state parameter.
Unit is a real type with a single instance, unlike Java's void keyword. That allows it to appear in generics and function types like () -> Unit, in Result<Unit>, and in MutableSharedFlow<Unit> to emit events without payloads. On the JVM, ordinary Unit functions compile to void, so there's no runtime overhead. The practical takeaway: knowing where these three types sit in the ladder lets you write code that communicates intent to both humans and the compiler.
Nothing's real payoff is compiler flow analysis: once a function's return type is Nothing, every call site becomes a source of unreachable-code information, which is why Kotlin can reason about nullability without runtime checks.
Unit being a type instead of a keyword is what enables Kotlin's function type syntax and event patterns; Java developers have to fake it with Void and null returns.
The UiState<Nothing> example shows the bottom type isn't just an academic curiosity; it directly enables a single Loading object to be reused across all generic state types.