Defining functions and default arguments
Functions are how you name a piece of work so you can reuse it and reason about it. Kotlin's functions are more flexible than most languages', and this module is where a lot of what makes Kotlin pleasant lives. This first lesson covers the shape of a function, its parameters and return type, and the single most useful feature — default arguments.
The anatomy of a function
fun greet(name: String): String {
return "Namaste, $name"
}
Read it left to right:
fun— declares a function.greet— the name. Use a verb or verb phrase; a function does something.(name: String)— the parameters, each writtenname: Type. Kotlin puts the type after the name, unlike Java or C.: String— the return type, after the parameter list.return ...— hands back the result.
Call it like this:
val message = greet("Kavita")
println(message) // Namaste, Kavita
A parameter's type is always required — Kotlin cannot infer it, because a function is a contract and its inputs must be explicit. The return type you often can omit for the single-expression form (a later lesson), but for a block-body function like this one you write it, and it is good practice to write it even when inference could manage, because it documents the contract for the reader.
Functions that return nothing: Unit
A function that does something but returns no meaningful value returns Unit — Kotlin's
equivalent of void:
fun logIn(user: String): Unit {
println("$user logged in")
}
You almost never write : Unit — it is the default when you omit the return type:
fun logIn(user: String) {
println("$user logged in") // returns Unit implicitly
}
So "no return type written" means "returns Unit". Unit is a real type (unlike Java's void,
which is a non-type), which matters when you get to higher-order functions and generics — but for
now, just know that a function with no return value returns Unit, and you leave it off.
Parameters are val — always
A crucial rule that surprises people from other languages: function parameters are read-only. You cannot reassign them inside the function:
fun addTax(price: Int): Int {
price = price + price / 10 // error: val cannot be reassigned
return price
}
Parameters behave like val — this is the val-by-default philosophy again, and it prevents a
subtle class of bug where a parameter is modified halfway through a function and later code uses the
changed value by accident. If you need a modified version, make a new local val:
fun addTax(price: Int): Int {
val withTax = price + price / 10
return withTax
}
Default arguments — the feature you will love
This is where Kotlin functions pull ahead. A parameter can have a default value, used when the caller does not supply one:
fun greet(name: String, greeting: String = "Namaste"): String {
return "$greeting, $name"
}
println(greet("Kavita")) // Namaste, Kavita
println(greet("Kavita", "Good morning")) // Good morning, Kavita
greeting defaults to "Namaste", so callers can leave it out. This eliminates a whole category
of boilerplate that other languages solve with method overloading — writing three versions of a
function with different parameter lists. In Java you might write greet(name), greet(name, greeting), and greet(name, greeting, punctuation) as three separate methods. In Kotlin it is one
function with defaults:
fun greet(
name: String,
greeting: String = "Namaste",
punctuation: String = "!"
): String {
return "$greeting, $name$punctuation"
}
println(greet("Kavita")) // Namaste, Kavita!
println(greet("Kavita", "Hello")) // Hello, Kavita!
println(greet("Kavita", "Hello", ".")) // Hello, Kavita.
One function, many ways to call it. Defaults make functions flexible without multiplying them, and they read far better at the definition than a pile of overloads. Put parameters with defaults after those without, so callers can supply the required ones positionally.
Functions can live anywhere
Unlike Java, where every function must be a method inside a class, Kotlin lets you declare functions at the top level of a file — no class required:
// in a file Utils.kt
fun formatRupees(paise: Int): String = "₹${paise / 100}.${paise % 100}"
This is idiomatic Kotlin. A utility function that does not belong to any object should be a top-level function, not a static method on a pointless "Utils" class. You can also declare functions inside other functions (local functions), which is occasionally useful for a helper used only in one place.
Check your work
The parts of a function declaration. fun, name, parameters (name: Type), return type
(: Type), body.
Where Kotlin puts the parameter type. After the name — name: String, not String name.
What a function with no return value returns. Unit, written implicitly when you omit the
return type.
Whether function parameters can be reassigned. No — they are read-only (like val); make a new
local val for a modified version.
What default arguments do. Give a parameter a fallback value used when the caller omits it.
What defaults replace. Method overloading — one function with defaults instead of several overloads.
Where parameters with defaults should go. After the required ones, so callers can pass the required ones positionally.
Where Kotlin functions can live. At the top level of a file (no class needed), inside a class, or inside another function.
Practice
- Write
greet(name: String): Stringthat returns a greeting, and call it. - Try to reassign a parameter inside a function and read the compiler error. Fix it with a local
val. - Write a function with no return type and confirm (in the IDE) it returns
Unit. - Add a
greetingparameter with a default and call the function both with and without it. - Add a third defaulted parameter and call the function three ways (zero, one, two extra arguments).
- Rewrite a set of imagined overloads (
send(msg),send(msg, urgent)) as one function with a default. - Write a top-level
formatRupees(paise: Int)function in its own file and call it frommain.
Official documentation
- Kotlin — Functions — Declaration, parameters, return types, and default arguments.
- Kotlin — Functions: default arguments — The feature that replaces overloading.
- Kotlin — Unit-returning functions — What
Unitis and why.
Next: named arguments, which make those defaults even more powerful.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship