Unlike Java or C, Kotlin's if can be used as an expression, directly producing a value from whichever branch runs — this is precisely why Kotlin has no separate ternary operator; if already covers that case. when replaces switch entirely and is considerably more capable: a single when can match exact values, ranges (in 1..10), types (is String), or arbitrary boolean conditions, and like if, it can also be used as an expression that produces a value directly.
if as an expression: no ternary operator needed
Both branches must be present when if is used as an expression (unlike as a statement, where else is optional) — the compiler needs a value from every possible path.
val age = 20
val category = if (age >= 18) "adult" else "minor" // if directly PRODUCES a value
println(category) // "adult"when: matching values, ranges, and types in one construct
A single when block handles an exact value, a range check, and a type check together — something that would need three genuinely different constructs in most other languages.
fun describe(x: Any): String = when (x) {
1 -> "exactly one" // exact value match
in 2..10 -> "between 2 and 10" // range match
is String -> "it's a string: $x" // type match, with smart-cast x to String inside
else -> "something else"
}
println(describe(5)) // "between 2 and 10"
println(describe("hi")) // "it's a string: hi"for and while: familiar, with Kotlin's range syntax
1..5 is inclusive of both ends; 1 until 5 excludes the upper bound — a small but genuinely useful distinction for avoiding off-by-one errors when the exclusive form is what's actually needed.
for (i in 1..5) { // inclusive: 1, 2, 3, 4, 5
print(i)
}
println()
for (i in 1 until 5) { // exclusive of 5: 1, 2, 3, 4
print(i)
}
println()
var n = 0
while (n < 3) {
n++
}