Fast and ergonomic annotation processors for Kotlin

What is KSP?

KSP (Kotlin Symbol Processor) is a new API from Google for writing Kotlin compiler plugins. Using KSP we can write annotation processors to reduce boilerplate, solve cross-cutting concerns, and move checks from runtime to compile-time.

While we already have annotation processors in Kotlin through kapt, the new KSP API provides promises speed and ergonomics.

Firstly, KSP is faster since kapt depends on compiling Kotlin to Java stubs for consumption by the API used by Java annotation processors. Compiling these stubs takes a significant amount of time, and since KSP can skip this step we can write faster processors.

Secondly, KSP…

Layer cake

In previous entries in the series, we learned the importance of a model and an ubiquitous language. We also understand that our app has to deal with some activity of interest to the user — the domain. A layered architecture is a tool for isolating this domain. This is because there is a world of implementation detail outside the domain. Detail like talking to the system via Intents, writing to a SQL Lite database etc. We don’t want everything crowded together — we would like to see the model as a system in a single glance.

Consider a “god object”…

Crunching knowledge

In part 1 we learned the need for a model. But how do we arrive at a model?

Crunching Knowledge

To tackle the complexity at the heart of software, we can’t just sit in a room by ourselves and write code. “Crunching knowledge” means talking to stakeholders and domain experts to distill a model. Evans gives the following example of the following conversation in the context of printed circuit board (PCB) design:

Expert 1: It isn’t enough to say a signal arrives at a ref-des, we have to know the pin.

Developer: Ref-des?

Expert 2: Same thing as a component instance. Ref-des…

The need for domain-driven design

We’ve come a long way since we wrote the entire logic for a feature inside a Fragment or Activity. But sometimes it’s hard to navigate the alternative approaches with their repositories, domain objects, DTOs, and use cases. What overarching purpose do they serve? Sometimes our understanding never surpasses the cursory, since sample projects are minimal and the primary sources are written from the point of view of enterprise web developers.

I’ve always wanted to return to the canon for repositories, domain objects and their like to ensure my understanding was correct. Reading Eric Evans’ Domain-Driven Design helped me place these…

Photo by Ankush Minda on Unsplash

The need for higher kinds

You may have noticed that many kotlin-stdlib classes like and implement a function:

Some of the worst software engineering disasters arise from trying to achieve code reuse too soon. What if we tried to share ? If we did this, we could then write a function that consumed either a or a :

The classic way of doing this in object-oriented programming would be to extract a common interface or abstract class. But look what happens in the attempt below:

Both implementations of now have a return type of . If we…

What it is and why it matters.

You can call it “beautiful code” when the code also makes it look like the language was made for the problem.

Ward Cunningham

If you have a sound continuous integration practice, your pull requests will be automatically evaluated for test coverage and compliance with code conventions. But it’s your teammates who will evaluate the degree to which the submitted code is high quality through being idiomatic. What does this mean?

Photo by Kelly Sikkema on Unsplash

What does “idiomatic” mean in general?

If we have DuckDuckGo installed, we can pretend our web searches are terminal scripts:

HTTP clients in idiomatic Kotlin

Our use case

The Trade Me ecosystem is stateful. Auctions on the site run through a lifecycle where members create, bid, win, and lose. Some of these states are quite difficult to achieve: in our squad, engineers would need to have two separate logged-in instances, the Trade Me web app running on their local machine (Alice), and the Trade Me app running on their phone (Bob). They would then click through multiple forms on the web app just to get the auction to the desired state. All of this just to test one part of the app.

The lost summary for an auction is only available after you take the ‘L’.

Additionally, because some states are dependent…

Arrow of outrageous fortune

Arrow is an exciting development for Kotlin developers interested in functional programming and, more broadly, pushing the limits of the Kotlin compiler. It was recently lauded in Thoughtworks Tech Radar:

Our initial positive impressions of Arrow were confirmed when using it to build applications that are now in production.

The ArrowKt logo

That being said, it’s not an easy framework to learn. There’s a sample Android project by Jorge Castillo, but it can be a bit intimidating. Let’s try and unpack some of the functional programming (FP) goodness in this article.

Package structure

In FP, we aim for an application constructed with pure functions. …

Do interfaces belong in Android projects?

Recently there’s been a bit of buzz around over-engineering in Android projects. Unfortunately, one person’s mere engineering is another’s over engineering. And vice versa. It’s like we’re trying to strike a median between Fizz Buzz Enterprise Edition and Big Ball of Mud.

For my own side, I want to present an argument for one particular language feature in Kotlin that some consider over-engineering, but I love to see used correctly in Android projects. Think of it as a BuzzFeed article for the enterprise-scale Android engineer: Seven Reasons To Love Interfaces.

1. You’re already using them implicitly

In our small tests (unit tests), we examine the dependencies…

Using fold in Kotlin

That should be map

Let’s say we need to convert a list of numbers to letters. For , I want . For , I want and so on. One way to do this is the following:

But we should have been listening to Justin Bieber and the memes:

That should be map

The combinator saves us the hassle of a loop and a mutable list:

So we can see that transforming one collection into another with a one-for-one correspondence should be expressed with . …

David Rawson


Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store