apply and with: Configure and Return
Use apply and with to configure objects and understand their return values.
apply and with: Configure and Return is a free Kotlin Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Scope Function Recap
Kotlin's scope functions (apply, also, let, run, with) let you execute a block in the context of an object. Each differs by receiver (this vs it) and return value.
apply Basics
apply { ... } runs the block with this bound to the receiver and returns the receiver itself. Perfect for object configuration.
class Person {
var name: String = ""
var age: Int = 0
}
fun main() {
val p = Person().apply {
name = "Ada"
age = 35
}
println("${p.name}, ${p.age}")
}Why apply Is Useful
Without apply, you'd need a temporary variable to configure and then return it. apply compresses this to a single expression.
class Config {
var host: String = ""
var port: Int = 0
}
fun makeConfig(): Config {
// Without apply:
// val c = Config(); c.host = "x"; c.port = 8080; return c
return Config().apply {
host = "localhost"
port = 8080
}
}
fun main() {
val c = makeConfig()
println("${c.host}:${c.port}")
}apply in a Chain
apply returns the receiver, so it chains naturally into further method calls.
class Builder {
val parts = mutableListOf<String>()
}
fun main() {
val result = Builder().apply {
parts.add("hello")
parts.add("world")
}.parts.joinToString(" ")
println(result) // hello world
}with Basics
with(receiver) { ... } runs the block with this = receiver and returns the lambda result (NOT the receiver). Useful when you want a derived value.
class Rect(val w: Int, val h: Int)
fun main() {
val area = with(Rect(3, 4)) {
w * h
}
println(area) // 12
}apply vs with
apply returns the receiver, perfect for builders. with returns the lambda result, perfect for computing from a receiver.
class Box(var width: Int = 0, var height: Int = 0)
fun main() {
val box = Box().apply { width = 10; height = 20 } // returns Box
val area = with(box) { width * height } // returns Int
println("$box area=$area")
}apply with Lists
Configure a mutable collection inline.
fun main() {
val list = mutableListOf<String>().apply {
add("a")
add("b")
add("c")
}
println(list)
}apply Returns the Same Type
The return type of apply is always the receiver type. No need for an explicit return.
class Sb {
private val buf = StringBuilder()
fun append(s: String): Sb { buf.append(s); return this }
fun build(): String = buf.toString()
}
fun main() {
val s = Sb().apply {
append("Hello, ")
append("Kotlin!")
}.build()
println(s)
}with Reusing Multiple Members
Inside with, all members of the receiver are in scope — no obj. prefix needed.
class Person(val name: String, val age: Int)
fun main() {
val description = with(Person("Ada", 35)) {
"Name: $name, Age: $age, AgeNext: ${age + 1}"
}
println(description)
}Nested apply
You can nest apply inside another apply for hierarchical configuration. Use sparingly.
class Address {
var city: String = ""
var zip: String = ""
}
class User {
var name: String = ""
var address: Address = Address()
}
fun main() {
val u = User().apply {
name = "Ada"
address.apply {
city = "Istanbul"
zip = "34000"
}
}
println("${u.name} in ${u.address.city}")
}When NOT to Use apply
If you don't need to return the receiver, prefer plain construction with named arguments or let/run. Don't use apply just for variety.
class Config(val host: String, val port: Int)
fun main() {
// Named arguments often beat builder + apply:
val cfg = Config(host = "localhost", port = 8080)
println("${cfg.host}:${cfg.port}")
}Quick Check
What does apply return after running its block?
Recap
apply runs a block with this = receiver and returns the receiver — perfect for object configuration. with runs a block with this = receiver and returns the lambda result — perfect for derived values. Use named arguments when configuration is simple.
Frequently asked questions
Is the “apply and with: Configure and Return” lesson free?
Yes — the full text of “apply and with: Configure and Return” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.
What will I learn in “apply and with: Configure and Return”?
Use apply and with to configure objects and understand their return values. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “apply and with: Configure and Return” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- apply and with: Configure and Return
- let and run: Transform and Scope
- also: Side Effects Without Changing the Receiver
- Choosing the Right Scope Function: Decision Guide