How should named arguments influence the design and evolution of a public Kotlin API?
answer
- names are source-level API surface
- rename = source break, not ABI break (silent)
- add defaulted params at the end
- reordering breaks positional callers silently
- @JvmOverloads for Java; require named args for booleans
basics
~10 sBecause callers can pass arguments by name, parameter names become part of your public contract. Pick names carefully and avoid renaming or reordering them, since that can break callers who used names.
solid answer
~40 sNamed arguments make parameter names a binary- and source-relevant part of a Kotlin API. Renaming a parameter is a source-breaking change for named callers; reordering parameters is source-breaking for positional callers and behavior-changing in subtle ways. When evolving APIs, add new parameters with default values at the end so existing positional and named calls keep compiling, and choose stable, descriptive names up front. For Java consumers, named/default args don't apply, so consider @JvmOverloads or explicit overloads. Tools like binary-compatibility-validator track ABI but not name changes, so name stability is largely a discipline. Prefer named arguments at call sites for boolean/numeric parameters to make intent explicit and reduce wrong-order bugs.
code
kotlin · 7 lines// Additive evolution keeps callers working:
// v1
fun open(path: String, readOnly: Boolean = false) {}
// v2: new defaulted param appended
fun open(path: String, readOnly: Boolean = false, createIfMissing: Boolean = false) {}
open("/tmp/f", readOnly = true) // still compiles unchangedgo deeper
Understands that names matter to callers and shouldn't be changed casually.
Knows to append defaulted parameters and avoid reordering to keep callers compiling.
Distinguishes source vs binary breakage of renames and applies @JvmOverloads for Java consumers.
Sets API-evolution policy (naming, additive defaults, named-arg call conventions) and accounts for tooling blind spots and polyglot consumers.
## Parameter names are part of the contract Once callers can write `f(timeout = 30)`, the **name** `timeout` is API surface: - **Renaming** a parameter is a **source-breaking** change for any caller using it by name (it won't compile after the rename). - It is *not* an ABI break on the JVM (the bytecode signature is unchanged), so binary-compatibility tools won't flag it — making it a silent trap for downstream source consumers. ## Reordering is worse Reordering parameters: - Breaks **positional** callers silently if the types are compatible (wrong values bound, possibly no compile error). - Breaks nothing for fully-named callers but is still confusing. So treat both order and names as stable once published. ## Safe evolution patterns - **Add new parameters at the end with default values.** Existing positional and named calls keep working: ```kotlin // v1 fun connect(host: String, port: Int = 443) {} // v2 — additive, non-breaking for Kotlin callers fun connect(host: String, port: Int = 443, useTls: Boolean = true) {} ``` - **Don't repurpose** an existing parameter's meaning; add a new one instead. - **Choose precise names early** — `enabled` vs `isEnabled`, `count` vs `n` — because they're hard to change later. ## Java consumers Named and default arguments are invisible to Java. For a polyglot library: - Use **`@JvmOverloads`** to generate trailing-omission overloads, or hand-write overloads for the shapes Java needs. - Remember Java can't skip a middle parameter the way Kotlin named arguments allow. ## Encourage named call sites in guidelines Many teams require named arguments for **boolean** and bare-**numeric** parameters in calls, e.g. `setVisible(visible = true)`. This: - prevents wrong-argument-order bugs, - documents intent inline, - survives later additions of defaulted parameters. ## Tooling reality ABI validators (e.g. `binary-compatibility-validator`) catch signature/binary breaks but **not** parameter-name changes. Name stability is therefore a **review/discipline** concern, sometimes aided by API-review checklists.
- Is renaming a parameter a binary-compatible change on the JVM?Yes, it's binary-compatible (the signature is unchanged), but it is source-breaking for Kotlin callers using that parameter by name — a silent trap because ABI tools won't flag it.
- What's the safest way to add a new option to an existing function?Append a new parameter with a sensible default value at the end so existing positional and named calls keep compiling without modification.
saying these in an interview costs you the question
- Treating parameter names as private implementation detail with no API impact
- Reordering parameters and assuming it's always safe
- Renaming a parameter and assuming ABI tooling will catch any break
- Inserting a new required parameter in the middle of an existing signature