0
0
Kotlinprogramming~15 mins

When as expression returning value in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - When as expression returning value
What is it?
In Kotlin, the 'when' construct is a powerful tool that can be used as an expression to return a value. Unlike traditional switch statements in other languages, 'when' can evaluate multiple conditions and directly produce a result that can be assigned to a variable or used in expressions. This makes code more concise and readable by combining condition checking and value assignment in one step.
Why it matters
Using 'when' as an expression simplifies decision-making in code by reducing boilerplate and improving clarity. Without it, developers would need separate if-else chains or switch statements that don't return values, leading to more verbose and error-prone code. This feature helps write cleaner, safer, and more maintainable programs.
Where it fits
Before learning 'when' as an expression, you should understand basic Kotlin syntax, variables, and control flow like if-else statements. After mastering this, you can explore more advanced Kotlin features like sealed classes, smart casts, and functional programming concepts that often use 'when' expressions.
Mental Model
Core Idea
'When' in Kotlin is like a smart decision-maker that evaluates conditions and hands you back the answer directly.
Think of it like...
Imagine you ask a friend to pick a snack based on your mood. Instead of telling them all the rules and then waiting for their choice, you just say your mood, and they immediately hand you the perfect snack. The 'when' expression works the same way: you give it a condition, and it instantly returns the matching result.
┌───────────────┐
│   when(value) │
├───────────────┤
│ condition 1 ->│ result 1
│ condition 2 ->│ result 2
│ else       -> │ default result
└───────────────┘

