Skip to main content
gamedev.net
🔒 Locked

[java] Java No Operator Overloading Why?

Started by Preacher 28 replies 4k views
Original Post
Preacher
Preacher
Just wondering why Java didn't implement operator overloading as have just converted a quaterion camera from c++ to java and the maths equations in java is just painful. Was there a good reason for leaving out op overloading?
shmoove
shmoove
It was a matter of taste. The creators of Java decided that operator overloading can cause a lot more problems than the ones it can fix. And since Java is a language that is supposed to make shooting yourself in the foot as hard as possible, they kept it out.

shmoove
Preacher
Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations. Of course it can be abused, i just think that its way to useful to just drop, have they ever considered introducing it i wonder, maybe i could send sun an email ;)
shmoove
shmoove
Well, it's just syntactic sugar. You can do exactly the same without it, but the code will look different. Hell, you could even write a small preprocessor that can replace "overloaded operator syntax" to regular Java syntax right before compilation if it's that important.

And I'm sure you can send Sun a letter, but you'll probably have some more luck (though not much I wager) by becoming a JCP member and starting a JSR.

shmoove
Preacher
Preacher
All good, i must admit i've haven't much experience making game engines its just as i siad my first try at making a quaterion camera was not helped by the fact that having to use methods to add, dot product etc.. vectors confused the matter further. I'm sure i'll get used to it in time and i didn't think of some of the ideas presented. So no to operator overloading then ;)
TheBluMage
TheBluMage
Quote:
Original post by Anonymous Poster
Quote:
Original post by Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations.


Nope.

Only if your OOP skill is poor do you need op-overloading.

That's not necessarily true. Operator-overloading, while it can cause problems while it's being implemented, can also make code a lot easier to read when they are used. Honestly, which is easier to read?

This:
BigInteger num = a + b - c * d / e;

Or this:
BigInteger num = a.add(b.subtract(c.multiply(d).divide(e)));

True, you can get by without operator-overloading. Even the best OOP programmer would probably agree that the first example above is much easier to read and write, though. Since part of Java's purpose was to be simple and get rid of unnecissary complications, I have to agree with their decision to keep operator-overloading out of the language. However, to an experienced programmer operator-overloading can, when used properly, clarify code and make its meaning clearer. (I guess that's probably one reason why there's more than one programming language. [lol])
Trap
Trap
BigInteger num = a.add(b.subtract(c.multiply(d).divide(e)));
(setf num (add a (subtract b (multiply c (divide d e)))))

BTW: "add" is just as ambigous as "+"

[Edited by - Trap on December 16, 2004 7:49:32 AM]
Strife
Strife
Quote:
Original post by Anonymous Poster
Quote:

BigInteger num = a + b - c * d / e;


Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.


No, not at all. It's called "order of operations."

And I dispute your claim that good OOP shouldn't use operator overloading. Really what all that comes down to is what your definition of "good" OOP is.
capn_midnight
capn_midnight
Quote:
Original post by Strife
Quote:
Original post by Anonymous Poster
Quote:

BigInteger num = a + b - c * d / e;


Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.


No, not at all. It's called "order of operations."

And I dispute your claim that good OOP shouldn't use operator overloading. Really what all that comes down to is what your definition of "good" OOP is.
Don't bother, good little OOP coders cringe at using operators on primitive types anyway.
AndyTX
AndyTX
Operator overloading can certainly be abused, but you're looking at some extremely basic examples. For the record, Direct3DX 9 has a C++ implementation that uses operator overloading.

Anyways operator overloading goes far beyond writing "+" instead of "add()". It starts to get cool when combined with templates (for example, any list storing objects with a < operator can be sorted using "sort", or unique/associative using "set" or "map").

If you want an advanced example of operator overloading in the context of template metaprogramming, check out LibSH at http://www.libsh.org.

However since Java does not have templates, then yes: you lose a lot of the advantages of operator overloading.
justo
justo
Quote:
for example, any list storing objects with a < operator can be sorted using "sort"


