Kotlin, just another trend? (Spoiler: no)

When I began to write this article, a few weeks ago, I talked about the amount of new frameworks, architectures and languages that come out every day, and about the need to separate the chaff from the wheat before investing our time in trying to assimilate new technologies.

I had crushed it, but on 17 May 2017, barely a week ago, Google announced that it was adopting Kotlin as a high-level language for Android development. In other words, the world has now been divided into those that shout ‘I knew it’ and those that whisper ‘but what does it mean?’.

I know that I’m asking you for an act of faith, but I can’t help but point out that at Paradigma we were on the side of the visionaries. So, without any more introduction, we’ll start with the most basic stuff…

What is Kotlin?

Kotlin is a static programming language for JVM, Android, browsers and soon LLVM, 100% interoperable with Java, created by Jetbrains, the company responsible for, among others, Intellij Idea.

That being said, it seems like just another JVM language of which there are many at this point, right? In a certain way, this is true, but the devil is in the details…

Why Kotlin?

Who hasn’t ever done something in JavaScript? Come on, raise your hand if you have ever flirted with the idea of putting Full Stack Developer on your CV. And who hasn’t lost their temper getting confused between double or triple equalities, or converting some random value in truthy and going crazy while debugging their if conditions?

I don’t need to see you to know that almost all of your hands are still up (and whoever lowered them did so out of shame, you’re not fooling me!).

JavaScript can be many things, but if I had to define it in one word, it would be confusing. And, before the front people get angry with me, how do you explain that the most recommended book about the language is this one?

Special mention to the subtitle: unearthing the excellence in JavaScript. Unearthing. This is no joke.

The crux of the issue is that a programming language, like any other tool, has to make what’s right simple and what’s wrong more complicated. Like Mr. Crockford, and five hundred other videos on YouTube, show us, it seems that JavaScript sometimes insists on doing the opposite. And that’s how it goes.

But you shouldn’t laugh at java-ists, since we also have our ten commandments for how to program without tying a rope around our necks…

Our friend Joshua Bloch distinguished himself here with an indispensable book. Whoever has been programming in Java for ten or fifteen years and hasn’t read it should not think that they have nothing to learn from it, quite the contrary. Now is when they will be able to get the most out of it, every time that they see a solution to one of those blunders that we all have on our conscience.

What does it mean for a language that books as essential as these come out? That something is rotten in the state of Denmark. Honestly, I think Java is the best choice for software development today, an unsurpassed ecosystem and a language that has picked up many good ideas and allowed us to get very far. But, let’s face it, the passing of time is not without consequence and now we see clearly that, besides good ideas, there are also clearly outdated design decisions.

We have two options: we learn to program brilliantly, investing time and extra effort in it, and avoid picking up our tool on the side that cuts, or we look for a better tool. Because it is not enough that you do things well, you have to trust that the rest of your team does too… and that your versions of ‘well’ match.

It’s possible, clearly, and many of us do it day after day. (At Paradigma, of course, we all do it, what the hell!) However, why put in more effort than necessary when there are better and, dare I say, more fun options?

But we already have other languages…

That’s true, and without even leaving the JVM we could talk about Jython, Groovy, Scala, Clojure, Ceylon, Xtend… Or decide that we don’t care about limiting ourselves to Microsoft and dedicate ourselves to C#, which emerged from the shadow of Java to become a very good language with a platform with very few possibilities, sadly.

The first great debate on languages of History

But Jetbrains were very clever when they decided that maintaining the code of their products was too cumbersome and that they needed a better language, as they saw a gap in the market that no one was covering. There was room for an alternative as long as it was:

A language for JVM. Because it is the best runtime in the market by far, unrivalled for large servers but capable of running software on a normal PC.

Easy to learn for the java-ists, which is where options like Scala or Clojure fail. It was always the intention to make a practical, non-academic language so that any of the 9,000,000 Java developers in the world could catch on to it practically, understand it without much difficulty, and be productive quickly.

100% compatible with Java, in such a way that in the same software parts made in Java can be mixed with parts made in Kotlin in a transparent way. In other words, you don’t have to throw out everything you’ve done and start from zero. You can make a new class in Kotlin, or a test, and it will work perfectly alongside the rest of the project. Another consequence of this is that you can use any Java library within Kotlin. Or make a Kotlin library and use it within Java. Make note of this, which might seem incidental but, in my opinion, is amazing. So much so that I’d put this whole paragraph in bold if it wouldn’t be so ugly.

Strongly typed. Because a test that tells you that your code is bad is good, but it’s better if the compiler can tell you. For this reason Intellij Idea can help you to convert code, auto-complete it, analyse it… And here the Groovy people start to cry.

