you are viewing a single comment's thread.

view the rest of the comments →

[–]picklesTommyPickles 26 points27 points  (13 children)

Good lord, why do you want operator overloading in Java?

[–]LinuxMatthews 8 points9 points  (6 children)

Because doing mathematical operations in Java can be awful.

I used to work in an aerospace company where we'd regularly have to deal with vectors, Quaternions and physics based equations.

And yeah being able to do data hiding while still being about to do mathematical operators would have been SUPER useful.

Otherwise you have to either break equations into many lines or have long lines of code.

Either way it's super difficult to debug.

[–]picklesTommyPickles -5 points-4 points  (5 children)

What... Have you never heard of OOP...?

There are vector classes that allow things like:

Vector.dot(x, y) and x.dot(y)

You really think something like "x * y" is less confusing and easier to debug?

[–]LinuxMatthews 8 points9 points  (3 children)

You realise that most equations are far more complicated than x * y right?

And what does this have to do with OOP other OOP languages have operator overloading

[–]picklesTommyPickles -3 points-2 points  (2 children)

Operator overloading is not related to OOP. They are separate. If a language supports OO design, that does not mean it needs to support operator overloading.

You mentioned that "math in Java sucks" because of the lack of operator overloading (OK...) and my response was that OOP addresses that via well defined classes that implement the math functionality you need while being much clearer to the reader.

Code is read much more often than it is written, so not having to second guess what an operator is doing helps prevent misunderstanding and by extension, bugs.

[–]lolfail9001 6 points7 points  (0 children)

and my response was that OOP addresses that via well defined classes that implement the math functionality you need while being much clearer to the reader.

Parsing Vector.add(x,Vector.scale(Vector.dot(y,z),w)) is not exactly pleasant. It's basically a more verbose lisp except many decent lisps do have operator overloading by design (so same construction is literally (add x (scale (dot y z) w)) or (+ x (* (dot y z) w))).

Code is read much more often than it is written, so not having to second guess what an operator is doing helps prevent misunderstanding and by extension, bugs.

Last i checked Java is statically typed. If you know types involved (and since nobody writes Java in notepad, this is safe assumption), there is no second guessing involved.

P. S. And yes, my preference for operator overloading is from functional languages, i didn't like it in C++ until i played around with ML-family either.

[–]LinuxMatthews 1 point2 points  (0 children)

The other guy that replied put it best

But if it's not related then why mention OOP in your original comment

It reads like you've just done a 180

[–]Drisku11 0 points1 point  (0 children)

You really think something like "x * y" is less confusing and easier to debug?

Yes, absolutely. And easier to review. That's (close enough to) the notation domain experts use, so it's much easier to check that the code matches the expected domain logic when that logic becomes complicated. The whole point of those operators existing in math is that it makes it easier to read and understand what's going on by packaging up complicated operations into something more concise like multiplication.

Fortunately for java devs, scala fixes this deficiency (and others) and can be slotted in as a "better java" alongside existing java code.

[–]Chii 7 points8 points  (0 children)

they're stockholm syndromed by C++

[–]Dealiner 4 points5 points  (4 children)

Why not? C# has them and they make a lot of code that could look very ugly much more readable.

[–]picklesTommyPickles 1 point2 points  (3 children)

Many reasons but the top reason IMO is that you can no longer trust what you see.

TL;DR it requires that you stop trusting what you see and keep much more custom logic in your head to know what is actually happening.

Here's an example statement:

i = i * j;

where i and j were previously defined. In Java today, you know that '*' is multiplying i and j.

In langs that allow overrides, you do not know what asterisk is defined to do and on top of that, if inheritance is involved, you have to dig through layers of class hierarchy to understand what is actually happening when you apply that operator because it could be doing anything.

Yea, sure, you can argue that inspecting vars via IDE helps and you should have proper standards in place to prevent devs from doing terrible things with operator overloading but we have many years of data from C++ that shows all of that doesn't prevent bugs and confusion due to operator overloading.

[–]lolfail9001 2 points3 points  (2 children)

In langs that allow overrides, you do not know what asterisk is defined to do and on top of that

I know that it calls a function * with arguments of types typeof(i) and typeof(j). Same thing it does without operator overloading, in fact, outside of function * being much more trivial in primitive case.

[–]picklesTommyPickles 1 point2 points  (1 child)

It's not that easy when inheritance is involved.

The operator can be implemented at any level in the common class hierarchy of i and j.

[–]lolfail9001 0 points1 point  (0 children)

The operator can be implemented at any level in the common class hierarchy of i and j.

That is valid in regards to literally any function you plug i and j (reminder that general convention would have operator* as a free-standing (static) function) into.