AIUI, one of the main reasons for its limited operator overloading, as for so many other little things in Kotlin, is readability.
Kotlin lets you overload the standard operators for mathematical operations, comparisons, collections, ranges, iteration, and destructuring* — but you can’t create your own operators. Neither can you change their precedence.
As a result, overloaded operators should behave in ways that correspond to the built-in ones. (That can’t be enforced in the language, but it does its best to encourage that.) So when you see a *
or in
or to
or […]
used on a new type, you already know what to expect.
For example, the book Kotlin In Action illustrates some of these cases with a Point
class, a trivial data class holding two co-ordinates. I’m sure you don’t need me to show the code for adding two points together, or multiplying a point by a number, because it’s obvious to everyone exactly how those will work! (Conversely, multiplying two points together doesn’t have a single, obvious meaning — it could be a vector product, or an inner product, or complex multiplication,… — and so the book doesn’t show that case.)
This makes the code readable even to someone who doesn’t know the details of the classes involved.
But what about new operators?
If you were to read someone else’s code, and came across <~>
, how would you read it? What would it mean? Clearly those characters have some meaning to you, or you wouldn’t have proposed them; but someone else may have had completely different, conflicting ideas. And that would lead only to confusion, and error.
Kotlin already provides other ways to write concise, domain-specific code when you need to. In particular, non-operator methods can be marked as infix
and used in much the same way as operators — except that, being words rather than cryptic symbols, anyone can read them!
For a case in point, look at how Kotlin implements bitwise operators: not as built-in operators, nor even as overloaded operators, but as simple infix functions: and
, or
, xor
, etc. — concise, but also far more obvious and meaningful to most people than obscure symbols.
You clearly have some appreciation of this already. (I feel the same about Scala!) But this isn’t about the number of operators you can overload; it’s about whether those operators already have a meaning in the language. I’m sure the set of operators you suggest would be meaningful in some domain — but to me, I’m afraid they’re just gobbledegook. Are there really no concise words you could use instead? That way, we’d all be able to read them.
(* That’s a fair number, actually. I count about 29 operator functions you can implement — though some of those are used by more than one operator, such as equals()
providing both ==
and !=
, so it’s hard to be exact.)