Why Kotlin?

Why Kotlin?

Finding Kotlin

I can't recall how I came about Kotlin. I know it was before M1 was announced. At this point I was coding Python in the day. In love with F# at night. But the big pain point with F# to me was developing in Linux, was errm less than ideal. We have dot net core now, but back then that was a pipe dream. Even now dot net core feels lack luster on Linux for development. For F# at least.

Once a month I would try out a new language, stack etc. I also worked with Java during the day. I liked the JVM, I felt the CLR was better from a technical perspective (no type erasure or proper generics, expression trees, async). But it felt so janky with mono under Linux. The build system also, I mean Fake and Forge are great. But my preference was gradle. Fable also deserves a call out and is gorgeous for multi-platform. I just started playing with F# again, and man I missed it. The development on Linux still pales to Intellij and Kotlin, but I digress. Spoiler here I still don't recommend F# or dot net core.

So I was trying out nim, d, rust, c, c++, haskell, ocaml. From these I extrapolated a base set of requirements for my ideal language.

  • Pattern matching
  • Type unpacking
  • Ttrongly typed
  • Type inference
  • Name spaced
  • Tail recursion
  • Good async support
  • First class functions
  • Record types/data classes
  • Free floating functions / Higher Order Functions
  • Potential for multi-platform
  • Operator overloading
  • Extension functions
  • Infix functions / Calling functions without parentheses
  • Vibrant community
  • Discriminated unions
  • great build and onboarding experience.

Extras would be higher kinded types(see KEEP-87), active patterns, currying, and monadic comprehension. It was a pipe dream, I thought.

Now Kotlin doesn't have all of those things. For example.

  • Pattern Matching is sort of weak, but it's much better than a switch
  • Async came much later but it is now stable! This depends on your library of choice.
  • Monadic comprehension is available via a third party library.

Pattern Matching

