Kotlin Killer Features for Programmers and Software Engineers
By: Alexandre Lombard
Tags: Software Development, Programming, Code, Kotlin, Java

I’ve started using Kotlin 2 years ago, and I immediately fell in love with this language. This article presents the point of view of a software engineer on this language, i.e. the point of view of someone who does not only want to write code easily, but who wants to write code which is readable, reusable, portable, and safe.

For those who don’t know Kotlin, it’s a language developed by Jetbrains (known for their IDE, Intellij IDEA). It has been designed to replace Java. It’s more concise, more elegant, safer, and it’s running on the JVM, making it totally compatible with existing Java libraries (and even more). But to replace the widely used Java, a new language must have really good arguments to show.

Kotlin is rising while Java’s popularity is decreasing, yet Kotlin’s popularity is still far from Java’s

Here, I’ll try to sum up these arguments, explaining why, in my opinion, software developers should begin migrating from Java to Kotlin. To start with, I’ll write the 5 first points which explains why Kotlin is a better Java than Java. In the second part, the 5 following points will explain why it‘ i’s just a good language on its own and why you should try it.

Type inference

Type inference is the ability to write code without specifying the type of the variables, if the type can be deduced without any ambiguity from the current context.

For instance, Kotlin allows us to write things like:

Type inference with Kotlin

(Note: var means it’s a variable, so the value can change, while val means it’s a value, so basically a constant ; by the way, var has been added in the recent Java versions but is limited to local variables)

The first example would translate to int i = 0; in Java which forces us to specify the type even if it’s obvious due to the affectation. But the gain is more evident in the second example which would translate to List<Integer> myList = new ArrayList<Integer>(), and where the repetition makes it harder to write and read.

But the main benefit of type inference is when you’re calling a function without knowing the return type of the function (when you’re using an API you’re not familiar with). Using this syntax, it’s just not a problem, because you don’t have to explicitly write the type.

It’s also important to note that this kind of type system is really different from what we can see in Python and JavaScript: even though the syntax doesn’t make it appear clearly, Kotlin is statically and strongly typed. This means that you avoid the pain of explicitly writing the type of the variables you’re using, while you have a fully functional autocompletion and a static analysis of the code preventing you from calling undeclared functions or reaching undeclared variables.

Operator overloading

When Java came out, it refused to include operator overloading, while this feature was heavily used in C++.

The main reasons for this are the poor semantic value of the operators (especially if the author of the code abused of operator overloading), and the possibility to overload any operator (C++ allows you to overload the new operator…).

Yet, it’s really convenient if it’s correctly used. Accessing to the i-th element of a list using myList[i] instead of myList.get(i) is really practical. And adding an element to a map using myMap[myKey] = myValue is more readable than myMap.put(myKey, myValue).

Let’s say we want to create a “Vector2D” class, we can allow to write a + b (with a and b being two Vector2Ds), just by writing this:

Overloading operator_plus (+) in a Kotlin class

It’s still up to the developer to ensure that the semantic of the operators is respected, but at least Kotlin restricts the number of operators you can overload, preventing the developers to abuse of this.

Extension functions

Sometimes you use a class and you think it would be pretty convenient to have that specific function you developed directly in the class, but you have no control over its source code. The only way is to extend the class through inheritance, but it’s not always possible (if the class is final, which is default in Kotlin, if the constructor is private, etc.).

Extension functions allows you to define functions that can be called like if they were defined in a specific class.

Actually, it’s just syntactic sugar: it does not rely on inheritance and it does not really change the behavior and the code of a class.

Let’s say I’m using the previous Vector2D class, and I want to extend the class with a function dotProduct taking two Vector2D as parameter and computing the dot product of the two vectors. I consider I can’t inherit the class.

In Java, I would write it like this:

“Extending” a class with Java

And using Kotlin, it would be this:

Extending a class with Kotlin

Obviously, the Kotlin way produces a more readable call for the extension of the function.

Default and named arguments

Again, default and named arguments are basically syntactic sugar provided by Kotlin.

Indeed, Java is a language where default arguments exists: you just have to define the function several times with a different number of arguments and in this function, refer to the other implementation of this function. But it’s really cumbersome…

Java version:

“Default values” for the arguments in Java

Kotlin version:

Default values for the arguments in Kotlin

The named arguments don’t have an alternative in Java. It’s just the possibility to specify an argument by giving its name (and not just by putting it in the good position). It makes the code more readable, and is also more concise when we only want to specify values for some arguments.

Concise and elegant syntax

Kotlin is definitely more concise than Java. At first sight, some developers are afraid of it because they think it makes the code obscure and undecipherable.

But they should trust Jetbrains on this one: unlike some purely scholar languages where the focus is put on having a minimalistic syntax (with no consideration for readability), Kotlin is concise but made to be readable. They only removed from Java the keywords and the elements which didn’t add any semantic value.

For instance, why should we explicitly write new when calling a constructor? If we are calling a constructor, it’s obvious that we want to build a new object…

Then, why should I write void if my function is not returning anything?

Shouldn’t public be the default for a function?

Couldn’t we auto-generate getters and setters (if the member is not private and not final)?

Etc. etc.