Default & Named Arguments

Reviewed & published by Brayan K

Kotlin is a modern, concise language that lets functions declare default parameter values and lets callers pass arguments by name — together they replace the tangle of overloaded methods found in other languages.

Part of the free Kotlin course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

By the end of this lesson you'll write flexible functions with defaults and call them with clear, self-documenting named arguments.

What You'll Learn in This Lesson

1️⃣ Default Argument Values

A parameter can declare a default with =. If the caller omits that argument, the default is used. This means one function definition can serve many call patterns — no overloading required.

// Give parameters default values with '='. Callers can omit them.
fun greet(name: String, greeting: String = "Hello", excited: Boolean = false): String {
    val mark = if (excited) "!" else "."
    return "$greeting, $name$mark"
}

fun main() {
    println(greet("Ada"))                       // both defaults used
    println(greet("Ada", "Hi"))                 // override greeting only
    println(greet("Ada", "Hey", true))          // override all
}

A single greet function handled three different call styles. In Java this would have meant three separate overloaded methods.

2️⃣ Named Arguments

When calling a function you can label each argument with its parameter name. This makes calls self-documenting, lets you reorder arguments, and — crucially — lets you skip earlier defaulted parameters to set just a later one.

fun makeBox(width: Int = 1, height: Int = 1, depth: Int = 1): String =
    "Box ${width}x${height}x$depth"

fun main() {
    // Named arguments make calls self-documenting AND let you skip
    // earlier defaults to set a later one.
    println(makeBox(width = 4, depth = 2))      // height stays 1
    println(makeBox(height = 10))               // only height set
    println(makeBox(2, 3, 4))                   // positional still works

    // Named args can come in any order:
    println(makeBox(depth = 5, width = 5, height = 5))
}

makeBox(height = 10) sets only the height and leaves width and depth at their defaults — impossible with purely positional calls.

Your turn. Replace the TODO, then run and compare.

// 🎯 YOUR TURN — replace each TODO then run main()

// A function with two defaulted parameters.
fun coffee(size: String = "medium", shots: Int = 1): String =
    "$size coffee with $shots shot(s)"

fun main() {
    // 1) Call with all defaults
    println(coffee())                       // expect: medium coffee with 1 shot(s)

    // 2) Use a NAMED argument to set ONLY shots to 2
    println(coffee(TODO = 2))               // 👉 replace TODO with 'shots'

    // 3) Override the size positionally
    println(coffee("large"))                // expect: large coffee with 1 shot(s)

    // ✅ Expected line 2:  medium coffee with 2 shot(s)
}

Mini-Challenge: A Flexible Logger

Write one log function with two defaulted parameters, then call it three different ways using named arguments.

// 🎯 MINI-CHALLENGE: a flexible logger.
// Save as Logger.kt and run main().
//
// 1. Write fun log(message: String, level: String = "INFO",
//        uppercase: Boolean = false): String
//    that returns "[<level>] <message>" and applies .uppercase()
//    to the message when uppercase is true.
// 2. In main(), call it three ways:
//    - just a message
//    - with level = "ERROR" (named)
//    - with uppercase = true (named)
//
// ✅ Example output:
//    [INFO] starting up
//    [ERROR] disk full
//    [INFO] DONE

fun main() {
    // your code here
}

Common Errors (and the fix)

Pro Tips

📋 Quick Reference — Arguments

ConceptKotlin Syntax
Default valuefun f(x: Int = 1)
Call with defaultf()
Named argumentf(x = 5)
Skip earlier defaultmakeBox(depth = 2)
Java interop@JvmOverloads

🎉 Lesson Complete!

Practice quiz

How do you give a Kotlin function parameter a default value?

  • With the default keyword
  • With a ? after the name
  • With = after the type, e.g. greeting: String = "Hello"
  • Defaults are not supported

Answer: With = after the type, e.g. greeting: String = "Hello". A parameter declares a default with =, used when the caller omits it.

What is a key benefit of default arguments?

  • One function definition can replace many overloads
  • They make functions run faster
  • They prevent null values
  • They are required on every parameter

Answer: One function definition can replace many overloads. Defaults let one function serve many call patterns without overloading.

What does a named argument let you do that positional args cannot?

  • Call a private function
  • Change a parameter's type
  • Add new parameters at runtime
  • Skip earlier defaulted parameters to set only a later one

Answer: Skip earlier defaulted parameters to set only a later one. Named args can skip earlier defaults, e.g. makeBox(depth = 2).

Can you reorder arguments in a call using named arguments?

  • No, order is always fixed
  • Yes, named arguments can appear in any order
  • Only the first two
  • Only if all are named

Answer: Yes, named arguments can appear in any order. Named arguments may come in any order.

Mixing positional and named arguments: which rule applies?

  • Once an argument is named, all following ones must also be named
  • Named must come first
  • You can never mix them
  • Positional must come last

Answer: Once an argument is named, all following ones must also be named. f(1, y = 2) is fine, but f(x = 1, 2) is not.

When are default argument values evaluated?

  • Once at definition time
  • Never, they are constants
  • On each call where the argument is omitted
  • Only the first time the function runs

Answer: On each call where the argument is omitted. Defaults are evaluated per call, so System.currentTimeMillis() gives a fresh value each time.

What happens if you type a wrong parameter name in a named argument?

  • It is silently ignored
  • It won't compile
  • It uses the default
  • It picks the closest match

Answer: It won't compile. The named argument must match a declared parameter name exactly.

What does greet("Ada") output if greeting defaults to "Hello" and excited to false?

  • Hello, Ada!
  • Ada
  • Hi, Ada.
  • Hello, Ada.

Answer: Hello, Ada.. Both defaults are used: greeting Hello and excited false gives a period.

Why do Java callers not see Kotlin default arguments automatically?

  • Java cannot call Kotlin
  • Java needs @JvmOverloads to generate overloads
  • Defaults are private
  • Java ignores all annotations

Answer: Java needs @JvmOverloads to generate overloads. Within Kotlin defaults just work; Java interop needs @JvmOverloads.

Can a default value reference an earlier parameter of the same function?

  • No, never
  • Only constants are allowed
  • Yes, a later default may use an earlier parameter
  • Only the first parameter

Answer: Yes, a later default may use an earlier parameter. Defaults can reference earlier parameters of the same function.

Continue this course

Frequently asked questions

How do default arguments reduce the need for overloads?

In languages without default values you often write several overloaded versions of the same function — one with two parameters, one with three, one with four — just to allow optional inputs. Kotlin lets a single function declare defaults like greeting: String = "Hello", so one definition covers all those cases. Callers supply only the arguments they care about, and the rest fall back to their defaults.

When should I use named arguments?

Named arguments shine in three situations: when a call has several parameters of the same type and positional order is easy to get wrong; when you want the call site to be self-documenting (makeBox(width = 4) is clearer than makeBox(4)); and when you want to skip over earlier default parameters to set a later one. They also let you reorder arguments freely.

Can I mix positional and named arguments in one call?

Yes, but with a rule: once you start using named arguments in a call, every argument after the first named one must also be named. So f(1, y = 2) is fine, but f(x = 1, 2) is not. In practice, pass any leading positional arguments first, then switch to named arguments for the rest.

Are default argument values evaluated once or on every call?

Default values are evaluated on each call where the argument is omitted, not once at definition time. This means a default like createdAt: Long = System.currentTimeMillis() produces a fresh value every time the function is called without that argument. Defaults can also reference earlier parameters of the same function.