Proved in production. Experiments are good for the typical toy project, but for something to use for work it’s better to be sure that it isn’t going to give more headaches than necessary. Jetbrains have been developing the language for six years, and almost from the beginning it has been used in the development of their products. It works for them. And for Trello, and for Basecamp, and so many others.

Compatible with Android. In my opinion, this was the coup de grace. With more than 80% of the smartphones market, we Android developers have found ourselves tethered to a kind of Java 7 that, in view of the fortune that has been spent on lawyers by Google and Oracle, doesn’t seem likely to improve much in the short term. How long did Google spend adding Java 7 functionalities little by little to Android? Years? Does anyone know if something is still missing? In the meantime, Java 8 arrived, lambdas and streams spread like wildfire, and in the mobile sector we continue to write lines and lines of paraphernalia to create a sad anonymous class. Has anyone tried writing RxJava without lambdas? Believe me, it’s not nice the first time, and let’s not talk about maintaining it afterward. Google was very conscious of this and, seeing that people were resorting to messy workarounds like using Retrolambda (which has always worked great for me, but let’s recognize that it’s a freak huge hack), ended up creating Jack, a new compiler that allowed some functionalities of Java 8. But, well, the problems of compatibility and performance have been so big that they recently threw it in the trash and incorporated these new features into the regular compiler. It was too little, too late, and we’ll see if any judge does not pull it back. At Google they knew that it was not enough…
(My partner Miguel Sesma tells me that we don’t have reason to assume that support for Java 8 will not be complete. I say that since they are still announcing new features that are planned to be ported, I will believe it when I see it … in 2021, at this rate.) Let’s recap. On Android Java is outdated, Groovy doesn’t run, Scala works as usual, and Ceylon (the work of another crack, Gavin King, creator of Hibernate and with Red Hat supporting it) is not there nor is expected to be.But Kotlin is made to work perfectly on mobiles from day one. Also, a gentleman named Jake Wharton (practically the official demigod for those of us who are dedicated to Android), notices it and recommends it in an internal report for his company. The rest is history…

The cheers and applause from those of us who were watching it via streaming from the Campus Madrid must have been heard from the street, and Twitter and Slack turned into a party. People applauding a programming language, just look at that. Almost nothing.

But what is Kotlin like?!

Okay, you still haven’t seen a line of code yet. But I think it was important to know the why of things and, if I have done my job well, you will now be eager to see some meat instead of just skimming over the examples.

What is Kotlin like? Kotlin is like picking up the book Effective Java and implementing almost all of its recommendations in a language. Think about everything that gave you headaches in your last project and how many laps you had to circle to make it good. Now see how to make it flawless from the first minute.

Disclaimer: The following code will not always be as idiomatic as it could be. The idea is to understand the difference, but do yourself a favour and do not use it as an example to put into production.

Nullable types

Does it happen to anyone else that more than half of the errors that you end up resolving are NullPointerException at some point? How do you know whether a method can return null or not? And can I pass it to a parameter? Hoare says unreservedly that the was his billion-dollar, and fifty years later it continues to be gospel truth.

In Java there are many ways to test it, including two or three libraries that compete among themselves with annotations of @Null, @Nullable, @Notnull, etc. which, if you remember to use them and the IDE that you use parses them, can save you from some blunders. Do you use them in your projects? Are they not… um… a pain?

It could be worse, it could be the official option of Java 8, the Optional type. (Option… Optional… ok, I’ll leave it.) Or, as I call it, the great missed opportunity of Java. Gentlemen of Oracle, was it so difficult to give a little syntactic sugar to this to make it a bit simple to use? Or, I don’t know, make it Serializable. Call me crazy, but when flamewars have been started about when and howOptional should be used and, more than anything, whenit shouldn’t, it means that it is not as polished as it could be.

Finally, in the end what we all do is look at Javadoc, pray that it is updated and, lastly, plant the if code.

Kotlin

// A String can’t ever be null
fun helloWorld(name: String) {
println("Hi, " + name.trim())
}
// String? can, but the compiler forces you to check before using it
fun helloWorldWithIf(name: String?) {
if (name != null) {
println("Hi, " + name.trim())
}
}
// There are safe calls, that return null if the var is null
// And an Elvis operator, that returns a default value if the left argument is null
fun callSafeHelloWorld(name: String?) {
println("Hi, " + (name?.trim() ?: "world"))
}
// For interoperability, if a value comes from Java is supposed to be nullable, but the
// developer can swear that he’s sure it’s not… and if he’s wrong, a NPE will be thrown
// Up to you, if you think it’s a good idea
fun dangerousHelloWorld(name: String?) {
println("Hi, " + name!!.trim())
}

