Finding Kotlin

I can't recall how I came about Kotlin. I know it was several months 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.

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, 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. 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, strongly typed, type inference, name spaced, tail recursion, good async support, first class functions, record types/data classes, free floating functions, potential for multi-platform, operator overloading, extension functions, calling functions without parentheses, vibrant community, discriminated unions, and lastly great build and onboarding experience. Extras would be higher kinded types, 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.
  • Monadic comprehension is available via a third party library.

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. Now Python is a hard sell to me, unless you have a large existing code base.

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. But there is no unit test coverage. This may cause a build or runtime error.

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.

I also felt Python had deviated from the newer trend with mobile. Highly concurrent connections, rich data, and querying support. Things like GraphQL are not as well supported in Python.

Onward

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 {
      world
    }
  }
`;

I've been delving deep into this lately. I think graphql is great for React and mobile. 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 section.

Build & Tooling

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. I'm still delving into GraphQL and Kotlin.

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, and exposed endpoints. 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.

As to exposed endpoints. There are a number of different ways to expose / interface with a service. Whether it be a REST endpoint, GraphQL, or pub / sub model. The JVM has a large swath of libraries. It may not be idiomatic Kotlin but you can write wrappers around it.

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.

The functional tilt is also very strong. If you go back and watch Kotlin Conference from last year. Functional was mentioned quite heavily. Looking at ArrowKt. I have about 70% of what I wanted language wise. With remarkebly better tooling and integration.

In the End

Why Kotlin? How do you convince a company to switch to it, or try it. I haven't been able to for a myriad of reasons. There are alot of good reasons for Kotlin. To me the biggest point is it feels pragmatic. There is great tooling, ease of learning, and great interoptability.

But the language doesn't matter. What matters is delivering value to the customer. If the customer is on a PHP stack and has a large code base. Then it's best to help them move to better standards, or improve the code.

I went through this moving in a role. Slated to move from C# to Python, Python developers were less expensive, and quicker development. That is rife in pain. Python is not the best bedfellow in a Microsoft ecosystem.

In the end the language of choice. Is more so in delivering features in a timely, maintainble manner. I think there is great benefit to the above technical features. But if I have to rewrite a number of standard libraries, and CI/CD systems. Then it's not the best choice.

But if you have to throw the baby out with the bath water. Scale when you need to not before, and avoid premature optimization.