correct me if i'm wrong, but isnt that just the equivalent of implementing the Comparable interface in java? your example of overloading is still debatably useful syntactic sugar...and what youre really talking about is templates anyway.

personally i think operator overloading can be nice, but its unnecessary and can often obfuscate more than what it is replacing...especially, as the AP pointed out, when symbols can mean completely different things to different people.

i like being more explicit, but thats just my style. just set up a preprocessor if it's not yours.
capn_midnight
capn_midnight
Quote:
Original post by justo
Quote:
for example, any list storing objects with a < operator can be sorted using "sort"


correct me if i'm wrong, but isnt that just the equivalent of implementing the Comparable interface in java? your example of overloading is still debatably useful syntactic sugar...and what youre really talking about is templates anyway.

personally i think operator overloading can be nice, but its unnecessary and can often obfuscate more than what it is replacing...especially, as the AP pointed out, when symbols can mean completely different things to different people.

i like being more explicit, but thats just my style. just set up a preprocessor if it's not yours.

because by defining an operator instead of implementing an interface, you can write containers that can hold both primitive types and class types. If you implement an interface, then you will have to box those primitive data types. ugly code ensues.
AndyTX
AndyTX
Quote:
Original post by justo
correct me if i'm wrong, but isnt that just the equivalent of implementing the Comparable interface in java? your example of overloading is still debatably useful syntactic sugar...and what youre really talking about is templates anyway.

Agreed, it is mainly the templates that give operator overloading power, although they can also do some very cool things when combined with recursion :) As capn_midnight noted as well, it allows more flexible containers without needing to "wrap" any existing objects in this interface.

Quote:
Original post by justo
personally i think operator overloading can be nice, but its unnecessary and can often obfuscate more than what it is replacing...especially, as the AP pointed out, when symbols can mean completely different things to different people.

Agreed. Like most programming language features, it can be misused. However, that isn't a point for its global disutility.

There are also other things that you can do with operator overloading that are somewhat cool. For example, you can make a data type interchangable with a primative. I've seen people who code "float" classes that compile down to using the primative type directly, but give them the flexability to change between float and double, rounding modes, implementations of "_ftol", etc. It can be pretty powerful actually, and allow another level of abstraction.

Of course it isn't necessary to accomplish anything, but neither is OOP. Both are just tools that in some cases can make the management of larger programs easier, and reduce bugs. Of course both when misused can do the opposite!
TheBluMage
TheBluMage
Quote:
Original post by Anonymous Poster
Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.

As was mentioned by Strife, the order of operations comes into play and naturally implies what will be done first. Yes, operator overloading is just syntactic sugar, but when you get down to it, so is every other part of any high-level language. It's all just sugar that wraps the underlying processor commands. Even assembly could be concidered syntactic sugar, as it uses words (ADD, SUB, MUL, DIV, MOV, etc.) to hide the 1's and 0's that are actually getting fed to the processor. Our lives would be a lot harder without syntactic sugar.

Quote:
Original post by Anonymous Poster
*

Has 5 standard meanings, just in basic programming, just off the top of my head. (multiply, cross-product, any-char, any-char-except-dot, FSM-0-or-more). I'm sure if I sat around all day I could think of 3 or 4 more common meanings.

The word 'multiply' has six standard meanings, just looking in my dictionary:

multiply1
1. To increase the quantity, amount, or degree of.
2. Math. To determine the product of by multiplication.
3. To become more in number, amount, or degree; increase.
4. Math. To determine the product by multiplication.
5. To grow in number by procreation; propagate.

multiply2
So as to be multiple; in many ways.

I won't go into the word 'add', as I would have to sit here most of the day typing.

Quote:
Original post by Anonymous Poster
Answer: all of them, if you're writing parsers. Because the "standardization" on the first operator used in grammars is so weak that all the above are used frequently :(. They also mean 6 different things, if you're writing parsers. Confused? You will be...

Speaking for myself, the symbols didn't confuse me anywhere near as much as the arguments against them. (No offense.)

