0
0
Kotlinprogramming~15 mins

Also function behavior and use cases in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Also function behavior and use cases
What is it?
The 'also' function in Kotlin is a special tool that lets you run some extra code on an object and then return the original object itself. It is often used to perform side actions like logging or modifying the object without changing the flow of the program. This helps keep code clean and easy to read by chaining operations smoothly.
Why it matters
Without 'also', you might write extra lines just to do small tasks like printing or updating an object, which can clutter your code. 'Also' lets you insert these tasks right inside chains of commands, making your code shorter and clearer. This improves productivity and reduces mistakes in real projects.
Where it fits
Before learning 'also', you should understand Kotlin basics like variables, functions, and lambda expressions. After mastering 'also', you can explore other Kotlin scope functions like 'let', 'apply', 'run', and 'with' to write more expressive and concise code.
Mental Model
Core Idea
'Also' lets you peek at or change an object while keeping it unchanged in the chain of actions.
Think of it like...
Imagine you are walking with a friend carrying a box. You want to quickly check or add a sticker on the box without stopping or taking it away from your friend. 'Also' is like that quick check or sticker — it happens alongside the main action without interrupting it.
Object ──▶ also { side action } ──▶ returns original Object

Flow:
┌─────────────┐      ┌───────────────┐      ┌───────────────┐
│ Original    │ ──▶ │ also block    │ ──▶ │ Same Original │
│ Object      │      │ (side action) │      │ Object        │
└─────────────┘      └───────────────┘      └───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Kotlin Lambdas
🤔
Concept: Learn what lambdas are and how to use them as blocks of code passed to functions.
In Kotlin, a lambda is a small function without a name that you can pass around. For example: val greet = { name: String -> println("Hello, $name!") } greet("Alice") This prints 'Hello, Alice!'. Lambdas let you write code blocks that can be reused or passed to other functions.
Result
You can create and call lambdas to run code snippets easily.
Understanding lambdas is key because 'also' uses a lambda to run extra code on an object.
2
FoundationWhat is a Scope Function?
🤔
Concept: Scope functions let you run code blocks with an object as context, simplifying code that works with that object.
Kotlin has special functions like 'let', 'apply', and 'also' that let you write code blocks where you can access an object directly. For example: val text = "hello" text.let { println(it.uppercase()) } This prints 'HELLO'. The object 'text' is passed into the lambda as 'it'.
Result
You can write cleaner code by running blocks with an object context.
Knowing scope functions helps you understand how 'also' fits as a tool to work with objects inside code blocks.
3
IntermediateBasic Usage of 'also' Function
🤔
Concept: 'Also' runs a lambda with the object as 'it' and returns the original object unchanged.
Example: val number = 5 val result = number.also { println("Number is $it") } println(result) Output: Number is 5 5 Here, 'also' prints the number but returns the original number itself.
Result
You see the side action output and keep the original object for further use.
Understanding that 'also' returns the original object allows chaining without breaking the flow.
4
IntermediateUsing 'also' for Side Effects
🤔Before reading on: Do you think 'also' can change the object it is called on? Commit to yes or no.
Concept: 'Also' is mainly for side effects like logging or modifying the object, but it always returns the original object.
Example: val list = mutableListOf(1, 2, 3) list.also { it.add(4) }.also { println(it) } Output: [1, 2, 3, 4] Here, 'also' lets you add an item and then print the list, all while returning the list itself.
Result
You can perform actions on the object and keep using it in a chain.
Knowing 'also' is for side effects helps you decide when to use it instead of other scope functions.
5
IntermediateDifference Between 'also' and 'apply'
🤔Before reading on: Does 'also' use 'this' or 'it' as the lambda receiver? Commit to your answer.
Concept: 'Also' uses 'it' as the lambda argument, while 'apply' uses 'this' as the receiver, affecting how you write code inside the lambda.
Example: val builder = StringBuilder().also { it.append("Hello") } val builder2 = StringBuilder().apply { append("Hello") } In 'also', you use 'it' to refer to the object. In 'apply', you can call methods directly without 'it'.
Result
You understand how to write lambdas differently depending on the scope function.
Recognizing the difference in lambda receivers prevents confusion and errors in code style.
6
AdvancedChaining 'also' for Fluent Side Effects
🤔Before reading on: Can you chain multiple 'also' calls and still get the original object? Commit to yes or no.
Concept: 'Also' returns the original object, so you can chain several 'also' calls to perform multiple side actions in sequence.
Example: val user = User("Alice") .also { println("Created user: ${it.name}") } .also { it.logCreation() } .also { it.sendWelcomeEmail() } Each 'also' runs a side effect but returns the user object for the next call.
Result
You can perform many side actions cleanly without breaking the chain.
Understanding chaining with 'also' helps write readable code with multiple side effects.
7
ExpertInternal Behavior and Performance of 'also'
🤔Before reading on: Do you think 'also' creates a new object or just passes the original? Commit to your answer.
Concept: 'Also' is an inline function that passes the original object to the lambda and returns it without creating new objects, making it efficient.
The 'also' function is defined as: inline fun T.also(block: (T) -> Unit): T { block(this) return this } Because it is inline, the lambda code is inserted directly where 'also' is called, avoiding overhead.
Result
Using 'also' does not slow down your program or create extra objects.
Knowing 'also' is inline explains why it is both convenient and efficient in production code.
Under the Hood
'Also' is an inline extension function on any object type T. It takes a lambda with the object as a parameter named 'it'. When called, it runs the lambda passing the original object, then returns the same object unchanged. Because it is inline, the compiler replaces the call with the lambda code directly, avoiding function call overhead.
Why designed this way?
The design of 'also' aims to provide a simple way to perform side effects on an object without changing it or breaking method chains. Inline functions reduce runtime cost, making 'also' suitable for frequent use in clean, fluent code. Alternatives like 'let' return the lambda result, but 'also' returns the original object to keep chaining easy.
┌───────────────┐
│ Original Obj  │
└──────┬────────┘
       │ calls 'also'
       ▼
