Avoid Overusing Defaults
Advice
Be cautious about using default arguments in data types or constructors - they can reduce safety, clarity, and discoverability in your code.
Context
Defaults are convenient, but they come with hidden trade-offs.
Defaults can potentially hurt
-
exhaustivity checking
When you give every parameter a default value, the compiler can’t help you find all the places where a change might matter. For example, adding a new property with a default means no callsites will prompt you to reconsider how it should be set. -
local reasoning
In order to understand how a value was derived, you may have to jump to another file to check what the default is, and that default might change later. -
discoverability
New developers might never realise certain parameters even exist.
Finally, in layered architectures, defaults often blur boundaries. A data-transfer object should not know business rules — if the backend decides what’s “default”, let the backend populate it explicitly.
Examples
Good
data class BlogPost(
val title: String,
val tags: List<String>,
val isBehindPaywall: Boolean
)
Bad
data class BlogPost(
val title: String,
val tags: List<String> = emptyList(),
val isBehindPaywall: Boolean = false
)