Quote:
Original post by Anonymous Poster
It's a nice idea to think that the use of simple operators is "easier to read", but it's an idea that any professional programmer ought to soon realise is a pipedream: After more than 2000 years of history, Mathematicians *still* haven't managed to standardize on symbols, and they have a lot more to play with than programmers do. IMHO it is naive to think that a symbol means the same thing to different readers, and it's blatantly not true.

Unlike mathematical symbols, programming languages can easily be standardized, though that decision hasn't been made yet for Java. If you think about it, the mathematical symbols we use are much more universal than the words used to represent their meaning. Pick out at random a programmer who doesn't speak English and ask him or her to interpret the following:

num = a + b - c * d / e

Then ask him/her to interpret this:

num = a.add(b.subtract(c.multiply(d).divide(e)))

Which one do you think s/he will understand quicker? In my opinion, it's naive to think that an English word will mean the same thing to different readers.

I have nothing against the decision to avoid operator-overloading in Java - it makes sense for this language. The technique itself, though, can be a very powerful tool and shouldn't be dismissed as something reserved for people with "poor OOP skill".
Tron3k
Tron3k
It's too bad you can't extend the Java language as you wish, like you can in Lisp.
“[The clergy] believe that any portion of power confided to me, will be exerted in opposition to their schemes. And they believe rightly: for I have sworn upon the altar of God, eternal hostility against every form of tyranny over the mind of man” - Thomas Jefferson
Raghar
Raghar
Yes operator overloading, yet again.
Operators are for example:
new
)
>
:
=
,

and imagine overloading this ";"

Of course Java does have operator overloading. Did you ever seen this? System.out.println(" line "+variable) ;
It's operator overloading described in the Java language specification. Java, however doesn't alow to define your own extremely "clever" ways how to ... It's one of big advantages, if you have hunger for operator overloading use an advanced IDE and do your worst. (Just the output files would be readable by any standard compiler, and by some programmers.)

So if you'd like to overload add for vectors, then it might be interesting how your code would look if you'd use some unstandard add in the mix.
And how would look operator for dot and cross product?
AndyTX
AndyTX
Let's be clear here though: I think most people are in agreement that operator overloading should not be in Java. Java is intended to be a simpler language and should remain that way: many question the introduction of generics and other more advanced features into Java, as it begins to erode the very reason that Java is good in the first place.

That said, operator overloading DOES have its place, beyond simple syntactic differences (see my previous posts). Can you accomplish the same things without it? Certainly. But similarly you can accomplish the same things as Java can in assembler (a VM assembler if you want to split hairs).

Can operator overloading get confusing? Absolutely. Can long method names on simple objects (like n-tuples or matrices) get confusing? Of course. However in certain situations both of these conventions can make things EASIER to read, provide MORE power and generally help the programmer.

I will agree that operator overloading can be somewhat dangerous in the hands of a novice who will be temped to just start providing automatic casts, and operator overloads for every situation. However if you truely understand the tool and what you are doing, it is indeed useful.

I would suspect that there would be a greater proportion of C++ coders that understand what is going on at the base level than Java coders. This isn't meant as an insult at all (personally I use both languages for different things), but rather an exact expression of the target market of both products. With that in mind, it's probably best to keep some of the more advanced and less-frequently-used programming language features OUT of Java. That is, indeed, the point.

