In Kotlin's function model, what do `Unit` and `Nothing` mean as return types, and how does an expression-body function differ from a block-body one?
answer
- Unit = void-like, one instance, optional annotation
- Nothing = bottom type, no instances, never returns
- Nothing is subtype of every type -> reachability
- Expression body: = expr, type inferred
- Block body: { } + return, explicit type
basics
~20 sUnit is the return type for functions that do something but have no useful result (like Java's void). Nothing means the function never returns normally (it always throws or loops). An expression-body function uses = and infers its type; a block-body uses { } and return.
solid answer
~50 sEvery Kotlin function returns a value. **`Unit`** is a real type with a single instance, returned by functions with no meaningful result — declaring `: Unit` is optional. **`Nothing`** is the bottom type with **no instances**; a function typed `Nothing` never completes normally — it always throws or loops forever (e.g. `fun fail(): Nothing = throw ...`). Because `Nothing` is a subtype of every type, the compiler uses it for control-flow analysis: after a `Nothing`-returning call, code is unreachable, and `Nothing?` is the type of `null`. **Expression-body** functions use `=` and can infer the return type: `fun double(x: Int) = x * 2`. **Block-body** functions use braces and require explicit `return` (and an explicit return type unless it's `Unit`): `fun double(x: Int): Int { return x * 2 }`. Expression bodies are concise for single-expression logic; block bodies suit multi-statement logic.
code
kotlin · 8 linesfun parsePort(raw: String?): Int =
raw?.toIntOrNull() ?: fail("bad port: $raw") // fail returns Nothing
fun fail(msg: String): Nothing = throw IllegalArgumentException(msg)
fun greet(name: String) { // block body, returns Unit implicitly
println("Hi, $name")
}go deeper
Knows Unit is the void-like return and expression vs block syntax.
Explains Nothing as 'never returns' and uses TODO()/error() correctly.
Articulates Nothing as the bottom type subtyping all types and its role in reachability and inference, plus expression-body type inference rules.
Reasons about public-API inferred-type contracts, exhaustiveness/control-flow guarantees, and Nothing in generic variance and DSL signatures.
## Everything returns something Kotlin has no `void`. Every function returns a value, even side-effecting ones — they return `Unit`. ## Unit **`Unit`** is an ordinary type with exactly **one value**, also written `Unit` (a singleton object). A function that does work but yields nothing useful returns it; the annotation is optional: ```kotlin fun log(msg: String): Unit { println(msg) } // ': Unit' can be omitted fun log2(msg: String) = println(msg) // also Unit (println returns Unit) ``` Because `Unit` is a real type, function types can mention it: `() -> Unit`, and lambdas with `Unit` result don't need a `return`. ## Nothing **`Nothing`** is the **bottom type**: it has **no instances** and is a **subtype of every other type**. A function returning `Nothing` *never returns normally* — it throws or loops forever: ```kotlin fun fail(message: String): Nothing = throw IllegalStateException(message) ``` Why it matters: - **Reachability**: the compiler knows code after a `Nothing` call is unreachable, so `val x = obj ?: fail("missing")` lets `x` be smart-cast to non-null — the right side never produces a value. - **Type inference glue**: because `Nothing` is below every type, `throw` and `return` expressions can appear where any type is expected. `Nothing?` is the type of the literal `null`. - **Empty collections / TODO**: `emptyList<T>()` and `TODO()` (which returns `Nothing`) exploit this. ```kotlin val port: Int = config["port"]?.toInt() ?: error("no port") // error() returns Nothing ``` ## Expression body vs. block body **Expression-body** function: `=` followed by a single expression; the return type can be **inferred**: ```kotlin fun area(r: Double) = Math.PI * r * r // type Double inferred fun sign(n: Int) = if (n >= 0) "+" else "-" // if is an expression ``` **Block-body** function: braces with statements; you must use `return`, and you must declare the return type **unless** it is `Unit`: ```kotlin fun area(r: Double): Double { // explicit type required here val pi = Math.PI return pi * r * r } ``` Guidance: prefer expression bodies for single-expression functions (often combined with `when`/`if` expressions); use block bodies when you need multiple statements or local variables. Note: omitting the explicit return type on a **public API** expression body is discouraged because the inferred type becomes part of the contract.
- Why can `obj ?: throw ...` smart-cast obj to non-null afterward?The throw expression has type Nothing, so the elvis right side never yields a value; if execution continues, obj must have been non-null.
- Must you declare the return type on a block-body function?Yes, unless it returns Unit. Block bodies don't infer the return type; only expression bodies do.
Unit is a receipt that says 'done, nothing to hand back'; Nothing is a one-way door — once a function steps through it (throw/loop), it never comes back to give you anything.
saying these in an interview costs you the question
- Thinking Unit and Nothing are the same / both mean 'void'
- Saying Nothing has instances or can be returned normally
- Believing block-body functions infer their return type
- Not knowing Nothing enables reachability/smart-cast
- Forgetting Unit is a real type usable in function types