Tomasz Wegrzanowski
Posted on November 24, 2021
Kotlin is to Java what ES6 is to old style JavaScript. A lot of people are stuck with JavaScript engine (like browser) or a JVM (like Android). Their native languages are atrocious, but using a completely non-native language leads to huge complexity interfacing with native APIs. And so compromise solutions were created, like ES6 for JavaScript, and Kotlin for Java. Kotlin is especially popular among Android developers, but you can use it anywhere where you can use JVM, and really it's hard to come up with a legitimate reason to use "plain Java" these days.
Hello, World
We can start with the usual program! It's nothing unusual, unless you remember just how bad it was in plain Java:
fun main() {
println("Hello, World!")
}
Unfortunately to run this we need to do this silly line, and the whole thing takes way too long for a reasonable hello world, 7s on my laptop:
$ kotlinc hello.kt -include-runtime -d hello.jar && java -jar hello.jar
Well, the Java world has very different expectations of what's a reasonable startup time than me. Kotlin has some sort of "scripting mode", and REPL, and it can be integrated with your IDE, so maybe it's not such a problem for people who code it on a daily basis.
I included a short script that allows ./run file.kt
in the code repository.
Fibonacci
It's not too bad. We need some type annotations which feel like they should be inferable, but it's all perfectly reasonable code. If you think I'm asking for too much, just wait until we get to Crystal; but a lot of languages could figure out that fib
is Int
into Int
.
Range loop syntax is perfectly readable, overall it's shockingly readable and concise code considering it's basically Java under the hood.
fun fib(n: Int): Int {
if (n < 3) {
return 1
} else {
return fib(n - 1) + fib(n - 2)
}
}
fun main() {
for (i in 1..30) {
println(fib(i))
}
}
FizzBuzz
Kotlin threw away C style switch
and instead introduced when
syntax, which vaguely resembles Haskell style pattern matching.
fun fizzbuzz(n: Int): String {
return when {
n % 15 == 0 -> "FizzBuzz"
n % 3 == 0 -> "Fizz"
n % 5 == 0 -> "Buzz"
else -> n.toString()
}
}
fun main() {
for (i in 1..100) {
println(fizzbuzz(i))
}
}
Unicode
As Kotlin is basically Java under the hood, it still doesn't handle Unicode correctly outside the base plane, so the last answer is wrong:
fun main() {
println("Hello".length)
println("Źółw".length)
println("💩".length)
}
It prints:
5
4
2
Data classes
Java makes it really tedious to work with just about any kind of data. Every simple data class needs explicit constructor, getters, setters, hashcode, and equals. You cannot even use ==
, you need to run .equals()
, but that would literally crash if one of the sides was null, so you need to null check both sides first, then .equals()
. It's ridiculous amount of boilerplate for basic data manipulation.
Kotlin avoids almost all of this bullshit:
data class Point(val x: Double, val y: Double) {
fun length() = Math.sqrt(x * x + y * y)
}
fun main() {
val a = listOf(1, 2, 3)
val b = listOf(1, 2, 3)
val c = Point(30.0, 40.0)
val d = Point(30.0, 40.0)
println(a == b)
println(c == d)
println(null == d)
println("len of ${c} is ${c.length()}")
}
Which prints:
true
true
false
len of Point(x=30.0, y=40.0) is 50.0
Well, we still needed to do listOf(1, 2, 3)
instead of [1, 2, 3]
, and it would complain if we tried Point(30, 40)
, but it's not too bad.
Functional programming
And how would we do map
, filter
, and reduce
in Kotlin? It looks almost like Ruby with { arguments -> ... }
blocks. Interestingly if you pass a block without any arguments, it treats as if it had default { it -> ... }
. That's a rare feature, most notably seen in Perl where it's called somewhat more cryptic $_
.
fun main() {
val alist = listOf(1, 2, 3, 4, 5)
println(alist.map{ x -> x * 2 })
println(alist.map{ it * 2 })
println(alist.filter{ it % 2 == 1 })
println(alist.reduce{ a, b -> a + b })
}
It produces the expected:
[2, 4, 6, 8, 10]
[2, 4, 6, 8, 10]
[1, 3, 5]
15
Should you use Java?
Normally I'd ask "should you use Kotlin", but that's looking at things backwards. The real question is "should you use Java" and the answer is clear and unambiguous NO! If you need to run something on JVM and interact with the "Java" ecosystem, you can do this without ever touching that miserable excuse for a language. Kotlin is to Java what ES6 was to old style JavaScript, but the improvement is much greater here. Old style JavaScript is dead, completely replaced by ES6+ JavaScript, and that's the fate that should befall Java as well.
There are other JVM languages like JRuby, Clojure, Scala, and so on, but they are essentially different languages, with different semantics, and with varied interoperability story. Kotlin is just Fixed Java, nothing more, nothing less.
So please don't use Java, ever.
Code
All code examples for the series will be in this repository.
Posted on November 24, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 8, 2024
November 19, 2024