Kotlin is one of the next-generation languages that builds on top of Java. It’s kind of a post-Scala and Groovy language that comes from JetBrains and therefore has a lot of static functionality that enables great tooling to be built on top of it.
It has been in development for a while but it is now getting a big push in terms of marketing as it approaches version one. I have noticed this a lot in terms of Android development, where Google and Oracle’s legal wrangle over the JDK code used in Android applications offers an opportunity for people who want great bytecode compatibility and post-Java 6 features but who cannot upgrade their Java version.
This blog post is purely based on going through the tutorials and koans for Kotlin and not any production experience I have. This post is more a summary of my initial evaluation of whether to spend more time with this language.
Kotlin aims to have great interoperability with Java but aims to reduce boilerplate coding and eliminate certain classes of error within pure Kotlin code.
The Java legacy
Kotlin’s symbiotic relationship with Java means that fundamentally you have a language that has all of Java’s quirks and legacy and adds to it a new layer of syntax and complexity. Essentially Kotlin is syntax-sugar on Java so deep that it is like the inch-high frosting on a cupcake.
Scala has also had a strong influence on Kotlin but disappointingly this means that many of the quirky aspects of Scala have been transplanted to Kotlin. Most particularly Scala’s val and var system of maintaining compatibility with Java’s fundamentally mutable variable system.
Like a lot of object-orientated languages with lambda support, functions like filter or map are on the data and take a lambda. So you chain operations together in a trainwreck-style or if you don’t like that then you have to introduce intermediate variables. I prefer collection manipulations to be their own standalone functions which take a sequence or iterable and the lambda. This allows partial or deferred application.
What’s good about Kotlin?
Kotlin has all the higher-order function functionality that you would expect along with a straight-forward declaration and package-style namespacing.
It has some “annotation functions” that allow you to package data objects in the same way as Scala case classes.
If you limit yourself to functions and data then you have a compact language with the power to do meaningful work.
It reminds me a lot of Groovy but is typed and compiled and is more in the camp of “if it compiles it will work”.
Unsurprisingly the tooling in IntelliJ is excellent and it is easy to write and navigate around the code.
The extension functions allow a way of enhancing or bespoking code you don’t own that is more elegant than Scala’s implicit magic. The function declarations attach to the type and compiler magic introduces an implicit this. By comparison with implicit there is much less runtime magic and if you are using IntelliJ then the declarations are easy to navigate.
The type system
Over half the koans are concerned with type-compatibility with Java, in particular issues with generics and extension methods. Type inference didn’t seem that good or bad, you have to declare the types of parameters and the return type of functions, which is par for the course. I didn’t come across any confusing type errors although the extension methods sometimes had confusing scoping issues if I didn’t declare them correctly.
Rather like Groovy, Kotlin has decided to retain null compatibility with Java but uses Option and some built-in operators to allow some type-safety around nulls. I found the new operators to be more confusing that simple null-checking as they do some type-changing from Option[T] to T conditional on the Option being Some[T], otherwise the expression doesn’t get evaluated.
In theory this means you write code that accesses nested, potentially null attributes of an object in a single line without risking a Null Pointer Exception. In practice though it seemed just as likely that the code execution would get vetoed which meant that you have a subtle code branch after each use of a null-checking operator.
I’m not sure the special operators added any real value to the normal API for Option, they are less explicit in their behaviour and they really seem more concerned with reducing line count when interacting with legacy code.
So most of Kotlin’s typing seems concerns with retro-fitting fixes to the underlying Java type system. It certainly doesn’t seem to have an declared interest in having more sophisticated or powerful types.
Final thoughts: Scala versus Kotlin
Scala in many ways is much more ambitious than Kotlin but in outcomes they are very similar. Both fundamentally want to retain compatibility with Java including mutable variables, null, mutable collections and the Java type system. Both add higher-order functions and a system for extending code that you don’t own.
Obviously Scala is the earlier language and therefore a lot of what Kotlin is doing is feature matching.
The thing that separates them is really what purpose you are using them for. If you are looking for an actively developed language that is fundamentally an enhanced Java with modern features then Kotlin has better tooling and a more explicit extension system.
If you are looking for a richer type system that allows you to express behaviour as the result of the application of types or you are into category theory then Kotlin isn’t going to do anything for you and Scala is still the better choice.