Usage:
result = when(value) {
  condition1 -> result1
  condition2 -> result2
  else -> defaultResult
}
Build-Up - 7 Steps
1
FoundationBasic when syntax and usage
🤔
Concept: Introduces the basic structure of 'when' as a control flow statement.
The 'when' keyword checks a value against multiple conditions. Each condition is followed by '->' and the code to run if it matches. For example: val x = 2 when (x) { 1 -> println("One") 2 -> println("Two") else -> println("Other") } This prints 'Two' because x equals 2.
Result
Output: Two
Understanding the basic syntax is essential before using 'when' as an expression that returns values.
2
FoundationUsing when as a statement vs expression
🤔
Concept: Shows the difference between 'when' used just for actions and 'when' returning a value.
By default, 'when' can be used as a statement to run code blocks. But it can also return a value, which you can assign to a variable: val x = 3 val result = when (x) { 1 -> "One" 2 -> "Two" else -> "Unknown" } println(result) This prints 'Unknown'.
Result
Output: Unknown
Recognizing that 'when' can produce a value lets you write cleaner code by combining condition checks and assignments.
3
IntermediateMultiple conditions in when branches
🤔Before reading on: Do you think 'when' can check multiple values in one branch or only one? Commit to your answer.
Concept: Explains how to check multiple conditions in a single 'when' branch using commas.
You can test several values in one branch by separating them with commas: val x = 5 val result = when (x) { 1, 3, 5 -> "Odd small number" 2, 4, 6 -> "Even small number" else -> "Other number" } println(result) This prints 'Odd small number' because x is 5.
Result
Output: Odd small number
Knowing that multiple conditions can share one result reduces repetition and makes code more concise.
4
IntermediateUsing when without argument for complex conditions
🤔Before reading on: Can 'when' be used without a value to check arbitrary conditions? Commit to yes or no.
Concept: Shows that 'when' can be used without an argument to evaluate boolean expressions directly.
Instead of checking a single value, you can write: val x = 10 val result = when { x < 5 -> "Less than five" x in 5..10 -> "Between five and ten" else -> "More than ten" } println(result) This prints 'Between five and ten'.
Result
Output: Between five and ten
Using 'when' without an argument allows flexible condition checks, similar to if-else chains but more readable.
5
AdvancedSmart casts and type checking in when
🤔Before reading on: Do you think 'when' can automatically cast types after checking? Commit to yes or no.
Concept: Demonstrates how 'when' can check types and smart cast variables inside branches.
Kotlin can check the type of a variable and let you use it as that type inside the branch: fun describe(obj: Any): String = when (obj) { is String -> "String of length ${obj.length}" is Int -> "Integer value $obj" else -> "Unknown type" } println(describe("Hello")) println(describe(42)) Outputs: String of length 5 Integer value 42
Result
Output: String of length 5 Integer value 42
Understanding smart casts in 'when' helps write safer code without explicit casting.
6
AdvancedExhaustive when expressions and compiler checks
🤔Before reading on: Does Kotlin require 'when' expressions to cover all cases? Commit to yes or no.
Concept: Explains that when used as an expression, 'when' must be exhaustive, meaning all possible cases are handled.
If you use 'when' as an expression (returning a value), Kotlin forces you to cover all cases or provide an 'else' branch: fun getColorName(color: Color) = when (color) { Color.RED -> "Red" Color.GREEN -> "Green" Color.BLUE -> "Blue" // No else needed because all enum cases covered } If a case is missing, the compiler shows an error. This helps prevent bugs from unhandled cases.
Result
Compiler error if cases are missing; safe code if exhaustive.
Knowing about exhaustiveness ensures your code handles all possibilities, reducing runtime errors.
7
ExpertWhen expression performance and bytecode behavior
🤔Before reading on: Do you think Kotlin's 'when' compiles to a simple jump table like Java's switch? Commit to yes or no.
Concept: Explores how Kotlin compiles 'when' expressions under the hood and their performance implications.
Kotlin compiles 'when' differently depending on the cases: - For enums and constants, it often generates efficient jump tables like Java's switch. - For complex conditions or type checks, it compiles to if-else chains. Understanding this helps optimize performance-critical code by choosing appropriate 'when' usage. Example: Using enums in 'when' is faster than arbitrary conditions.
Result
Efficient bytecode for enums; less efficient for complex conditions.
Knowing compilation details helps write performant Kotlin code and avoid surprises in critical paths.
Under the Hood
The Kotlin compiler transforms 'when' expressions into bytecode that either uses jump tables for simple constant matches or chains of conditional checks for complex cases. When used as an expression, the compiler ensures all branches return a value, enforcing exhaustiveness. Smart casts inside 'when' branches rely on Kotlin's flow analysis to safely treat variables as specific types after checks.
Why designed this way?
Kotlin's 'when' was designed to be more powerful and flexible than traditional switch statements, combining pattern matching, type checking, and expression capabilities. This design reduces boilerplate and increases safety. The exhaustiveness requirement prevents bugs from missing cases, a common problem in other languages. The compiler optimizes simple cases for performance while supporting complex logic.
┌───────────────┐
│   when(value) │
├───────────────┤
│  Match enum?  ├─Yes─> Jump table bytecode
│               │
│  Complex cond?├─Yes─> if-else chain bytecode
│               │
│  Type check?  ├─Yes─> Smart cast enabled
│               │
│  Exhaustive?  ├─Compiler enforces all cases
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does 'when' always require an 'else' branch? Commit to yes or no.
Common Belief:Many think 'when' always needs an 'else' branch to compile.
Tap to reveal reality
Reality:If 'when' covers all possible cases (like all enum values), Kotlin does not require 'else'.
Why it matters:Adding unnecessary 'else' branches can hide missing cases and reduce code safety.
Quick: Is 'when' just a fancy if-else chain? Commit to yes or no.
Common Belief:Some believe 'when' is just syntactic sugar for if-else statements.
Tap to reveal reality
Reality:'When' is more powerful: it supports multiple conditions per branch, type checks, and is an expression returning values.
Why it matters:Underestimating 'when' limits its use and misses opportunities for clearer, safer code.
Quick: Does Kotlin's 'when' always compile to a jump table? Commit to yes or no.
Common Belief:People often assume 'when' compiles like Java's switch with jump tables for all cases.
Tap to reveal reality
Reality:Only simple constant or enum matches compile to jump tables; complex conditions compile to if-else chains.
Why it matters:Misunderstanding this can lead to performance surprises in critical code.
Quick: Can 'when' smart cast variables automatically? Commit to yes or no.
Common Belief:Some think 'when' does not smart cast variables after type checks.
Tap to reveal reality
Reality:'When' supports smart casts, letting you use variables as their checked types inside branches without explicit casts.
Why it matters:Not knowing this leads to unnecessary casting and verbose code.
Expert Zone
1
When used as an expression, 'when' must be exhaustive, but this exhaustiveness is checked by the compiler only for sealed classes and enums, not for all types.
2
Smart casts inside 'when' branches depend on Kotlin's flow analysis and can fail if variables are mutable or changed elsewhere, requiring careful code structure.
3
The order of branches in 'when' matters for performance and correctness, especially when using complex conditions or overlapping cases.
When NOT to use
Avoid using 'when' for very simple true/false checks where if-else is clearer. For complex pattern matching beyond 'when's capabilities, consider sealed classes with polymorphism or functional constructs like 'fold'.
Production Patterns
In production, 'when' expressions are commonly used for handling UI states, parsing input commands, and mapping enums to values. Developers often combine 'when' with sealed classes to ensure exhaustive handling of all cases, improving code safety and maintainability.
Connections
Pattern Matching in Functional Programming
'When' builds on the idea of pattern matching found in functional languages like Haskell or Scala.
Understanding 'when' as pattern matching helps grasp its power to concisely handle multiple cases and types, a concept used widely in functional programming.
Switch Statements in Java
'When' is Kotlin's more powerful and flexible alternative to Java's switch statement.
Knowing Java's switch helps appreciate how Kotlin improves on it by supporting expressions, multiple conditions, and type checks.
Decision Making in Human Psychology
'When' mirrors how humans make decisions by evaluating conditions and choosing outcomes.
Recognizing this connection shows how programming constructs model real-world thinking processes, aiding intuitive understanding.
Common Pitfalls
#1Forgetting to cover all cases in a 'when' expression, causing compiler errors.
Wrong approach:val result = when (color) { Color.RED -> "Red" Color.GREEN -> "Green" // Missing Color.BLUE and no else }
Correct approach:val result = when (color) { Color.RED -> "Red" Color.GREEN -> "Green" Color.BLUE -> "Blue" }
Root cause:Not understanding that 'when' expressions must be exhaustive to compile.
#2Using 'when' without an 'else' branch when cases are not exhaustive.
Wrong approach:val x = 10 val result = when (x) { 1 -> "One" 2 -> "Two" // No else branch }
Correct approach:val x = 10 val result = when (x) { 1 -> "One" 2 -> "Two" else -> "Other" }
Root cause:Misunderstanding exhaustiveness requirements for non-enum or open types.
#3Trying to use 'when' as a statement but expecting a return value.
Wrong approach:when (x) { 1 -> "One" 2 -> "Two" } val result = x // result is not assigned from when
Correct approach:val result = when (x) { 1 -> "One" 2 -> "Two" else -> "Other" }
Root cause:Confusing 'when' statement usage with expression usage.
Key Takeaways
'When' in Kotlin is a versatile expression that evaluates conditions and returns values, making code concise and readable.
It supports multiple conditions per branch, type checking with smart casts, and requires exhaustiveness when used as an expression.
Understanding how 'when' compiles helps write efficient and safe code, especially with enums and sealed classes.
Avoid common mistakes like missing cases or confusing statement vs expression usage to prevent bugs and compiler errors.
Mastering 'when' unlocks powerful Kotlin patterns for clean decision-making and safer code.