What you'll learn
Real programs make decisions. Kotlin's control flow has a twist that makes it especially expressive: if and when are expressions — they return values — so you write less and say more.
By the end you'll be able to:
- Use
ifas both a statement and a value-returning expression - Harness the powerful
whenexpression - Match on values, ranges, types, and arbitrary conditions
- Loop with
forandwhile
if as an expression
In Kotlin, if doesn't just choose which code to run — it returns a value. That means you can assign its result directly to a variable. A happy consequence: Kotlin has no separate ternary operator, because if/else already fills that role concisely:
val score = 82
// 'if' is an EXPRESSION — it returns a value
val grade = if (score >= 90) "A"
else if (score >= 80) "B"
else "F"
println(grade) // B
// so Kotlin has no separate ternary — 'if' IS the ternary
val max = if (5 > 3) 5 else 3
println(max) // 5The when expression
when is Kotlin's supercharged replacement for the switch statement — and it's an expression too. It can match against literal values, ranges, types (with smart casts), and even arbitrary conditions when used without an argument:
1 -> ...
match a literal value
in 4..5 -> ...
match a range
is String -> ...
match a type (with smart cast)
temp > 30 -> ...
match any condition (no argument)
val day = 3
val name = when (day) { // 'when' as an expression
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
in 4..5 -> "Later in the week"
else -> "Weekend"
}
println(name) // WednesdayMatching on types pairs beautifully with smart casts (Module 4):
fun describe(x: Any) = when (x) {
is Int -> "an int: ${x}"
is String -> "a string of length ${x.length}"
else -> "something else"
}
println(describe(42))
println(describe("hi"))And with no argument, each branch is a boolean condition — a clean if/else-if chain:
val temp = 30
val advice = when { // no argument — like an if/else chain
temp > 30 -> "Too hot"
temp < 10 -> "Too cold"
else -> "Just right"
}
println(advice) // Just rightwhen must be exhaustive as an expression
when to return a value, it must cover every case — usually with an else. This compiler check means you can never forget a case, which becomes a superpower with sealed classes (Module 18).Loops
Kotlin's for is a "for each" loop — it iterates over ranges, collections, or anything iterable. There's no C-style index loop; you use ranges instead. while and do-while work as you'd expect:
for (i in 1..3) {
println("Count $i")
}
for (fruit in listOf("apple", "banana")) { // for-each over a collection
println(fruit)
}
var n = 3
while (n > 0) {
print(n)
n--
}Tip
for ((index, value) in list.withIndex()) — the Kotlin equivalent of Python's enumerate.Recap & quick check
Key takeaways
- if is an expression that returns a value — so Kotlin has no separate ternary operator.
- when is a powerful switch that's also an expression.
- when can match values, ranges (in 4..5), types (is String, with smart cast), or conditions (no argument).
- As a value-returning expression, when must be exhaustive (usually via else).
- for is a for-each over ranges/collections; use withIndex() for the index.
Quick check
1. Why does Kotlin have no ternary operator (?:)... for conditionals?
2. What is 'when' most like from other languages?
3. How can a 'when' branch match a range?
4. When used as an expression, a 'when' must be…
5. How does Kotlin's for loop work?
Nicely done. Next up: Module 6 — Functions, where you'll package logic into reusable pieces.