Kotlin
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Null Safety
-
Section 4: Object-Oriented Kotlin
-
Section 5: Functional Kotlin
-
Section 6: Coroutines
-
Section 7: Collections Deep Dive
-
Section 8: Type System Deep Dive
-
Section 9: Interop and Tooling
-
Section 10: Kotlin DSLs and Patterns
-
Section 11: Testing and Quality
-
Section 12: Server-Side Kotlin
-
Section 13: Practical Projects
-
Section 14: Interview Practice
-
Section 15: More Practice Exercises
-
Section 16: More Standard Library
-
Section 17: Multiplatform Kotlin
-
Section 18: kotlin.collections In Depth
-
Section 19: kotlin.text In Depth
-
Section 20: kotlin.ranges and kotlin.sequences
-
Section 21: kotlin.io and File Handling
-
Section 22: kotlinx.coroutines Deep Dive
-
Section 23: kotlin.reflect
-
Section 24: Android Development with Kotlin Overview
-
Section 25: Kotlin Multiplatform Deep Dive
-
Section 26: Kotlin for Backend Deep Dive
-
Section 27: Kotlin Design Patterns
-
Section 28: Advanced Language Features
-
Section 29: More Practice Exercises
-
Section 30: More Interview Practice
-
Section 31: Kotlin Type System Deep Dive
-
Section 32: Kotlin Null Safety Advanced
-
Section 33: Kotlin Testing Deep Dive
-
Section 34: Kotlin Build Tooling Deep Dive
-
Section 35: Kotlin Serialization
-
Section 36: Kotlin Performance Considerations
-
Section 37: Kotlin Native Overview
-
Section 38: Kotlin for Data and Scripting
-
Section 39: More Coroutines Practice
-
Section 40: More Android-Adjacent Patterns
-
Section 41: More Practical Projects
-
Section 42: More Design and Architecture Practice
-
Section 43: Kotlin Language Evolution
-
Section 44: More Interview and Review
-
Section 45: Kotlin Delegation Patterns Deep Dive
-
Section 46: Kotlin Annotations Deep Dive
-
Section 47: Kotlin for Gradle Plugin Development
-
Section 48: Kotlin Concurrency Beyond Coroutines
-
Section 49: Kotlin Compiler Internals
-
Section 50: Real-World Kotlin Case Studies
-
Section 51: Final Practice Projects
-
Section 52: Kotlin for Server-Side Reactive Programming
-
Section 53: More Practice and Drills
-
Section 54: Kotlin Security Practices
10: Named Arguments
Imagine you're ordering a custom sandwich at a deli. If you just say, "Turkey, swiss, sourdough, toasted, no mayo," the person behind the counter knows what you mean because they're trained to expect the order in that specific sequence: Protein, Cheese, Bread, Style, Condiments. But what happens if you only want to change the bread and the mayo, and you're fine with everything else being the standard? You don't want to recite the entire list just to change two things. You'd probably just say, "I'll take the standard sandwich, but make the bread sourdough and skip the mayo."
In Kotlin, calling a function normally is like that first sandwich order. You provide arguments in a specific order (positional arguments), and the compiler maps them to the parameters based on where they sit in the list. But as your functions grow, this becomes a nightmare to read. Named arguments let you "label" your inputs, making it clear exactly which value is going into which slot, regardless of the order.
The Problem with Mystery Numbers
I've spent way too many hours of my career staring at a line of code like this and wondering what on earth the developer was thinking:
// What do these numbers even mean?
setupWindow(800, 600, 10, 10, true, false)
Without jumping back to the function definition, I have no idea if 800 is the width or the height, or if that true means "resizable" or "visible." This is what I call "mystery arguments," and they are a breeding ground for bugs. You accidentally swap two integers, and the code still compiles perfectly, but your UI looks like a disaster.
Making the Call Explicit
Kotlin solves this by letting you name the parameter you're targeting. Here is how we fix that window setup call:
fun setupWindow(width: Int, height: Int, x: Int, y: Int, resizable: Boolean, visible: Boolean) {
/* logic here */
}
// Now it's crystal clear
setupWindow(
width = 800,
height = 600,
x = 10,
y = 10,
resizable = true,
visible = false
)
Now, anyone reading this—including you six months from now—knows exactly what's happening. A few things to keep in mind here:
- Order doesn't matter anymore: Once you use names, you can put
visiblefirst andwidthlast. The compiler doesn't care about the sequence; it just matches the labels. - Readability is king: I generally recommend using named arguments whenever a function has more than two or three parameters, or when you have multiple parameters of the same type (like those four integers above).
Combining Names with Default Values
This is where the real magic happens. You've already learned about default parameter values. When you combine defaults with named arguments, you can ignore most of the parameters and only specify the ones you actually care about.
fun createUser(
username: String,
email: String,
isAdmin: Boolean = false,
theme: String = "Light",
notificationsEnabled: Boolean = true
) {
/* logic here */
}
// I only care about the basics and the theme.
// I'll let isAdmin and notificationsEnabled stay at their defaults.
createUser(
username = "kotlin_coder",
email = "dev@example.com",
theme = "Dark"
)
See how clean that is? I didn't have to pass false and true just to reach the theme parameter. I just pointed directly to the one I wanted to change. It makes your API much more flexible and your calling code significantly shorter.
📋 Practical Task
Refactoring the Email Notification System
You've inherited a piece of code for an email system that is currently very hard to read. The sendEmail function has several parameters, and the current implementation uses positional arguments, making it impossible to tell what the Booleans and Strings are doing.
fun sendEmail(
recipient: String,
subject: String,
body: String,
isHtml: Boolean = false,
priority: Int = 1,
cc: String? = null
) {
println("Sending email to $recipient...")
}
fun main() {
// This call is confusing!
// It's sending an HTML email with priority 3, but no CC.
sendEmail("boss@company.com", "Quarterly Report", "See attached PDF", true, 3)
}
Your Task: Refactor the sendEmail call inside the main function. Use named arguments to make it explicitly clear that the email is HTML and has a priority of 3. To make it even cleaner, remove the positional arguments and only specify the parameters you are actually providing values for (leaving the cc parameter to its default null).
There are no comments for now.