[Edited by - AndyTX on December 17, 2004 12:46:06 AM]
C-Junkie
C-Junkie
Operator overloading breaks the philosophy of oop, so java avoided it, since it trys to stick ot a strict OO philosohpy. (that way, for example, you can't have things outside of classes, either)

C++ only has it because it's multiparadigmed and allows you to create more natural constructs.

Operator overloading confuses the OO concept of sending a message to an object.

object.message(parameters).

One form for calling a function. Very simple.

object + parameters

would be another form. For what reason?

I have a toy language of my own that's got some nifty features w.r.t. operators, since it's not object oriented (unless you VERY loosely interpret that word). For example, "if(currentNum in? seenNumbers)" is a valid statement.
capn_midnight
capn_midnight
If Sun were really worried about breaking the OOP philosophy of Java, then they wouldn't have introduced the overloaded + operator for string concatenation. It's tatamount to hypocrisy.

And if Sun were worried about elliminating possible ways the programmer could mess things up, and increase readability, then they would get rid of annonymous inner classes (egad, my eyes, it's like fire)
Mayrel
Mayrel
Quote:
Original post by Anonymous Poster
Quote:
Original post by Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations.

Nope.

Only if your OOP skill is poor do you need op-overloading.

Can you justify that claim? In what manner is operationg overloading incompatible with object-orientation?

I understand object-orientation to be comprised of polymorphism, encapsulation and inheritance.

The key point is here polymorphism. Polymorphism is a Good Thing because it allows you to use the same code to perform sematically equivalent operations upon objects of different type using the same code.

e.g. in C++
template<typename T> T average (int size, T *array) {  T r = 0;  for (int i = 0; i < size; ++i)    r += array;  return r / size;}


This works on any type of object that defines (1) a conversion from 0, (2) a += operator, and (3) a / operator.

Requiring += is a bit nasty. But I can use polymorphism again to define += for any type that supports addition and assignment:
template<typename T1, typename T2>T1 & operator += (T1 & a, const T2 & b) {  return a = a + b;}

Quote:

OR: if you are doing some niche stuff (e.g. financial services work). In that case, however, you SHOULDN'T BE USING JAVA - if what you *really* want is a mathematical language, you should be using a mathematical language, and preferably a pure functional one, and only using java for the non-mathematical bits.

Then it's lucky that Java makes it so easy to use functions exported from programs written in a mathematical language (whatever that is).

Oh, hang on... It doesn't.
Quote:

For 3D engines, there's no way you need op-overloading. Mainly because op-overloading produces inferior engines: there are too many things you need to do in an engine, and yet only about 6 operations that have stnandard meaning; these are way too insufficient.

For instance, in a 3d engine you need:
- add vector A to B, returning result C, without modifying anything
- ditto, but store result in A
- ditto, but store result in A and normalize it
- any combination of 1 above with 2 or 3 simultaneously

Seeing as each of these creates different numbers of temporary objects, and is used in different algorithms, you really need all of them (sooner or later), but there are only TWO standardized operators for addition: + and +=

How is this a problem?
c = a + b;a = a + b;a = normalize(a + b);

Simple. And I didn't even need to use +=.

What's that you say? It's inefficient because of those temporary objects? So you think that you're better at optimising away temporary objects than the compiler, do you?

Premature optimisation is the root of all evil.
Quote:

And this is a simple case.

Most of the vector algebra you need to do benefits greatly from having the verbosity of words. Please c.f. the discussions in the 1980's and 1990's about whether we should use "long variable names". Most of the arguments in favour of long var names apply to non op-overloading (in addition to the other arugments against op-overloading).

Yes, you're quite right. That's why Java doesn't use short names like "+" and "int" for commonly used concepts.

Addition is not a bizarre concept. You don't need to think outside the box to figure out what "a + b" is intended to do when a and b are vectors.
Quote:

The only time you need op overloading is when you need a mathematical language or you have a crap IDE. Go and get a better IDE with autocomplete. Even VIM can do heuristic autocomplete (i.e. it analyses your code and second-guesses what you probably want to complete, putting that to the first item in the list, so often you don't need to select an item manually).

Quite so. That's the only time.

Consider these three lines of code.
a = a * t + b * 1 - t;a = a.mul(t).add(b.mul(t.rsub(1)));a = a.multiplyAddToMultiplyBySubtractFrom(t, b, 1, t);

Clearly, the first is opaque and impossible to understand. The second makes things almost crystal clear. But the third, with its long name, leaves us with absolutely no doubt as to what the code is going to do.
Quote:

(PS: I've written 5 software renderers, everything from C scanliners to a 3kb java engine with dynamic lighting. I speak from experience: over the years it's become more and more obvious that op overloading is unnecessary and undesirable in 3D engines)

Ah, argument from authority, is it?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.