# New operators

**URL:** <https://discuss.kotlinlang.org/t/new-operators/4125>\
**Category:** Language Design\
**Created:** [August 10, 2017, 8:35am UTC](https://discuss.kotlinlang.org/t/new-operators/4125 "2017-08-10T08:35:46Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![maaartinus](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@maaartinus](https://discuss.kotlinlang.org/u/maaartinus)\
**Post date:** [October 29, 2017, 7:24pm UTC](https://discuss.kotlinlang.org/t/new-operators/4125/22 "2017-10-29T19:24:18Z")

</div>

> I think that having three different equals operators in the language runs very much against Kotlin’s ambitions to be clear and simple.

@yole But the real problem is not having three different operators, but having three different notions of equality. And this is already the case and can’t be changed. Whenever there’s something like `>=`, then a corresponding equality operator should be provided. As the consistency of `compareTo` and `equals` can’t be enforced, the induced equalities will differ.

_Given three notions of equality, having three corresponding operators is the simplest solution._

@nbengtg To me, recycling `=` for equality is worse than using a new third operator, assuming we can find something readable. For “not equal according to `compareTo`”, `<>` is the obvious choice, with the mnemonics of “`compareTo` returns something `<` or `>` than zero” or simply “less or bigger”. For the opposite, I’d suggest `!<>` which reads as “neither less nor bigger”. This way, all operators based on `compareTo` contain some `<` or `>`, which makes it pretty clear.

@Dmitry_Petrov_1 You’re surely aware that `int -> float` and `long -> double` are lossy and you won’t repeat the Java mistake to call them widening, will you? The only _really_ widening conversions between integral and floating-point types in Java are `byte/short -> float` and `byte/short/int -> double`.

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [October 29, 2017, 10:06pm UTC](https://discuss.kotlinlang.org/t/new-operators/4125/23 "2017-10-29T22:06:27Z")

</div>

I like `<>` (and `!<>`) operators. They look funny, it means that reader will notice them. It’s a good idea, if a problem is real (honestly I can’t imagine the situation where I would want to use it, but my imagination might be limited).

What I don’t like is operator `===`. It shouldn’t exist. Problem with Java’s `==` is that it means something different for referential types and it was easy to compare things like strings or boxed numbers and sometimes it would even work. Kotlin solved this problem, but `===` is easy to mistype when you wanted to type `==`, it’s hard to spot, it will work sometimes and surely it’ll introduce subtle bugs. It should be replaced by something like `x referentiallyEquals y`.

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [October 30, 2017, 1:40am UTC](https://discuss.kotlinlang.org/t/new-operators/4125/24 "2017-10-30T01:40:59Z")

</div>

The fact that some classes implement compareTo() inconsistently with equals() is a corner case, and is important only in extremely rare cases. Having three different kinds of comparison operators in the language is a very visible feature, and will be greatly confusing to all learners of Kotlin, including those who will never in their life encounter a situation where the difference matters.

---

<div class="post-metadata">

**Author:** ![maaartinus](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@maaartinus](https://discuss.kotlinlang.org/u/maaartinus)\
**Post date:** [October 30, 2017, 3:07am UTC](https://discuss.kotlinlang.org/t/new-operators/4125/25 "2017-10-30T03:07:58Z")

</div>

@yole I don’t find it confusing at all, but people who didn’t read this discussion probably do, especially programming beginners. It’s true that the difference matters only very rarely. So I agree with you.

Another thing is the comparison of different numeric types. I guess, there’s no chance of making the above example

```auto
val a = 1
val b = 1L
a >= b gives true
a == b is not testable

```

work for `==` as it’s bound to be Java `equals` and it’s already defined for all operand combinations. So you can’t make `1 == BigInteger(1)` work, but you can make `1 >= BigInteger(1)` return true by providing an overload for `compareTo`. Now we have a much better use case for `<>` and `!<>` as they can use the overload. You can make it work for all combinations of predefined Kotlin data types and users can extend it for their own types.

---

<div class="post-metadata">

**Author:** ![nbengtg](https://avatars.discourse-cdn.com/v4/letter/n/9de053/32.png) [@nbengtg](https://discuss.kotlinlang.org/u/nbengtg)\
**Post date:** [October 30, 2017, 8:55am UTC](https://discuss.kotlinlang.org/t/new-operators/4125/26 "2017-10-30T08:55:20Z")

</div>

@maaartinus This is exactly my point. @yole I don’t think this is a corner case. As I said above in reply to

> Looks like this problem can be solved much more easily by providing a different implementation of BigDecimal

equals() and compareTo serve different purposes and are implemented differently. Specifically, I can implement compareTo(myType) for any numerical type by an extension function, but I can _not_ extend equals() as it is defined on Any. It’s not BigDecimal that is the problem, it also goes for any custom numerical type.

As for this being important only in extremely rare cases, that, I submit, depends on what areas of programming Kotlin is being used for, which, conversely, will be correlated to how well Kotlin is able to express what is needed in these areas. I am just now considering Kotlin for implementing a considerable amount of business logic. I had hoped that Kotlin would enable me to write more readable code, as compared to (!) Java, but if I can write \> instead of compareTo()\>0, but not = instead of compareTo()==0, it will not be clearer, just inconsistent, and we will probably go with Java anyway (or possibly Scala). Which is kind of sad, because I like Kotlin very much in many respects.

---

<div class="post-metadata">

**Author:** ![maaartinus](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@maaartinus](https://discuss.kotlinlang.org/u/maaartinus)\
**Post date:** [October 30, 2017, 1:46pm UTC](https://discuss.kotlinlang.org/t/new-operators/4125/27 "2017-10-30T13:46:45Z")

</div>

@nbengtg I see, I was just repeating your arguments. That’s because of this thread being damn long and because of me being a Java guy, where `compareTo` is the way of implementing `Comparable` and nothing more.

---

<div class="post-metadata">

**Author:** ![taffarel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/taffarel/32/4860_2.png) [@taffarel](https://discuss.kotlinlang.org/u/taffarel)\
**Post date:** [March 5, 2018, 11:02pm UTC](https://discuss.kotlinlang.org/t/new-operators/4125/28 "2018-03-05T23:02:20Z")

</div>

> [@nbengtg](#):
>
> Comparing BigDecimals for numeric equality requires using compareTo(), not equals(), since equals also tests scale

I’m new to Kotlin and am having this problem with `BigDecimal` as it doesn’t like the fact that mathematically `0` and `0.0` are the same thing.

I understand that what our brain expects is not the same as what an object would be. It would be like saying a piece of paper with `0` written on it is exactly the same thing as a piece of paper with `0.0` written on it. They are not.

My point is, if you need numeric equality in your test, you need to transform both sides into the same thing, like you would test a `String` using `equalsIgnoreCase()` for instance.

My suggestions as a beginner, if people agree with me:

Use `unscaledValue()` in both sides of the test

or

Create your own extension functions for this equality check somewhat like this:

```
fun BigDecimal.equalsIgnoreScale(other: BigDecimal): Boolean {
    return this.unscaledValue() == other.unscaledValue()
}
fun BigDecimal.equalsIgnoreScale(other: Double): Boolean {
    return this.unscaledValue() == BigDecimal(other).unscaledValue()
}
.
.
.

```

Another option would be extension functions overwrite member functions with same signature. But that could cause some other problems, so it is a good thing that this is not possible.

[Previous page](https://discuss.kotlinlang.org/t/new-operators/4125.md?page=1)
