0
0
Kotlinprogramming~15 mins

Why expressions over statements matters in Kotlin - Why It Works This Way

Choose your learning style9 modes available
Overview - Why expressions over statements matters
What is it?
In Kotlin, expressions produce a value and can be used wherever a value is expected, while statements perform actions but do not return values. Choosing expressions over statements means writing code that is more concise, flexible, and easier to combine. This approach helps developers write clearer and more powerful programs by treating almost everything as a value.
Why it matters
Using expressions instead of statements allows developers to write code that is more readable and less error-prone. It enables chaining operations, reduces the need for temporary variables, and supports functional programming styles. Without this concept, code tends to be longer, harder to maintain, and less adaptable to change.
Where it fits
Before learning this, you should understand basic Kotlin syntax, variables, and control flow. After mastering expressions over statements, you can explore advanced functional programming concepts, such as lambdas, higher-order functions, and immutability.
Mental Model
Core Idea
Treating code as expressions that produce values makes programs more flexible, concise, and composable.
Think of it like...
It's like cooking with ingredients (expressions) that you can mix and reuse in many recipes, instead of just following fixed steps (statements) that don't leave you with reusable parts.
┌───────────────┐       ┌───────────────┐
│   Statement   │       │   Expression  │
│ (does action) │       │ (produces val)│
└──────┬────────┘       └──────┬────────┘
       │                       │
       │                       │
       ▼                       ▼
  No value produced       Value produced
       │                       │
       │                       │
  Harder to combine     Can be combined
  and reuse code        and reused code
