HomebaseWorks
Lesson 2 of 4

Functions, lambdas and coroutines in Kotlin

when expressions, extension functions, lambdas on collections and the coroutine basics that Android screenings ask about.

EWritten by the HomebaseWorks editorial team · reviewed 26 Oct 2026

Once null safety is clear, Kotlin questions move on to functions: how when replaces switch, how extension functions and lambdas shorten code, and how coroutines run work without blocking the main thread.

Advertisement

when as an expression

when can match a value or, with no argument, test conditions in order. It returns the value of the first matching branch, so it can be assigned directly. Used as an expression, it needs an else branch unless the compiler can see that every case is covered, as with an enum or sealed class.

val score = 72
val grade = when {
    score >= 80 -> "pass"
    score >= 60 -> "close"
    else -> "building"
}   // "close"

Extension functions and lambdas

An extension function adds a function to an existing type without changing its source. Inside it, this is the receiver object and can usually be left out.

fun String.initials() = split(" ").map { it.first() }.joinToString("")
println("Ada Lovelace".initials())   // AL

A lambda is a block of code passed as a value. When it has a single parameter, you can refer to it as it, and when it is the last argument, it goes outside the parentheses.

val nums = listOf(3, 8, 5, 10)
println(nums.filter { it > 4 }.map { it * 2 })   // [16, 10, 20]
println(nums.sumOf { it })                      // 26

Coroutine basics

Coroutines let you write asynchronous code that reads from top to bottom. A suspend function can pause without blocking a thread, and it can only be called from a coroutine or another suspend function.

  • launch starts a coroutine and returns a Job, for work that produces no result.
  • async returns a Deferred, and await() gets its result.
  • withContext(Dispatchers.IO) moves blocking work such as disk or network access off the main thread.
viewModelScope.launch {
    val user = withContext(Dispatchers.IO) { repo.loadUser(id) }
    nameText.value = user.name
}

On Android, viewModelScope cancels its coroutines automatically when the ViewModel is cleared, which prevents leaks and wasted work.

Habit to build

When you read a lambda chain, write down the intermediate list after each step. When you read coroutine code, mark which lines run on the main thread and which run on a background dispatcher.

Advertisement
Continue with Kotlin4 lessons · 1 interview set · 1 test · 1 certificate
Not tested

More in Programming