┌─────────────────────┐
│ Inline 'also' func   │
│ - runs lambda(block) │
│ - passes Original Obj│
│ - returns Original Obj│
└──────┬──────────────┘
       │
       ▼
┌───────────────┐
│ Same Original │
│ Object        │
└───────────────┘
Myth Busters - 3 Common Misconceptions
Quick: Does 'also' change the object it is called on? Commit to yes or no.
Common Belief:Many think 'also' modifies the object or returns the lambda result.
Tap to reveal reality
Reality:'Also' never changes the object itself unless you do so inside the lambda. It always returns the original object, not the lambda's result.
Why it matters:Assuming 'also' changes the object can lead to bugs where the original object is expected but altered unexpectedly.
Quick: Is 'also' the same as 'apply' in how you access the object inside the lambda? Commit to yes or no.
Common Belief:Some believe 'also' and 'apply' are interchangeable and use 'this' inside both lambdas.
Tap to reveal reality
Reality:'Also' uses 'it' as the lambda parameter, while 'apply' uses 'this' as the receiver, changing how you write code inside.
Why it matters:Mixing these leads to syntax errors or confusing code, especially for beginners.
Quick: Does using many 'also' calls slow down your program significantly? Commit to yes or no.
Common Belief:People often think chaining many 'also' calls adds performance overhead.
Tap to reveal reality
Reality:'Also' is inline, so the compiler optimizes it away, causing no extra runtime cost.
Why it matters:Avoiding 'also' for performance reasons can lead to less readable code unnecessarily.
Expert Zone
1
Using 'also' is ideal for logging or debugging inside chains without breaking the flow or changing the object.
2
Because 'also' returns the original object, it is perfect for chaining side effects but not for transforming data.
3
The choice between 'also' and other scope functions depends on whether you want to access the object as 'it' or 'this', affecting lambda readability.
When NOT to use
'Also' is not suitable when you want to transform an object and use the transformed result next; use 'let' instead. For configuring objects with multiple property assignments, 'apply' is better. Avoid 'also' if you need to change the lambda's return value.
Production Patterns
In real projects, 'also' is commonly used for logging, validation, or side effects during object construction or method chaining. For example, adding debug prints inside a chain of calls or updating mutable objects while keeping the chain intact.
Connections
Fluent Interface Pattern
'Also' supports fluent interfaces by allowing side effects without breaking method chains.
Understanding 'also' helps grasp how fluent APIs maintain readability and flow while performing extra actions.
Functional Programming Side Effects
'Also' provides a controlled way to perform side effects in otherwise functional-style code.
Knowing 'also' clarifies how to balance pure functions with necessary side actions like logging.
Unix Pipe Command Chaining
Like Unix pipes passing output unchanged while running commands, 'also' passes the object unchanged while running code.
This cross-domain link shows how 'also' fits a universal pattern of inserting side actions in a chain without altering the main data.
Common Pitfalls
#1Trying to transform an object inside 'also' and expecting the transformed result.
Wrong approach:val newString = "hello".also { it.uppercase() } println(newString) // prints 'hello', not 'HELLO'
Correct approach:val newString = "hello".let { it.uppercase() } println(newString) // prints 'HELLO'
Root cause:Misunderstanding that 'also' returns the original object, not the lambda's result.
#2Using 'also' and trying to access the object inside lambda as 'this' instead of 'it'.
Wrong approach:val list = mutableListOf(1, 2).also { add(3) } // Error: Unresolved reference 'add'
Correct approach:val list = mutableListOf(1, 2).also { it.add(3) } // Correct
Root cause:Confusing 'also' lambda parameter 'it' with 'apply' receiver 'this'.
#3Avoiding 'also' for side effects fearing performance cost.
Wrong approach:val user = User("Bob") println("Created user: $user") // instead of chaining with also
Correct approach:val user = User("Bob").also { println("Created user: $it") }
Root cause:Not knowing 'also' is inline and optimized, leading to less readable code.
Key Takeaways
'Also' is a Kotlin scope function that runs a lambda with the object as 'it' and returns the original object unchanged.
It is mainly used for side effects like logging or modifying the object while keeping method chains fluent and readable.
'Also' differs from other scope functions by its lambda receiver and return value, which affects how you write and use it.
Because 'also' is inline, it adds no runtime overhead, making it efficient for frequent use in production code.
Choosing the right scope function depends on whether you want to transform the object, configure it, or just perform side actions.