0
0
Kotlinprogramming~15 mins

Apply function behavior and use cases in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Apply function behavior and use cases
What is it?
The apply function in Kotlin is a special tool that lets you run a block of code on an object and then return that same object. It helps you set up or change an object’s properties in a clean and easy way. Instead of writing many lines to change an object, apply lets you do it all inside one block.
Why it matters
Without apply, setting up objects can be repetitive and messy, especially when you want to change many properties. Apply makes your code shorter and clearer, which means fewer mistakes and easier reading. It helps programmers write neat code that looks like a natural conversation with the computer.
Where it fits
Before learning apply, you should understand basic Kotlin syntax, how to create and use objects, and lambda expressions. After mastering apply, you can explore other Kotlin scope functions like let, run, also, and with, which offer different ways to work with objects.
Mental Model
Core Idea
Apply lets you configure an object inside a block and then returns the same object for easy chaining or reuse.
Think of it like...
Imagine you have a blank form and a pen. Apply is like sitting down with the form and filling in all the details at once, then handing back the completed form to use or share.
Object
  │
  ▼
┌───────────────┐
│ apply block   │
│  (this = obj) │
│  set props    │
└───────────────┘
  │
  ▼
Same Object (with changes)
Build-Up - 7 Steps
1
FoundationUnderstanding Kotlin Objects
🤔
Concept: Learn what objects are and how to create them in Kotlin.
In Kotlin, an object is an instance of a class. For example: class Person { var name: String = "" var age: Int = 0 } val person = Person() person.name = "Alice" person.age = 25
Result
You create a person object and set its name and age properties.
Knowing how to create and modify objects is the base for using apply to simplify these changes.
2
FoundationBasics of Lambda Expressions
🤔
Concept: Understand how to write and use lambda expressions in Kotlin.
A lambda is a block of code you can pass around and run later. For example: val greet = { name: String -> println("Hello, $name!") } greet("Bob")
Result
The program prints: Hello, Bob!
Lambdas let you write blocks of code that can be used inside functions like apply.
3
IntermediateUsing Apply to Configure Objects
🤔Before reading on: do you think apply returns the object itself or the last expression inside the block? Commit to your answer.
Concept: Learn how apply runs a block on an object and returns the same object after changes.
You can write: val person = Person().apply { name = "Charlie" age = 30 } println(person.name) // Charlie println(person.age) // 30
Result
The person object has name and age set inside apply, and apply returns the same person object.
Understanding that apply returns the original object allows chaining and cleaner initialization.
4
IntermediateDifference Between Apply and Other Scope Functions
🤔Before reading on: do you think apply uses 'this' or 'it' inside its block? Commit to your answer.
Concept: Learn how apply uses 'this' as the context object, unlike some other functions that use 'it'.
In apply, you access properties directly: val list = mutableListOf().apply { add(1) add(2) } In let, you use 'it': val size = list.let { it.size }
Result
Apply uses 'this' so you can call members without prefix; let uses 'it' as the object.
Knowing the context object style helps choose the right scope function for readability.
5
AdvancedChaining Apply for Fluent Configuration
🤔Before reading on: do you think you can chain multiple apply calls on the same object? Commit to your answer.
Concept: Learn that because apply returns the object, you can chain multiple apply calls to configure it step-by-step.
Example: val person = Person() .apply { name = "Dana" } .apply { age = 28 } println(person.name) // Dana println(person.age) // 28
Result
The person object is configured in two steps using chained apply calls.
Chaining apply calls can organize complex setups into clear, separate blocks.
6
AdvancedUsing Apply for Builder Pattern Simplification
🤔
Concept: Apply can replace verbose builder patterns by configuring objects inline.
Instead of: val builder = StringBuilder() builder.append("Hello") builder.append(" World") val result = builder.toString() You can write: val result = StringBuilder().apply { append("Hello") append(" World") }.toString()
Result
The string "Hello World" is built in a concise way.
Apply reduces boilerplate and makes builder-style code more readable.
7
ExpertApply’s Role in DSL and Internal APIs
🤔Before reading on: do you think apply is only for simple property setting or also useful in complex DSLs? Commit to your answer.
Concept: Apply is heavily used in Kotlin DSLs (Domain Specific Languages) to create readable, nested configurations by keeping the object context.
For example, in a UI DSL: val button = Button().apply { text = "Click me" onClick = { println("Clicked") } } This style lets DSLs look like natural language.
Result
Apply enables clean, readable code in complex APIs by keeping the object context inside blocks.
Understanding apply’s use in DSLs reveals its power beyond simple object setup.
Under the Hood
Apply is an extension function on any object that takes a lambda with receiver. Inside the lambda, 'this' refers to the object. The lambda runs with the object as context, allowing direct access to its members. After the lambda executes, apply returns the original object unchanged except for any modifications made inside the block.
Why designed this way?
Apply was designed to simplify object configuration by combining the context of the object and returning it for chaining. This avoids temporary variables and makes code more fluent. Alternatives like let return the lambda result, which is less convenient for chaining object setups.
Object ──▶ apply { block }
  │           │
  ▼           ▼