Immutability

Another classic story of days spent debugging code. Is a variable supposed to be overwritten or not? We have the option of adding final to everything, but it is adding an extra word to, effectively, everything and most of the time it is not done. Bad developers!

With Kotlin you have to decide from the beginning. And perhaps you realize that mutability is the devil, as a rule. Good Kotlin!

Java

final String immutable = "This can’t be changed";
String mutable = "This can, but didn’t we think that it rather not? I can’t remember...";

Kotlin

Properties

I hate JavaBeans. I hate them. You have to write the variables, the getters and the setters and everything in Javadoc, copying and pasting the same thing four times. But it’s done in case someone wants some logic, you’ll tell me. Okay, but could there not be a bit more concise notation?

No primitive types

In Java there are primitive types and objects. Sun did this for optimization. Do you know who are better than people when it comes to analysing code and optimizing it? Compilers, that’s who. In Kotlin all data is an object, and derives from Any?. Arrays also. There are no special cases.

Type inference

Is it obvious which type is a variable or a function belongs to? Well, don’t put it on if you don’t want to.

var aString = "I’m a String"

Equals

You’ve been programming for years, and you still sometimes make the mistake of putting == instead of equals, or vice versa. In Kotlin both things are the same.

Default values

Do we want a default value for a parameter in Java? Welcome to the party of polymorphism!

Java

public void helloWorld(String adjective, String name) {
// We all know that concatenation is not very efficient
System.out.println(String.format("Hi, %s %s", adjective, name));
}
public void helloWorld() {
helloWorld("cruel", "world");
}
public void helloWorld(String name) {
helloWorld(“bland”, name);
}
// Do you want a version with only the adjective? That would be another method with
// a String parameter.
// It’s impossible.
// You have to change the name of the method.
public void uglyHelloWorld(String adjective) {
helloWorld(adjective, "thing");
}

Kotlin

Parameters by name

Wait, the last example was missing something. Can you call the method to leave the adjective as is and only change the name? Yes, we can!

fun usageExample() {
helloWorld(name = "day") // Hi, cruel day
}

Data classes

Ok, We’ve seen properties, type inference, default values and parameters by name. It was all part of a plan to teach you the data classes because, if I ordered these examples by importance, for me it would clearly be in the Top 3 of Kotlin. Pay attention.

If defining properties in a class already saves you lines and lines of bureaucracy with getters, setters and documentation, let’s think about the fact that for the typical JavaBean, which we want to be identified by the data that it carries inside and is already there, you have to write its equals, its hashCode and its toString.

Because we never fail to verify that the contract between equals and hashCode is respected, obviously. After all, there are libraries that help you, and virtually all IDEs bring functions to generate them.

Of course, then we add a new field, we forget to maintain these two methods, we place an instance in a collection and then the party starts…

Let’s not stop here. Do the fields have to be mutable or immutable? Do we create a constructor or a Builder? And a method for making copies? We could say that we don’t need it and that we’ll see later on, but that’s a sure recipe to end up making spaghetti code, and you know it. It’s better to establish a practice from the beginning, isn’t it? Or could Kotlin save us the trouble?

Look at this comparison, which is one that hurts. To be honest, I could use Guava or Apache Commons, but it would barely get rid of two or three lines…

Kotlin

var aKotlinLongString = """
No need to escape here
Line breaks are allowed
But the spaces on the left
Slip into the value
<--- These spaces
"""
var aKotlinLongStringWithTrim = """
|Don’t you worry
|Kotlin has an answer for everything
|A pipe is the default prefix
|But we could use another chat
""".trimMargin()
var json = “””
{
// What a change, isn’t it?
“name”: “Sergio”,
“surname”: “Delgado”
}
“””

Extension Methods

We all have a StringUtils class or two. Too bad that this is not object orientation or anything that resembles it. An extension method allows you to add code to a class that you can’t touch, so that it is read as God intended.

Don’t use it for such shabby examples. But do add it to your Android Contexts and Activities and marvel at the difference.

Functions and lambdas

You’ve seen that the methods all have the reserved word fun in front. Effectively, it means function. Why is it added? Because Kotlin allows you to have functions outside of objects. Also to define a function with a lambda, or a reference to another function. And to pass functions as parameters of other higher-order functions, without the need to invent interfaces. Functions are fun, fun, fun!

