Thursday, August 2, 2012

Kotlin is fun :-)

I have just recently began experimenting with language called Kotlin, which is a statically typed programming language compiled to JVM byte code.

I wanted to try how it works and how affects coding style. So far, my personal feeling is that Kotlin combines very well statically typed paradigm and the flexibility of Javascript.

 I also wanted to try how Context works with Kotlin and so far everything has worked as expected. At this moment, Kotlin is still under development and has for instance incomplete support for method parameter annotations. This creates some inconveniences with Guice-related injections, but that is a minor concern.

One really nice feature in Kotlin is its null-safety. Basically it means that in common cases possible null-pointer references are forbidden at compile time. Code does not compile if null-checks aren't properly handled. And in case where null pointer might occur, you as a developer has to choose how to deal with it. For me there has been a certain learning curve and especially when Kotlin-code is mixed with Java-code it may be confusing sometimes, because Kotlin assumes that Java-classes are not null-safe.

I have also experience with Scala, but so far Kotlin feels better. With Scala it is possible to create really cryptic looking code and for some reason I like Kotlin syntax better. So, if you are a Java developer having experience with Javascript, I would recommend to try Kotlin for next generation language.

The fun part

Because Kotlin is a modern language, it has type inference, function literals and extension functions etc. which are completely missing from Java. Extension functions allows me to write something that I have always wanted to do. Consider following Java-code that traverses directory tree:

File root = new File("...");


for (File file : root.listFiles()) {
  if (file.isDirectory()) {
    traverse(file);
  } else if (file.getName().endsWith(".xml")) {
    handleXml(file);
  } else if (file.getName().endsWith(".png")) {
    handlePng(file):
  }
}

What bothers me with this code is that It has file.getName() twice in the code. If that method would be expensive, it would be a problem. That can of course be fixed for instance like this:

for (File file : root.listFiles()) {
  if (file.isDirectory()) {
    traverse(file);
  } else {
    String name = file.getName()
    if (name.endsWith(".xml")) {
      handleXml(file);
    } else if (name.endsWith(".png")) {
      handlePng(file):
    }
  }
}

That is better, but I still feel that more could be done. How about this example?

String email = person.getContactInformation().getEmail();
if (email != null && isValid(email)) {
    sender.send(email, title, msg);
}

That code contains a lot of things. First, there is a temporary email-variable to hold the value hidden deep in the object tree. Then there is an if-condition to check whether email can be sent at all. This is kind of normal Java-code in that sense that there is always a null-check, just to avoid possible NPE.

There is the method isValid(), but it does not really say anything about null-emails. It is possible that null-email is a valid option and the signature also does not say anything. It might be possible to replace it with isNullOrValid() but not everyone likes adding Or or And-words in methods. In any case null-checks are so common that they tend to pollute code a lot.

Also the temporary variable email is not nice. It is used only for a small amount of time, but it may be visible for all code in the rest of the method body. This can of course be fixed with making an own method to handle email sending like this:

private void sendEmail(String email, String title, String msg) {
 if (email != null && isValid(email)) {
    sender.send(email, title, msg);
 }
}

So, that is the Java-way of doing things.

But, what I have been longing for is a simple function that takes a variable or a return value of a method and applies a function on it. And in Kotlin I'm able to write just that, and it is:

public fun Any._<T>(func: (t: T) -> Unit) : Unit {
    func((this as T))
}

When that is used, code looks a bit different. Take for instance the directory traverse example in Kotlin:

val root = File("...")


root.listFiles()!!.forEach({ file ->
  if (file != null) {
    if (file.isDirectory().sure()) {
      traverse(file))
    } else {
      file.getName()?._<String>{ name ->
        if (name.endsWith(".xml").sure()) {
          handleXml(file)
        } else if (name(".png").sure()) {
         handlePng(file)
        }
      }
    }
  }
})

Also the email-example might look like this:

person.getContactInformation().getEmail()?._<String>{ email ->
    if (isValid(email)) {
        sender.send(email, title, msg);
     }
}

Or how about these examples:

FileInputStream(file)._<InputStream>{ stream ->
    // do something with the stream
    stream.close()
}


val person = findPerson()
person.getContactInformation()?._<ContactInformation>{
    it.email = other.email
    it.phoneNumber = other.phoneNumber
    ...
}

In all these examples the information (or variable) at hand is simply encapsulated inside a local function and forgotten when not needed anymore. Also null-checks are clearly visible where needed. It also make sure that if the return value or variable would be null the function is never called and no explicit if statements are needed.

I could not find a way to infer the type for the _-method and it may lengthen the function. It would certainly look nicer if the type parameter and the method name itself could be removed. Then it would really look concise. For instance like this:

person.getContactInformation().getEmail()? {
    if (isValid(it)) {
        sender.send(it, title, msg);
    }
}

Maybe that construction could be taken into Kotlin itself in some form :-D. Anyway, these are my first steps learning Kotlin and so far I have really liked what I have seen. Keep up the good work.