[Inside block: 'this' = Object]
  │           │
  ▼           ▼
Modified Object ──▶ Returned by apply
Myth Busters - 4 Common Misconceptions
Quick: Does apply return the result of the lambda or the original object? Commit to your answer.
Common Belief:Apply returns the last expression inside the lambda block.
Tap to reveal reality
Reality:Apply always returns the original object it was called on, regardless of the lambda's last expression.
Why it matters:Expecting a different return can cause bugs when chaining calls or assigning results.
Quick: Is 'this' or 'it' used inside apply's lambda? Commit to your answer.
Common Belief:Apply uses 'it' as the object inside the lambda.
Tap to reveal reality
Reality:Apply uses 'this' as the context object, so you access members directly without 'it'.
Why it matters:Using 'it' inside apply leads to errors or confusion about scope.
Quick: Can apply be used to transform the object into a different type? Commit to your answer.
Common Belief:Apply can change the type of the object it returns.
Tap to reveal reality
Reality:Apply always returns the same object type it was called on; it does not transform the object.
Why it matters:Misunderstanding this can cause type errors or unexpected behavior.
Quick: Is apply only useful for setting properties? Commit to your answer.
Common Belief:Apply is only for setting simple properties on objects.
Tap to reveal reality
Reality:Apply is also useful in complex DSLs and builder patterns for configuring objects with functions and nested calls.
Why it matters:Limiting apply to simple cases misses its power in real-world Kotlin codebases.
Expert Zone
1
Apply’s use of lambda with receiver means you can call extension functions inside the block as if they were members of the object.
2
When chaining apply calls, each block can focus on a different aspect of configuration, improving code organization.
3
Apply does not create a new object; it modifies the existing one, so side effects inside the block affect the original reference.
When NOT to use
Avoid apply when you need to return a different result from the block or when you want to avoid modifying the original object. In those cases, use let or run instead.
Production Patterns
Apply is widely used in Android development for initializing views, in Kotlin DSLs for building UI or configuration files, and in builder patterns to create immutable objects with clear setup steps.
Connections
Fluent Interface Pattern
Apply supports fluent interfaces by returning the same object for chaining method calls.
Understanding apply helps grasp how fluent APIs maintain readability and chainability in many programming languages.
Lambda with Receiver
Apply is built on the lambda with receiver concept, which changes the context inside the lambda to the object itself.
Knowing lambda with receiver clarifies why apply lets you access object members directly without qualifiers.
Builder Pattern in Software Design
Apply simplifies the builder pattern by allowing inline configuration without separate builder classes.
Seeing apply as a builder pattern tool shows how language features can reduce boilerplate in common design patterns.
Common Pitfalls
#1Trying to use apply to transform an object into a different type.
Wrong approach:val result = person.apply { name = "Eve"; age = 22; "Done" }
Correct approach:val result = person.apply { name = "Eve"; age = 22 }
Root cause:Misunderstanding that apply returns the original object, not the last expression inside the block.
#2Using 'it' inside apply block instead of 'this'.
Wrong approach:val person = Person().apply { it.name = "Frank" }
Correct approach:val person = Person().apply { name = "Frank" }
Root cause:Confusing apply with let or other functions that use 'it' as the lambda parameter.
#3Expecting apply to create a new object instead of modifying the existing one.
Wrong approach:val newPerson = person.apply { name = "Grace" } // expecting newPerson to be a copy
Correct approach:person.apply { name = "Grace" } // modifies original person
Root cause:Not realizing apply works on the same object reference, causing side effects.
Key Takeaways
Apply is a Kotlin function that lets you run code on an object and then returns that same object.
It uses 'this' inside its block, so you can access object properties directly without qualifiers.
Apply is perfect for setting up or configuring objects in a clean, readable way.
Because apply returns the original object, you can chain calls or use it in builder patterns.
Understanding apply unlocks writing fluent, concise Kotlin code and working with DSLs effectively.