Kotlin for Seniors: Code Less, Solve More. 3 tips. Part 2.

Artem Asoyan
3 min read2 days ago

--

Kotlin is all about writing less code and solving more problems. If you’re a seasoned developer, you already know the power of clean, efficient code.

Here are three pro tips that will help you write cleaner, more expressive Kotlin code with less boilerplate and better performance. 🚀

1. Master inline and crossinline for performance

Lambda functions are powerful but come with a hidden cost — they create objects and add function call overhead. Kotlin’s inline keyword helps eliminate this by replacing the function call with its actual code at compile time.

Using inline for performance

Without inline (creates extra objects)

fun execute(task: () -> Unit) {
task()
}

With inline (no extra objects, better performance)

inline fun execute(task: () -> Unit) {
task()
}

Here, execute() is replaced directly in the bytecode, avoiding object creation and function calls.

When to use crossinline?

Sometimes, you need an inline function but don’t want to allow early return from the lambda. That’s where crossinline comes in:

inline fun runTask(crossinline action: () -> Unit) {
Thread {
action() // `crossinline` ensures action() is not returned early
}.start()
}

Use crossinline when the lambda is executed inside another function (like a background thread) and cannot return from the outer function.

Rule of Thumb: Use inline for performance and crossinline when passing lambdas inside other functions.

2. Simplify complex names with typealias

If your team struggles with long generic types, typealias can make your code much more readable.

❌Without typealias (ugly, hard to read)

val cache: HashMap<String, List<Pair<Int, String>>> = hashMapOf()

Not great, right? Let’s simplify it:

✅ Using typealias for clarity

typealias UserCache = HashMap<String, List<Pair<Int, String>>>

val cache: UserCache = hashMapOf()

Another great use case is simplifying callback functions:

typealias CompletionHandler = (Boolean, String) -> Unit

fun fetchData(callback: CompletionHandler) {
callback(true, "Success!")
}

When to use typealias?
✔️ When your types are too long
✔️ When defining complex function types
✔️ When improving code readability

3. Write less boilerplate with delegated properties

Kotlin’s delegated properties (by lazy, by Delegates.observable, by map) help eliminate boilerplate code when managing object properties.

lazy for on-demand initialization

Instead of initializing a variable immediately, use lazy to initialize it only when needed:

val expensiveData: String by lazy {
println("Loading data...") // Runs only once
"Expensive Data"
}

fun main() {
println(expensiveData) // First call triggers loading
println(expensiveData) // Second call reuses existing data
}

Best Use Case: Large objects that don’t need immediate loading (e.g., database connections, configuration settings).

Observable for property change listeners

Need to track property changes? Use observable:

import kotlin.properties.Delegates

var theme: String by Delegates.observable("Light") { _, old, new ->
println("Theme changed from $old to $new")
}

fun main() {
theme = "Dark"
theme = "Blue"
}

Conclusion

Kotlin offers powerful tools to help you write less code and solve more problems efficiently.

What are your favorite Kotlin tricks? Let’s discuss in the comments! 👇

--

--

Artem Asoyan
Artem Asoyan

Written by Artem Asoyan

Head Of Mobile, Android Tech/Team Leader, Career mentoring. 12+ years in software development #MobiusConference2023 #PodlodkaAndroidCrew1 #Leetcode (0.4%)

No responses yet