When exactly is the operator keyword required in Kotlin?

In Java, operators are tied to specific Java types. For example, String and numeric types in Java can use the + operator for concatenation and addition, respectively. No other Java type can reuse this operator for its own benefit. Kotlin, on the contrary, provides a set of conventions to support limited Operator Overloading.

Let’s start with a simple data class:

data class Point(val x: Int, val y: Int)

We’re going to enhance this data class with a few operators.

In order to turn a Kotlin function with a pre-defined name into an operator, we should mark the function with the operator modifier. For example, we can overload the “+” operator:

operator fun Point.plus(other: Point) = Point(x + other.x, y + other.y)

This way we can add two Points with “+”:

val p1 = Point(0, 1)

val p2 = Point(1, 2)

println(p1 + p2)

Point(x=1, y=3)


Why does this code compile?

This compiles because the overridden interface method, Comparable<T>.compareTo, is itself an operator fun.

/**
 * Compares this object with the specified object for order. Returns zero if this object is equal
 * to the specified [other] object, a negative number if it's less than [other], or a positive number
 * if it's greater than [other].
 */
public operator fun compareTo(other: T): Int

As the function overrides this, it is also an operator function.

When exactly is operator required?

operator in general is required whenever you wish to be able to use a function as if it were an operator, since operator usages are simply compiled to function calls (except on primitive types, etc.)

That is, foo += bar, for example, is equivalent to foo.plusAssign(bar), foo[bar] = baz is equivalent to foo.set(bar, baz), etc.

Personally I prefer specifying operator wherever possible even if it is not required, for readability reasons.

If MyDate were not a Comparable, and you omitted the operator modifier, comparing two dates via <, >, <=, or >= would not compile.

I couldn't find anything in the specification on this, though. However in a polymorphic sense it makes sense - why should you be able to write a < b where the type of a and b are Comparables, but not when they are a MyDate? Since you wouldn't be able to remove the "operator-ness" of this function, it makes sense that operator should be inheritable from the superclass method.


Kotlin has many features that are enabled via particular conventions. Those can be identified by the use of an operator keyword. Examples are ranges, operator overloads, index operators, destructuring declarations and more.

If we want to compare two objects in Java, for sorting e.g., we implement the Comparable interface with its compareTo method. This is also done in Kotlin, but with much better support and a shorthand syntax. If you implement this method in a class, you can use all the nice operators like <, <=, >, >= with that class out of the box. These operators are translated to appropriate calls of compareTo by the compiler:

obj1 > obj2obj1.compareTo(obj2) > 0

The interface method compareTo in Comparable already defines the operator keyword, which makes it redundant to add the keyword in your own implementation.

In your example, the operator keyword is not mandatory since the overridden method already defines it.