Extension Functions & Higher-Order Functions
Add behavior to existing types with extension functions and use higher-order functions and scope functions (let, apply, also, run, with) for expressive Kotlin code.
Extension Functions & Higher-Order Functions is a free Android Academy lesson on CoddyKit — lesson 4 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 Android Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Extension Functions
An extension function lets you add new functions to existing classes without modifying them or using inheritance. You can extend String, Int, your own classes, or even Android's View.
Syntax: fun TypeName.functionName() { }
Writing Extension Functions
Inside an extension function, this refers to the receiver object:
fun String.isPalindrome(): Boolean {
val cleaned = this.lowercase().filter { it.isLetter() }
return cleaned == cleaned.reversed()
}
fun Int.isEven() = this % 2 == 0
fun main() {
println("racecar".isPalindrome()) // true
println("hello".isPalindrome()) // false
println(4.isEven()) // true
println(7.isEven()) // false
}Extension Functions on Android Views
Common Android pattern — hide/show views with an extension instead of repeating boilerplate:
import android.view.View
fun View.show() { visibility = View.VISIBLE }
fun View.hide() { visibility = View.GONE }
fun View.invisible() { visibility = View.INVISIBLE }
// Usage in Activity:
// binding.progressBar.show()
// binding.recyclerView.hide()Higher-Order Functions
A higher-order function takes a function as a parameter or returns one. You've already used them: filter, map, forEach are all higher-order functions.
Function type syntax: (ParamType) -> ReturnType
Passing Functions as Parameters
Define a function that accepts another function:
fun operate(a: Int, b: Int, op: (Int, Int) -> Int): Int {
return op(a, b)
}
fun main() {
val sum = operate(3, 4) { x, y -> x + y }
val prod = operate(3, 4) { x, y -> x * y }
val max = operate(3, 4, ::maxOf) // method reference
println(sum) // 7
println(prod) // 12
println(max) // 4
}Returning Functions
Functions can also return other functions — useful for building configurable behavior:
fun makeMultiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
fun main() {
val double = makeMultiplier(2)
val triple = makeMultiplier(3)
println(double(5)) // 10
println(triple(5)) // 15
val numbers = listOf(1, 2, 3, 4)
println(numbers.map(double)) // [2, 4, 6, 8]
}Scope Functions: let
Kotlin scope functions run a block on an object and return a result. let is used for null checks and transformations:
fun main() {
val name: String? = "Alice"
// Only runs if name is not null
name?.let {
println("Name length: ${it.length}")
println("Upper: ${it.uppercase()}")
}
// Transform a value
val length = name?.let { it.length } ?: 0
println("Length: $length") // 5
}Scope Functions: apply & also
apply configures an object and returns the object. also performs a side effect and returns the object:
data class Config(var host: String = "", var port: Int = 0, var timeout: Int = 0)
fun main() {
// apply: configure an object (this = receiver)
val config = Config().apply {
host = "api.example.com"
port = 443
timeout = 30
}
println(config) // Config(host=api.example.com, port=443, timeout=30)
// also: log or debug (it = receiver)
val result = listOf(1, 2, 3)
.also { println("Original: $it") }
.map { it * 2 }
.also { println("Doubled: $it") }
}Scope Functions: run & with
run executes a block on an object and returns the block result. with is similar but not an extension:
data class User(val name: String, val age: Int)
fun main() {
val user = User("Bob", 30)
// run: compute something using the object
val greeting = user.run {
if (age >= 18) "Hello, $name!" else "Hi, $name!"
}
println(greeting) // Hello, Bob!
// with: group operations on an object
val info = with(user) {
"Name: $name, Age: $age"
}
println(info) // Name: Bob, Age: 30
}Scope Function Cheatsheet
Quick reference for choosing the right scope function:
let— null-safe block, transform object, returns lambda resultapply— configure object, returns the object (this)also— side effects (logging), returns the object (it)run— compute result from object, returns lambda resultwith— group calls on an object, not an extension
inline Functions & reified
Mark a higher-order function as inline to avoid lambda object allocation at runtime. reified lets you use generic type T at runtime (normally erased):
inline fun <reified T> Any.isOfType(): Boolean = this is T
fun main() {
println("hello".isOfType<String>()) // true
println(42.isOfType<String>()) // false
println(3.14.isOfType<Double>()) // true
}Quick Check
Which scope function is best for configuring a newly created object and returning that same object?
Recap: Extensions & Higher-Order
Kotlin's functional toolkit is now yours:
- Extension functions — add behaviour to any type without inheritance
- Higher-order functions — pass and return functions for flexible APIs
- Scope functions:
let(null check),apply(configure),also(side effect),run/with(compute) inline+reified— zero-cost lambdas with runtime type info
Next: build multi-screen apps with Fragments.
Frequently asked questions
Is the “Extension Functions & Higher-Order Functions” lesson free?
Yes — the full text of “Extension Functions & Higher-Order Functions” is free to read here on the web, and the Android 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 Android Academy course, upgrade to CoddyKit PRO.
What will I learn in “Extension Functions & Higher-Order Functions”?
Add behavior to existing types with extension functions and use higher-order functions and scope functions (let, apply, also, run, with) for expressive Kotlin code. You practise Android 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 Android Academy?
No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Extension Functions & Higher-Order Functions” 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 Android Academy lesson?
Yes. Every Android 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
- Null Safety
- Classes & Objects
- Data Classes & Sealed Classes
- Extension Functions & Higher-Order Functions