Kotlin, use operator overloading BUT use it carefully

Marko Novakovic
4 min readJun 19, 2021

“With great power comes great responsibility”
Uncle Ben, Spider-Man

Kotlin is great and expressive language. One feature that CAN greatly improve expressiveness and readability are operator overloading. Key thing here is CAN improve, you have to use it carefully and not go over the top. If you abuse it your code can be as unreadable as it can be. With that said let’s see what good implementation looks like.

Full code.

Examples we will use to showcase this are:

1. Food ordering application. We will have Cart, Article and Topping.

2. Simple state change.

First let’s give a bit of a theory about operators and operator overloading in Kotlin. You have fixed set of operators and you can’t create your own, you can just use existing ones. You do it like this operator fun OPERATOR() {} and you follow operator signature but operator fun is a must. Some operators are invoke/(), plus /+, plusAssign /+=, get /[] etc. You can read documentation to learn more.

Lets start with food ordering application. Structure would look like this:

Pardon my MutableList usage. Using List is much better and adding Article would ideally return new Cart object and you would update it with Kotlin data class copy() method. This is for the sake of simplicity.

Our first use case is adding Article to Cart. Most “primitive” version of this would look like this:

If we take a look at how operator overloading is used through Kotlin itself we will find MutableList implementation of +=/plusAssign.

This is something we can look up to and create our own +=. It would look like this:

This is readable right? You know what’s it doing, it’s intuitive. Simply put, great. There is another operator : +. We will not use it for this because + assumes that expression returns something val a = 5 + 6. something + somethingElse returns (should return) value. In our example it would be confusing, += updates object, + returns value.

We will do the same thing for Article and Topping.

Now, you may be tempted to implement += for Cart and Topping. That is an example of operator overloading hurting your code and design. Why are we adding Topping to Cart? Where does that Topping go? On what? It doesn’t make sense logically nor semantically. You can see that this is easy line to cross so be careful and RESPONSIBLE.

Other use case would be simple state change. Lets say we have scenario where we track is some part of the UI expanded/collapsed and we want to toggle it with button. This can be visible/invisible etc. Whats important with this example is that it has TWO possible values, like true or false.

That state could look like this:

When we click that button state should change? If it was Collapsed it should be Expanded and vice versa. We can do that with if checks but it’s again more primitive version:

Let’s look at something we all already know and use every day. !.

This looks much better!

I will end this post here in order to keep it reasonably long. You can reach out to me if you have some better example, need help etc.

I will encourage you to explore other operators, especially invoke(), in, get, set could be useful.

You can find full code here.

--

--