Build-Up - 7 Steps
1
FoundationUnderstanding Statements in Kotlin
🤔
Concept: Statements perform actions but do not return values.
In Kotlin, a statement is a line of code that does something, like assigning a value or printing text. For example: val x = 5 // assignment statement println(x) // print statement These lines do actions but don't themselves produce a value you can use elsewhere.
Result
The program runs the actions but you cannot use these lines as values in expressions.
Knowing what statements do helps you see their limits in building flexible code.
2
FoundationUnderstanding Expressions in Kotlin
🤔
Concept: Expressions produce values and can be used wherever values are needed.
An expression is any piece of code that results in a value. For example: val y = 3 + 4 // '3 + 4' is an expression producing 7 You can use expressions inside other expressions, like: val z = (3 + 4) * 2 Here, '(3 + 4)' produces 7, then multiplied by 2 to get 14.
Result
Expressions allow you to build complex values by combining smaller ones.
Recognizing expressions lets you write code that is more compact and composable.
3
IntermediateUsing if as an Expression
🤔Before reading on: do you think Kotlin's if can return a value like an expression? Commit to your answer.
Concept: In Kotlin, if can be used as an expression that returns a value, unlike many other languages where it's only a statement.
In many languages, if is only a statement: if (x > 0) { y = 1 } else { y = -1 } In Kotlin, if can return a value: val y = if (x > 0) 1 else -1 This means you can assign the result of if directly to a variable.
Result
Code becomes shorter and clearer by using if as an expression.
Understanding this unlocks more concise control flow and reduces boilerplate.
4
IntermediateUsing when as an Expression
🤔Before reading on: do you think Kotlin's when can be used as an expression returning a value? Commit to your answer.
Concept: Kotlin's when is a powerful control structure that can be used as an expression to produce values.
The when expression lets you choose a value based on conditions: val result = when (x) { 1 -> "one" 2 -> "two" else -> "other" } This assigns a string based on x's value, all in one expression.
Result
Using when as an expression simplifies multi-branch logic and value assignment.
Knowing when returns values helps write clearer, more functional-style code.
5
IntermediateFunctions as Expressions
🤔
Concept: Functions in Kotlin can be expressions that return values, enabling chaining and composition.
Every function returns a value (or Unit if nothing meaningful). For example: fun square(x: Int) = x * x You can use this in expressions: val result = square(5) + 10 Functions as expressions let you build complex calculations cleanly.
Result
Functions become building blocks for expressions, improving modularity.
Seeing functions as expressions encourages writing reusable, composable code.
6
AdvancedBenefits of Expressions in Functional Style
🤔Before reading on: do you think using expressions supports functional programming benefits like immutability and chaining? Commit to your answer.
Concept: Expressions enable functional programming patterns such as chaining calls and avoiding side effects.
Because expressions produce values, you can chain them: val result = listOf(1, 2, 3) .map { it * 2 } .filter { it > 3 } .sum() Each step returns a new value without changing the original list, making code safer and easier to reason about.
Result
Code becomes more predictable, testable, and concise.
Understanding expressions is key to adopting modern, functional programming styles.
7
ExpertExpression-Oriented Design and Compiler Optimization
🤔Before reading on: do you think expression-oriented code helps the compiler optimize better? Commit to your answer.
Concept: Writing code as expressions allows Kotlin's compiler to optimize and inline code more effectively, improving performance.
Because expressions produce values and avoid side effects, the compiler can analyze and rearrange code safely. For example, it can inline small functions or remove unused computations. This leads to faster and smaller bytecode. Also, expression-oriented code reduces branching and temporary variables, which helps the compiler generate efficient machine code.
Result
Expression-oriented code not only improves readability but also runtime performance.
Knowing this explains why Kotlin encourages expressions and how it benefits both developers and users.
Under the Hood
Kotlin treats expressions as code units that return values, enabling them to be nested and combined. The compiler represents expressions as abstract syntax trees that can be optimized and transformed. Statements are treated as expressions returning Unit, allowing uniform handling. This design supports functional programming features and enables better static analysis and optimization.
Why designed this way?
Kotlin was designed to improve on Java by making code more concise and expressive. Using expressions over statements reduces boilerplate and aligns with functional programming trends. This design choice helps Kotlin support safer, more readable, and more maintainable code, while still interoperating with Java.
┌───────────────┐
│   Expression  │
│  (returns val)│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│   Compiler    │
│  Optimization │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│  Bytecode /   │
│  Machine Code │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do you think all if statements in Kotlin are just statements and cannot return values? Commit to yes or no.
Common Belief:If in Kotlin is only a statement and cannot be used as a value.
Tap to reveal reality
Reality:In Kotlin, if is an expression that returns a value and can be assigned or used inside other expressions.
Why it matters:Believing this limits your ability to write concise and clear conditional code, leading to unnecessary verbosity.
Quick: Do you think expressions always make code harder to read? Commit to yes or no.
Common Belief:Using expressions everywhere makes code complex and confusing.
Tap to reveal reality
Reality:Expressions, when used well, make code more readable, concise, and easier to maintain by reducing boilerplate and clarifying intent.
Why it matters:Avoiding expressions due to this misconception causes longer, repetitive code that is harder to debug.
Quick: Do you think statements and expressions are completely separate and cannot overlap in Kotlin? Commit to yes or no.
Common Belief:Statements and expressions are totally different and cannot be mixed in Kotlin.
Tap to reveal reality
Reality:In Kotlin, statements are a subset of expressions; even statements return Unit, making the language expression-oriented.
Why it matters:Not understanding this leads to confusion about Kotlin's syntax and missed opportunities for writing elegant code.
Quick: Do you think expression-oriented code always runs slower than statement-based code? Commit to yes or no.
Common Belief:Expression-oriented code is less efficient and slower at runtime.
Tap to reveal reality
Reality:Expression-oriented code often enables better compiler optimizations, resulting in equal or better performance.
Why it matters:Avoiding expressions for performance reasons can prevent you from writing modern, efficient Kotlin code.
Expert Zone
1
Expressions returning Unit unify Kotlin's syntax, allowing statements to be treated as expressions, which simplifies language parsing and tooling.
2
Using expressions enables better type inference and reduces the need for explicit type declarations, improving developer experience.
3
Expression-oriented design facilitates coroutine support and asynchronous programming by allowing suspension points within expressions.
When NOT to use
Expression-oriented style is less suitable when side effects dominate or when imperative step-by-step debugging is needed. In such cases, traditional statements or imperative code may be clearer. Also, for very simple scripts or beginners, statements might be easier to understand initially.
Production Patterns
In production Kotlin code, expressions are used extensively in DSLs, builder patterns, and reactive programming. For example, Kotlin's standard library uses expression-based functions like map, filter, and fold to process collections concisely and efficiently.
Connections
Functional Programming
Expressions are the foundation of functional programming, enabling pure functions and immutability.
Understanding expressions helps grasp functional programming concepts like function composition and side-effect-free code.
Mathematics - Algebraic Expressions
Programming expressions mirror algebraic expressions that combine values and operations to produce results.
Recognizing this connection clarifies how code evaluates and combines values systematically.
Cooking Recipes
Like combining ingredients (expressions) to create dishes, programming expressions combine values to produce results.
This cross-domain link shows how building blocks can be combined flexibly to create complex outcomes.
Common Pitfalls
#1Using if only as a statement, missing its expression power.
Wrong approach:if (x > 0) { y = 1 } else { y = -1 }
Correct approach:val y = if (x > 0) 1 else -1
Root cause:Not knowing that if in Kotlin returns a value and can be used as an expression.
#2Writing verbose code with temporary variables instead of chaining expressions.
Wrong approach:val doubled = list.map { it * 2 } val filtered = doubled.filter { it > 3 } val sum = filtered.sum()
Correct approach:val sum = list.map { it * 2 }.filter { it > 3 }.sum()
Root cause:Not leveraging expressions to compose operations fluently.
#3Treating statements and expressions as completely separate, causing confusion in Kotlin syntax.
Wrong approach:fun example() { val x = 5 if (x > 0) println("Positive") // Cannot use if as expression }
Correct approach:fun example() { val message = if (x > 0) "Positive" else "Non-positive" println(message) }
Root cause:Misunderstanding Kotlin's expression-oriented design.
Key Takeaways
Kotlin treats most code as expressions that produce values, making programs more concise and flexible.
Using expressions over statements enables chaining, reduces boilerplate, and supports functional programming styles.
Control structures like if and when are expressions in Kotlin, allowing direct value assignment and clearer code.
Expression-oriented design helps the compiler optimize code better, improving performance and maintainability.
Understanding this concept is essential for writing modern, idiomatic Kotlin code that is both readable and efficient.