Don't let Kotlin's single-expression function ruin your businessš²
Take care, Keep building!
Hello developers š,
This is a mini-blog where we'll see how a small mistake can lead to a confusing and serious issue.
Kotlin provides us with a way where we can define single-expression functions for one-shot operations. For e.g. we do something like this š
fun getItemById(id: String) = repository.findItemById(id)
The return type of the above function will be the return type of the result of findItemById()
, right? In the single-expression function, we donāt have a need to specify return type since itās automatically inferred by Kotlinās compiler.
The real problem š¬
One day I was playing with Kotlin and while doing it I came across an issue that was actually produced by my own mistake. This issue looks small but it took me some time to came to know about it.
Now letās understand how can our mistake lead to the issues. So refer to the below code.
fun greetGoodMorning() {
// Some code
println("Good Morning")
}
fun greetGoodAfternoon() = {
// Some code
println("Good Afternoon")
}
fun main() {
greetGoodMorning()
greetGoodAfternoon()
}
// Output:
// Good Morning
Whatš? Just Good Morning? Why Good Afternoon isnāt printed?
How? š¤
Did you notice = {}
in greetGoodAfternoon()
function? So this where the problem comes from. Letās understand the issue.
So any developer wonāt be intentionally writing such code. It may be just like we introduce typo mistakes! As we know, in a single-expression function, the returning type of a function is automatically inferred by the compiler (if not specified explicitly). When we write = {}
, its return type is inferred internally as this š
fun greetGoodAfternoon(): () -> Unit = {
// Some code
println("Good Afternoon")
}
Yes, itās inferred as a lambda block š
. So when we called greetGoodAfternoon()
it returned a lambda!
If we call greetGoodAfternoon().invoke()
or greetGoodAfternoon()()
then itāll be get executed (Because you now know what happened š).
Note: IntelliJ IDEA or Android Studio warns you if you do such mistakes. But even after that if you ignored it, no one can help you.
Solution š”
We are humans!šÆ We always will do mistakes but thatās fine. The mistake which we did above (= {}
) canāt be solved using any manual way. But there are some learnings by which we can avoid other related issues.
In my opinion, good practice to avoid mistakes will be a habit of mentioning return types explicitly! Yes, if we mention it explicitly (even if using a simple-expression function) then itāll avoid mistakes then weāll be sure about such things at compile time itself.
fun getItemById(id: String): Item = repository.findItemById(id)
By this, we can be sure that this function is returning Item
. If not, then the compiler will be there to help you out. It makes code more readable and also we can be sure about it just by reading it (like what exactly function is returning). It can help the reviewer while reviewing code on GitHub as well š.
For a simple, one-liner call that doesnāt return anything, then this is fine š
fun printSomething(something: Any) = println("$something")
Thereās no doubt that Kotlin has made developerās life simple and easy. But anyone can do such mistakes.
So the final conclusion is š
Mention return type of a function explicitly and make it a habit!
If you liked this article then share it with everyone! Maybe itāll help someone who needs it.
Thank you š
Many thanks to Siddhesh Patil and Niharika Arora for helping me to make this better! š