Looking at Kotlin - The rest of it

Published on 2013-5-22

I'm nearly done with my brief foray into Kotlin, but I've a few more things to cover

Inner classes

So, inner classes, a feature that both Java and C# have and each with their own set of issues.

class Outer() { 
  private val bar : Int = 1 
    class Nested() { 
      fun foo() = 2 
    } 
  } 

val demo = Outer.Inner().foo() // == 2

No biggy here, except in Java there is a problem with nested class as explained in this blog entry

An inner class is a non-static nested class, i.e. it holds a reference to an instance of its outer. In Java nested classes are inner by default, and if you don’t want a reference to the outer, you make your class static. Sometimes it leads to memory leaks, when someone is holding a reference to an instance of an inner class without knowing that it also holds an outer instance.

Kotlin's solution is to say that you can't do this

class Outer() { 
  private val bar : Int = 1 
    class Nested() { 
      fun doSomething() {
        println(bar)
      }
    } 
  } 

Instead you have to mark the inner class with 'inner' to make this an explicit decision

class Outer() { 
  private val bar : Int = 1 
    inner class Nested() { 
      fun doSomething() {
        println(bar)
      }
    } 
  } 

I have a better solution, get rid of inner classes, they're crap anyway and don't just cause problems in software, but apparently cause problems with language design too. Problem solved.

null and elvis

Kotlin operates on the basis of things not being nullable by default, which is something I wholeheartedly support.

var derpy : Pony = null

This isn't allowed.

We're allowed to say we want a nullable object, by adding a question mark to things.

var derpy : Pony? = null

This is sensible, and can't be faulted.

Most legacy java APIs will return things that can be nullable, and in fact a lot of Java APIs do this in places where they really shouldn't. The compiler will complain about this though, so where I do

Compiler error

 var fileList = files.listFiles()
 var size = fileList.size
 println(size)

Compiler success

 var fileList = files.listFiles()
 var size = fileList?.size
 println(size)

The elvis operator gets compiled down into

 var fileList = files.listFiles()
 if(fileList != null) {
   var size = fileList.size
   println(size)
 }

This is a case where Kotlin "fixes" Java well, so I'm not complaining.

Ranges

Syntastical sugar, but always a fan of this sort of thing

for (i in (1..4).reversed() step 2) print(i) // prints "42" 

I like this sort of thing, although it gets out of hand in languages like Ruby so I'd watch this stuff cautiously.

Pattern matching

when (x) { 
  1 -> print("x == 1") 
  2 -> print("x == 2") 
  else -> { // Note the block 
    print("x is neither 1 nor 2") 
  } 
}

or

when (tuple) { 
  is #(1, 2) -> ... 
  is #(val a, 3) -> print(a) // binding a to the first element of the tuple 
  !is #(*, 1100) -> ... 
  else -> ... 
}

I'm a sucker for pattern matching constructs and I like this implementation because of how easy it is to declare those function literals.

Also, it does intelligent casting for you as well, cutting own on some of the cruft you'd usually get with this sort of thing

function strangeFunction(a : Any) : Any {
  when(a) {
    is Int ->
      return a + 5
    is String ->
      return a + "5"
  }
}

Nice

Round-up

The stated goals of Kotlin of "fixing Java" don't appear to have been met, there are holdovers from the language such as

And then some new ones

It does 'fix'

And it does compile to JavaScript which means some interesting library targeting opportunities.

If I were "fixing a problem like Java", it would be by removing features that people shot themselves in the foot with often and by adding a few pieces of sugar to make things more readable in places.

It wouldn't be by adding more key-words and more options for shooting yourself in the foot with, and it wouldn't be by defaulting to mutable and public :)

That's pretty much all I have to say from my day of Kotlin, there are probably more things in there but I've got other stuff to do and not on the JVM!

2020 © Rob Ashton. ALL Rights Reserved.