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.

[caption id="" align="aligncenter" width="790"]

The first great debate on languages of History[/caption]

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:

[caption id="" align="aligncenter" width="460"]

Jake Wharton seducing the camera[/caption]

Furthermore, as a culmination of history, in the keynote of Google I/O 2017 they dropped a bombshell: Google gives official support to Kotlin as a first-level language for development in Android:

https://youtu.be/d8ALcQiuPWs

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.

Later they also announced that, besides being open source, Kotlin is donated to a non-profit foundation and so on. But that's something for the lawyers in the audience...

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 how Optional should be used and, more than anything, when it 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.

Not with Kotlin. Kotlin skips all this.

Java


/**
* The typical example.
*
* @param name name to greet, can't be null
*/
public void helloWorld(String name) {
   // We use trim to make it exciting
   System.out.println("Hi, " + name.trim()); // NPE if null is entered
}
public void defensiveHelloWorld(String name) {
   if (name != null) {
       System.out.println("Hi, " + name.trim());
   }
}
public void annotatedHelloWorld(@NotNull String name) {
   System.out.println("Hola, " + name.trim());
}
public void optionalHelloWorld(Optional<String> name) {
   // Hey, if you use Idea even the IDE complains about using Optional in a parameter!
   System.out.println("Hi, " + name.map(String::trim).orElse("world"));
}

Kotlin

[code light="true"]
// 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())
}
[/code]

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

[code light="true"]
val immutable = "This can’t be changed"
var mutable = "This can, and I’m saying explicitely that I’m counting on that"
[/code]

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?

Java


public class JavaBean {
   // The name
   // Don’t worry if you missed it, because I’m going to repeat it quite a bunch of times
   private String name;
    /**
    * Constructor.
    *
    * @param name name
    */
    public JavaBean(String name) {
       this.name = name;
    }
   /**
    * Returns the name.
    *
    * @return name
    */
   public String getName() {
       return name;
   }
   /**
    * Sets the name.
    *
    * @param name name
    */
   public void setName(String name) {
       this.name = name;
   }
}

Kotlin

[code light="true"]
/**
* Bean with a [name].
*/
class KotlinBean {
var name: String? = null
}

/**
* Bean with a [name] whose first letter is returned in uppercase.
*/
class KotlinBeanWithLogic {
var name: String? = null
// Do we want some logic? No probs
get() = name?.capitalize()
}

/**
* Bean with a [name] that it’s initialized with a parameter from the constructor.
*/
class KotlinBeanConstructor(var name: String)

fun usageExamples() {
// It’s used as easy as this
val bean: KotlinBean = KotlinBean()
bean.name = "sergio"
println(bean.name) // sergio

// Does the getter have some logic? So what!
// You realize you can introduce it afterwards without touching even a comma from
// the rest of the code, don’t you?
val bean2: KotlinBeanWithLogic = KotlinBeanWithLogic()
bean2.name = "sergio"
println(bean2.name) // Sergio

val bean3: KotlinBeanConstructor = KotlinBeanConstructor("Sergio")
println(bean3.name)
}
[/code]

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.

[code light="true"]
var aString = "I’m a String"
[/code]

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.

Java


AbstractMap.SimpleEntry<Integer, String> apples =
       new AbstractMap.SimpleEntry<>(2, "pieces of fruit");
AbstractMap.SimpleEntry<Integer, String> oranges =
       new AbstractMap.SimpleEntry<>(2, "pieces of fruit");
System.out.println(apples.equals(oranges)); // True
System.out.println(apples == oranges);        // False

Kotlin

[code light="true"]
val apples = Pair(2, “pieces of fruit”)
val oranges = Pair(2, “pieces of fruit”)

println(apples.equals(oranges)) // True
println(apples == oranges) // True
println(apples === oranges) // == from Java, False in this case
[/code]

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

[code light="true"]
fun helloWorld(adjective: String=”cruel”, name: String ="world") {
println("Hi, " + adjective + " " + name)
}

fun usageExample() {
helloWorld("exciting") // Hi, exciting world
}
[/code]

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!

[code light="true"]
fun usageExample() {
helloWorld(name = "day") // Hi, cruel day
}
[/code]

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...

Java


public class JavaBean {
   private String name;
   private String surname;
   public JavaBean(String name, String surname) {
       this.name = name;
       this.surname = surname;
   }
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
   public String getSurname() {
       return surname;
   }
   public void setSurname(String surname) {
       this.surname = surname;
   }
   @Override
   public boolean equals(Object o) {
       if (this == o) return true;
       if (!(o instanceof JavaBean)) return false;
       JavaBean javaBean = (JavaBean) o;
       if (name != null ? !name.equals(javaBean.name) : javaBean.name != null) return false;
       return surname != null ? surname.equals(javaBean.surname) : javaBean.surname == null;
   }
   @Override
   public int hashCode() {
       int result = name != null ? name.hashCode() : 0;
       result = 31 * result + (surname != null ? surname.hashCode() : 0);
       return result;
   }
   @Override
   public String toString() {
       return "JavaBean{" +
              "name='" + name + '\'' +
              ", surname='" + surname + '\'' +
              '}';
   }
   public JavaBeanBuilder copy() {
       return new JavaBeanBuilder(name, surname);
   }
   public static final class JavaBeanBuilder {
       private String name = "José";
       private String surname = "García";
       public JavaBeanBuilder() {
       }
       private JavaBeanBuilder(String name, String surname) {
           this.name = name;
           this.surname = surname;
       }
       public static JavaBeanBuilder toJavaBean() {
           return new JavaBeanBuilder();
       }
       public JavaBeanBuilder withName(String name) {
           this.name = name;
           return this;
       }
       public JavaBeanBuilder withSurname(String surname) {
           this.surname = surname;
           return this;
       }
       public JavaBean build() {
           return new JavaBean(name, surname);
       }
   }
}

Kotlin

[code light="true"]
data class KotlinBean(var name = "José", var surname = "García")
[/code]

I repeat, the word data has added the following to the class:

To which we add, by pure Kotlin syntax, the default values in the parameters and the ease of calling the parameters by name.

[code light="true"]
fun iWantABabyBrother() {
var sergio = KotlinBean(“Sergio”, “Delgado”)
var baby = sergio.copy(name=”Raúl”)
}
[/code]

All this in one line! With no possibility of bugs! And it will always be up-to-date!

String Interpolation

By the way, we said that concatenation isn’t cool. But so far, I’ve used it in all the examples of Kotlin. This was just to go little by little. In reality what I would write is this:

Java


System.out.println(String.format("Hi, %s %s", adjective, name));

Kotlin

[code light="true"]
println("Hola, $adjective $name")
[/code]

Remember, make what’s right simple. How many times do we not get past the String.format because it’s not understandable or simply from laziness?

String literals

It’s not just interpolation, defining strings in Java also becomes very cumbersome. Between these two options, which version seems more readable?

Java


String aLongString = "One line\nTwo lines";
String anotherLongString = "For the lines to be noticed\n" +
       "We split it in several literals\n" +
       "And join them";
String json = “{\”name\”:\”Sergio\”,\n\”surname\”:\”Delgado\”}”;

Kotlin

[code light="true"]
var aKotlinLongString = """
No need to escape here
Line breaks are allowed
But the spaces on the left
Slip into the value

Tell us what you think.

Comments are moderated and will only be visible if they add to the discussion in a constructive way. If you disagree with a point, please, be polite.

Subscribe