Kotlin idioms survey

Dear Kotliners.
You probably know about JBA / Hyperskill platform. It allows learning different languages (including Kotlin) not by reading books, but by solving almost-real-life problems step-by-step. Sadly, the theoretical part of Kotlin track is not as good as it could be so there is some effort to improve it. What we miss is a core around which we can build different topics. We’ve discussed it and decided that the best core is the list of kotlin idioms. Of course, the language is developing and even the creators are not always able to keep track of this development. Some idioms are present in the documentation, but surely there are some things missing there. Therefore, please - look at the existing list and add your own ideas, if you do not find it there. We will update the list as we go.

Here is the form: https://forms.gle/saauMhbWvfPTiK3o9

2 Likes

It is a useful compilation!

However, I wonder about one idiom:

class Doubles(val list: DoubleArray)
 
@Suppress("FunctionName")
fun Doubles(vararg numbers: Number) = Doubles(numbers.map{it.toDouble()}.toDoubleArray())
 
Doubles(1,2,3)

What would be the benefit of defining an “external” method compared to an overloaded constructor?

Another option could be to define an invoke function in the companion object:

class Doubles(val list: DoubleArray) {
    companion object {
        operator fun invoke(vararg numbers: Number) = 
            Doubles(numbers.map{it.toDouble()}.toDoubleArray())
    }
}

However, I don’t see an advantage over a secondary constructor, too.

As soon as we get all required feedback, I will try to publish some videos explaining those idioms. The fake constructor allows much more flexibility. You do not have to think about initialization order which is a major problem in kotlin. There are more instruments like error checks, better stack traces and you can actually make them suspend. Since 1.4.20 suppression is not needed in this case anymore. Secondary constructors are still useful sometimes, but in general, it became an idiom not to use them.

3 Likes

When checking the small utility program I’ve created for my own purposes, I’m missing delegation (of course, by lazy is delegation, but ‘by’ is much more versatile than that)

class FileBackedList(private val fileName: String, private val contents: MutableList = mutableListOf()) :
MutableList by contents

But perhaps I have just overlooked it in the idioms list

I also used a companion object to house a factory method [there does not seem a companion object in the list either], but I’m not sure if that is idiomatic kotlin, compared to the Doubles (though I don’t think needing an @Suppress annotation is that great)

Anyway, delegation (more general than lazy) and a companion object would be my current additions.

Thanks for the feedback. Delegates are not quite idiomatic in my opinion. They are more like advanced API design, but I will think about that.

Passing a mutable map is not a good practice, but empty collection creation is a good idea, I will add that.

The companion factory was discussed, but we decided that factory functions are preferred right now.

Please provide us with the link to the video explaining the idioms when you get to it. Thanks!

1 Like