Functions & Lambdas
🔧 Functions & Lambdas
📐 Declaring a Function
Every parameter must have an explicit type — Kotlin does not infer parameter types the way it infers val types, since the compiler has no value to look at until the function is called. The return type (: String above) can often be omitted and inferred, but many teams write it explicitly on public functions for readability.
Function Syntax: Java vs JavaScript vs Kotlin
| Language | Declaring greet(name) |
|---|---|
| Java | public String greet(String name) { return "Hello, " + name; } |
| JavaScript | function greet(name) { return `Hello, ${name}!`; } |
| Kotlin | fun greet(name: String): String { return "Hello, $name!" } |
➡️ Single-Expression Functions
When a function body is just a single return expression, Kotlin lets you drop the braces and the return keyword entirely, using = instead:
The return type is inferred from the expression (Int * Int is Int), so it's usually left off in single-expression form. This isn't just shorthand for its own sake — Kotlin code leans heavily on small, expression-bodied functions, especially once lambdas and collection operators enter the picture later in the course.
Default Parameters
A parameter can have a default value, making the argument optional at the call site: fun greet(name: String, greeting: String = "Hello"). Calling greet("Philip") uses the default; greet("Philip", "Hi") overrides it.
Named Arguments
Any call can name its arguments explicitly: greet(name = "Philip", greeting = "Hi"). This lets you skip earlier defaults and go straight to a later one, or just make a call with many parameters self-documenting.
In Java, "optional" parameters are usually simulated with several overloaded method signatures (createUser(name), createUser(name, age), createUser(name, age, isAdmin)) — three methods to maintain in sync. Kotlin's default parameters replace all of that with one function.
🎯 Lambda Basics
A lambda is a function without a name, written inline and often passed as an argument — conceptually identical to a JavaScript arrow function:
Lambda Syntax: JavaScript vs Kotlin
| JavaScript | Kotlin | |
|---|---|---|
| Arrow / lambda | (x) => x * x | { x: Int -> x * x } |
| Separator | => | -> (inside braces) |
| Implicit single param | Not available | it |
| Trailing lambda call | arr.map((x) => x * 2) | list.map { it * 2 } |
That last row matters: when a lambda is the last argument to a function — which it is for almost every collection operator (map, filter, forEach...) — Kotlin lets you move it outside the parentheses entirely, and drop the (now-empty) parentheses altogether. numbers.map({ it * 2 }) and numbers.map { it * 2 } are the same call; the second is idiomatic Kotlin.
💻 Coding Challenges
Challenge 1: Default Parameters & Named Arguments
Write a function orderPizza(size: String = "medium", toppings: Int = 1, extraCheese: Boolean = false) that prints an order summary. Call it four times: with no arguments, with only size overridden, with only extraCheese overridden using a named argument, and with all three provided.
Goal: Get comfortable mixing default values with named-argument overrides.
Challenge 2: Single-Expression Functions
Write three functions as single-expression functions (using =, no braces or return): isEven(n: Int) returning a Boolean, max(a: Int, b: Int) returning the larger value, and greeting(name: String) returning a greeting string using a string template.
Goal: Practice recognizing when a function body is simple enough to collapse to a single expression.
Challenge 3: Lambdas with map and filter
Given val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), use a lambda with filter to keep only even numbers, then use a lambda with map to square each of the results. Print the final list. Write the lambdas using the implicit it parameter.
Goal: Chain two lambda-based collection operators and get comfortable with it.
The "lambda moved outside the parentheses" pattern (list.map { it * 2 } instead of list.map({ it -> it * 2 })) shows up constantly in idiomatic Kotlin — not just for collections, but for things like building UI layouts in Jetpack Compose later on. Getting used to reading it now pays off throughout the rest of this course.
🎯 What's Next
Next chapter: Null Safety — nullable types, the safe call operator ?., the Elvis operator ?:, smart casts, and the not-null assertion !!.