fun higherOrderFunction(aString: String, function: (String) -> String) {
println(function(aString))
}
fun firstLetterToUppercase(aString: String): String {
return aString.capitalize()
}
// An easier way to say the same
fun firstLetterToUppercaseAsAExpression(aString: String) = aString.capitalize();
fun usageExamples() {
// Without an instance, because the function is defined in the package
higherOrderFunction("sergio", ::firstLetterToUppercase)
// A function from a class
higherOrderFunction("sergio", String::capitalize)
// A lambda, in the most awkward way possible
higherOrderFunction("sergio", { aString: String -> aString.capitalize()})
// If the last parameter is a lambda, you can take it out of the parameter list
higherOrderFunction("sergio") { aString: String -> aString.capitalize() }
// And if there is only one parameter, it can be named “it” by default
// Can you imagine your Android listeners like this?
higherOrderFunction("sergio") {
it.capitalize()
}
}

Collections and ranges

We have higher-order functions. We have lambdas. We have classes with immutable data. Does this not sound like functional programming? No one forces us, but if we want to use it, we can. And for that, a good covering of the library collections is nothing short of essential.

for (i in 1..10) {
println(i)
}
val j = 3
if (j in 1..10)
println("$j is between 1 and 10")
}

There are even sequences, which are like collections but with lazy evaluation and are potentially infinite.

// It will generate every power of 2, beginning with a seed value and a function to calculate
// every subsequent value from the previous one
generateSequence(1) { it * 2 }
// We take the first 5
.take(5)
// And collect them into a list
.toList()

Semicolons

You will have noticed that semicolons are optional in Kotlin. Apparently, many people hate them. First world problems.

And there are no bad things?

Well, to be honest, there are some:

Not very widespread. Up until this week, Kotlin was known by a minority, albeit an enthusiastic one. But you’ll already see the number of views on YouTube of the two conferences they’ve dedicated to it on the Google I/O…

It is not mathematically perfect. For the Scala people, who don’t miss an opportunity to criticise the rest of us.

There is much left to say

Indeed, we have barely scratched the surface. I hope, however, to have left you wanting more. See you, if you fancy, in future blog articles where we’ll be able to talk about:

More features of the language. Even more? Yes, even more, but in exchange I won’t bore you with my stories. Sealed classes! inline functions! Delegation! Singletons! Generics! Co-routines! DSLs!

Enough with bits of code, here we will make a complete tutorial to create an app from scratch and without using any Java]. You’ll like it, I assure you.

Did you not remember that Kotlin also works for the browser? Will it succeed where Google failed with Dart? It will be difficult, but perhaps an example with React Native will make you take their side.

Gradle this substitute for Maven produces a love-hate response in me. On the one hand, well, it isn’t Maven, but I would be lying if I said that I haven’t spent hours reviewing Groovy scripts to find some option that wasn’t defined exactly where it should be and that derailed my entire compilation. Damn dynamic languages! I can’t be the only one frustrated by this, because the people at Gradle are working hard to allow defining scripts completely in Kotlin. Hallelujah.

Testing if your boss is a coward and doesn’t let you put Kotlin into production, consider that he probably doesn’t care how the hell you do the tests. JUnit 4, JUnit 5, Mockito, Spek, Kluent… We can handle it all.

Kotlin Native. They’re ambitious at Jetbrains. Not only do they want us to share code between JVM and JavaScript, but now they encourage platforms with native compilation and interoperability with C. With Kotlin Native they point to IoT devices or to the iPhone, although for now we have a functional preview for Raspberry Pi. They take away the garbage collector (which they promise to replace) and the standard library of Java, but in return they give us … the world. One language to rule them all!

More frameworks, if you haven’t already had enough. ¿VertX? ¿Kara? ¿ktor? Of course, I can’t promise that any of these will still be alive next year. Except Vert.X, I’m afraid.

And many more surprises… I hope.

And if I can’t wait?

Well, in the meantime, here are some resources of all kinds and colours:

Kotlin in Action, a book written by two of the creators of the language. Unfortunately, it only covers up to version 1.0, but it is very interesting to get to know the details about the most cumbersome parts of the language like the generics or the design of DSLs.

Kotlin for Android Developers, the book by Antonio Leiva, a well-known member of the Android community in Spain, where he builds an app from the ground up. A perfect project for a weekend.

And, of course, you can also search for the corresponding tag on your favourite blogging platform, such as Medium or DZone.

But the most important thing if you want to learn is… roll up your sleeves and get to it. Come on. It isn’t so difficult.

Programmer by calling. I've gone from video games in C++, slot machines, e-learning platforms in PHP, tussled with Dreamweaver, automatised calls in a call-center and managed a I+D department. Currently Java Architect in Paradigma Digital and Android developer in my spare time.

2 comentarios

You’re actually mistaken in your equality example because you used Kotlins Int type which compiles to the JVM int type (Int? maps to Integer). I tested it in the Kotlinc REPL just to be sure. It should read: