Search code examples
kotlinlanguage-design

Why is Kotlin's Number-class missing operators?


In Kotlin, the Number type sounds quite useful: A type to use whenever I need something numeric.

When actually using it, however, I quickly noticed it is pretty useless: I cannot use any operators on these numbers. As soon as I need to do something with them, I need to explicitly convert them (even for comparing).

Why did the language designers choose to not include operators in the Number specification?

Thinking on this, I noticed it could be tricky to implement Number.plus(n: Number): Number, because n might be of a different type than this.
On the other hand, such implementations do exist in all Number subtypes I checked. And of course they are necessary if I want to type 1 + 1.2, which calls Int.plus(d: Double): Double

The result for me is that I have to call .toDouble() every time I use a number. This makes the code hard to read (compare a.toDouble() < b.toDouble() with a < b).

Is there any technical reason why operators where omitted from Number?


Solution

  • The problem is the implementation of the compareTo method. While it sounds reasonable and easy to add it in the first place, the devil lies in the details:

    How would you compare instances of arbitrary Number classes to each other? Kotlin could implement the compare method using toDouble(); however this has problems with equality/precision: How do you compare a BigDecimal to a Double? Using toDouble() on the BigDecimal might lose precision, and two (actually different) BigDecimals might be considered equal using this method. The mess gets even worse when you start to assume one or both types were supplied by libraries, where you cannot make assumptions on precision etc.

    In Java, the Number type is not Comparable either. Furthermore, some Number values like NaN might not be comparable at all.

    If you need a Number to be comparable, you can easily implement your own compareTo-method as extension function. This has some additional limitations though, as most Number subtypes implement Comparable, and the extension function will lose against that implementation.

    Credit for this answer goes to Roland, I only extended his comments (see on the question) into an answer.