enum class Role {

fun grantAccess(role: Role) {
    when(role) {
        is ADMIN -> grantAdmin()
        else -> grantNonAdmin()

fun grantAccess(role: Role) {
    when(role) {
        is ADMIN, USER -> grantAdmin()
        else -> grantNonAdmin()

Type Unpacking

val (userName, userRole) = Pair(Jane, Role.Admin)

Tail Recursion

Record Types / Data Classes

data class User(val id:UUID, val name:String)

Operator Overloading

var a = 1
var aPlusOne = a++


Now the immutability is at compile time, it's not inferred at run time.

// Immutable
val x = 1
// Mutable
var x = 1


Functions without Parentheses

infix fun Int.shl(x: Int): Int { ... }

1 shl 2

That's not the best part. The best thing is when you have a lambda as the last paramater to a function it can be passed in. Look at the forEech function.

infix fun <T> Iterator<T>.foreach(operation: (element: T) -> Unit)

listOf(1,2,3,).forEach { println(it) }

Some of these are limits of utilizing the JVM. But despite that it allows for a nice blend of functional and object orientated programming. As I was writing it, I was literally able to think like I did in python. But with types, and better performance. The little bit of ramp up time initially was getting familiar with the micro-service libraries I was utilizing.

Why not Python

Why wasn't I using python in my side projects? It's a common sentiment to use python in your side projects. It's quick to develop, has a rich ecosystem, and a vibrant community. At this point if I was doing something for profit I would use python. But I was doing this to learn as much as build.

Looking a step further. During the day I found long term maintenance issues with python. Due to it's type system. Someone refactors a function, but misses a call deep in the code base. A type system would catch this but not python, until runtime. Performance also takes a hit, hence projects like pypy. Wherever I've worked whenever we start talking multithreading, we just up and move to another ecosystem.


It is very often that the back-end is just a piece of the puzzle. More often than not it is the broker for data. Consumed by a front-end, mobile or some other point.

This is similar to the Amazon mantra of an API for everything. Going in line with that is the idea of providing a library. Something that is consumeable and type safe in a given language.

We have a pretty much standard path way around the client facing side.

  • Web is generally TypeScript
  • Mobile is Swift/Kotlin or more than likely React Native

With Kotlin multi platform. We can write modules that output to the target platform. Some of this can be alleviated by a swagger contract. But if we veer outside of that, writing an asynchronous pub/sub model. That is a manual interface.

Why not compile that message interface coming from the server to Swift, TypeScript, JVM. One piece of code that then covers all of your target platforms.

With the back-end defining the message contract. It is emitting the latest compile tested interface. There is no risk of a team having to manually define an interface then missing a property.

To an extent you can write React/Angular/Vue in Kotlin. The pattern matching is such a life saver to me. But iOS is still buggy. I would wait on doing a front-end/client in Kotlin. But writing the data libraries. That is an easy win.


I was talking to someone trying to explain why to use this language. I then read this article. There are a number of articles on why to use Kotlin. It's a question of why are you looking at another language? Are you addressing maintenance, performance, spending too much time fighting the type system, etc? Kotlin is not a magic solve all bullet. It's golden for the backend, but rough around the edges in other areas.

There are so many languages out there right now. From Go, Rust, Java, Scala, C#, F#, Python, Ruby, Elixir, Nim, Crystal, OCaml, Haskell etc. At this point I would strike any dynamic language for a backend service. As I've noted there is a reason type safety is being bolted onto JavaScript, Ruby and Python. Remember when the dynamic languages came to prominence, the enterprise languages didn't have type inference. It was nastiness like:

Person bob = new Person("bob")

The type system was largely a pain, something you had to fight against. Coralling it against my will. I honestly feel like bashing my head against a wall when writing go. It's weak type system is such a pain. I'd rather go back to a dynamic language.

So that's trend one type safety. What's the other? Multi platform! The ability to write code once and reuse it across several platforms. I'm a backend developer and site reliability engineer first. I spend my time there because it's crucial for a good frontend experience. But I also know my front end team, be it mobile or web. They need to consume my services. I want to make it easy as possible, and performant.

Now Kotlin is still in it's toddler stage with multi platform. There is no way I'd recommend someone to write an iOS application in Kotlin for production. I'd be hard pressed to even recommend you write a React or Web front end in Kotlin. API backend and Android, solid gold.

Despite this it's not all frownies. We can take baby steps to ease our platform interoperation. As an example I can take a common data class, and export modules for Objective C, JVM, and JavaScript. In the context of an API I can write a class once, and have it properly cast with the expected type safety to all consumed targets. This libary can then be inherited by the team implementing the frontend.

More specifically we craft a User library that handles getting a user's profile information, and editing it. There is the common data type associated with each portion. Then methods to retrieve and post the data. With the multi platform, I can create artifacts for multiple targets. Say web, android, ios, and backend. Then have each service consume that library.

I have been working a lot with React and Kotlin lately. It is still very rough around it's edges. But working with a Rest API I wrote in Jooby, that returns a common data class. Allows me to directly consume and cast that in the React code. Making compilation ensure I accesss only valid properties. This is a net win, but again rough edges.

Then there are the other parts, like graphql...

const query = gql`
  query {
    hello {

I've been delving deep into this lately. I think graphql is great for react. But I have very little idea how to appropiately approach migrating this over. My gut is telling me to rewrite it, but that is a rabbit hole I don't have time for right now.

So with Kotlin and React, if you're using graphql. Wait! If using REST, and you have a standard design library. Develop components per micro service. So you build a micro service to handle updating user profiles. Have that team also generate out the components for that scetion.

Then there is gradle, while gradle is a beast in it's own right. It is still far and away my favorite build tooling.Add in the fact that gradle supports a Kotlin DSL. The biggest pain point right now is documentation, but that is coming shortly. One language for literally everything.

I honestly thought the intermixing of Java and Kotlin in one project would be a big selling point. But honestly it hasn't been. Whenever I present features like null conditional checks, data classes, property access, etc. The Java developers I've mentioned to this don't want the added complexity. While it's nice in practice to be able to slowly migrate. It seems to be rarely sought after. Additionally slowly migrating a project, seems less ideal than starting from fresh. The win with java interopability, is use of existing libraries and ecosystems.

That being said, the interoperation is great with the JVM land. There area already a number of libraries and frameworks. There are just new extensions that make use of Kotlin features.

There is only one instance where I have needed to fall back to Java. That was with GraphQL-SPQR. A bug in annotations required some of it to be cast in Java.

It is built by an IDE company, they know tooling. There is a reason C# and Visual Studio are golden. They write the IDE for that language. This is much the same experience. The tooling is phenomenal for Kotlin.

Multi platform not just in the sense of targets. In regards to the development environment. Intellij works perfectly on Linux, Windows, or Mac. This is my biggest gripe with C#/F# is it works best on Windows. You should allow your developer to work on the platform that suits them best. With optimal tooling experience.

Multi Paradigm

There are several stages to writing Kotlin code. From full competence, to loose understanding. The core syntax can generally be learned in a day. Look at my Python to Kotlin guide. The syntax feels remarkebly similar.

You can write Kotlin in whatever way fits you best. I write mine with a very functional tilt. Focusing on side effect free functions, with immutable data structures. Classes are by and large avoided.

Or you can do a Java light syntax. Doing a number of interfaces, with inheritance building off of each other. Using dependency injection where needed. I'm going to stop here, because I really don't do OOP. I'm more opt to use currying and partial application for inheritance.

Once you have down the basics of classes, inheritance, extensions, etc. You can start delving into infix functions.