📜 ⬆️ ⬇️

(Translation) Overloading operators in Scala

image

One can argue for a long time whether the ability to overload operators is the strength or weakness of a particular language. But the fact remains that there is such an opportunity in Scala. So why not use it?

The material of the article is intended mainly for beginning Scala developers.

Operator Overloading


So what is operator overloading?
In general, operators are familiar to you "+", "-", "*", "!" and many others. Moreover, sometimes the same operator can behave differently depending on what it operates with (for example, + as taking the sum of integers and + as an operation of string concatenation). The idea of ​​operator overloading is simple - if the behavior of an operator changes depending on the class of objects with which it works, then why not define a new behavior for it specifically for your class?
')
Wait a minute! But they told me that operator overloading is evil!

Operator overloading is a rather controversial topic. It is often said that this is the cause of many abuses, and this possibility in C ++ was slandered so much that the creators of the Java language deliberately abandoned it (with the exception of the "+" operator for string concatenation).

I have a slightly different opinion. If we approach operator overloading with due responsibility, then we can derive substantial practical benefits. I will give an example: many objects can be added together or summarized, so why not just use the "+" operator?

Suppose you wrote a class for complex numbers, and you want complex numbers to be added. Isn't it more pleasant to write the following code:

Complex result = complex1 + complex2;
... than ...
Complex result = complex1.add(complex2);

The first line looks more natural, isn't it?

So, does Scala allow operators to be overloaded?



Not really. More precisely, no.

It turns out that everything I read before is nonsense? This is the stupidest article I've ever read! I hate Scala. It is better to continue to program on Algol 68.


Just a second, I haven't finished yet. Scala does not support operator overloading, because Scala simply does not have them!

Are there no operators in Scala? You're crazy! I wrote something like “sum = 2 + 3” so many times! But what about the operations "::" and ": /" on the lists? They look like operators!


Alas, they are not. The whole point is that Scala does not have strict requirements for what can be called a method.

When you write the following code:

sum = 2 + 3
..., in fact, you call the + method in the RichInt class on the instance with the value 2. You can even rewrite the last line as:
sum = 2.+(3)
... if you really want it.

Yeah. Now I understand. So you wanted to tell me about operator overloading?


It is very simple - as simple as the description of the usual method. I will give an example.

 class Complex(val real : Double, val imag : Double) { def +(that: Complex) = new Complex(this.real + that.real, this.imag + that.imag) def -(that: Complex) = new Complex(this.real - that.real, this.imag - that.imag) override def toString = real + " + " + imag + "i" } object Complex { def main(args : Array[String]) : Unit = { var a = new Complex(4.0,5.0) var b = new Complex(2.0,3.0) println(a) // 4.0 + 5.0i println(a + b) // 6.0 + 8.0i println(a - b) // 2.0 + 2.0i } } 


All this is cool, but what if I want to redefine the “not” operator (“!”)?


The difference of this operator from the operators "+" and "-" is that it is unary and prefix. But Scala also supports such, however, in a more limited form than infix operators like "+".

By a restricted form, I mean the fact that only 4 can be redefined for unary prefix operators: "+", "-", "!" and "~". For this, it is necessary to determine the appropriate methods unary_ !, unary_ ~ in the class, etc.

The following example illustrates how to define the operator "~" for complex numbers, which returns the modulus of this number:

 class Complex(val real : Double, val imag : Double) { // ... def unary_~ = Math.sqrt(real * real + imag * imag) } object Complex { def main(args : Array[String]) : Unit = { var b = new Complex(2.0,3.0) prinln(~b) // 3.60555 } } 


Finally

As you can see, overloading operators in Scala is very simple. But please use this opportunity wisely . Do not define methods like "+" in a class, unless your class knows how to do something that can be interpreted as addition or summation.

Original article - Tom Jefferys, "Operator Overloading" in Scala

Source: https://habr.com/ru/post/143311/


All Articles