Why doesn't Java offer operator overloading?
Asked Answered
K

18

489

Coming from C++ to Java, the obvious unanswered question is why didn't Java include operator overloading?

Isn't Complex a, b, c; a = b + c; much simpler than Complex a, b, c; a = b.add(c);?

Is there a known reason for this, valid arguments for not allowing operator overloading? Is the reason arbitrary, or lost to time?

Karrykarst answered 16/9, 2008 at 22:4 Comment(6)
May also read Why Java does not support Operator overloadingUnbiased
@zzzz, I have a hard time reading that article. Was this auto-translated, or is English the writer's 2nd language? I find the discussion here to be much cleaner.Zaslow
To the pile-on of folks closing this as not constructive, this question has yielded some of the most constructive dialog I've seen at SO. Perhaps it's a better candidate for programmers.stackexchange.com, but there are times when I think SO is being overly dismissive of broader subjects.Zaslow
@Unbiased it's easy, just mentally insert a and the - missing artlcles is a dead giveaway that the person is either not a native english speaker or a programmer (or like this guy, both :) The reason programmers can drop articles is that it can make comments shorter and fit easier in the space provided.. from there, they just get used to it. My problem is with the layout, somehow I'm always hitting that site in google searches. Luckily there is a great chrome extension called Clearly that reformats hard to read pages wonderfully.Procopius
I don't see any reason why & how OP accepted the first answer? Answer written by @stackoverflow.com/users/14089/paercebal is excellent. It should be accepted.Seismography
I wished the == operator would be overloaded for strings. Gets me every time I switch back from GO, PHP, RUBY, Python, ....Jumbuck
R
12

Assuming you wanted to overwrite the previous value of the object referred to by a, then a member function would have to be invoked.

Complex a, b, c;
// ...
a = b.add(c);

In C++, this expression tells the compiler to create three (3) objects on the stack, perform addition, and copy the resultant value from the temporary object into the existing object a.

However, in Java, operator= doesn't perform value copy for reference types, and users can only create new reference types, not value types. So for a user-defined type named Complex, assignment means to copy a reference to an existing value.

Consider instead:

b.set(1, 0); // initialize to real number '1'
a = b; 
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail

In C++, this copies the value, so the comparison will result not-equal. In Java, operator= performs reference copy, so a and b are now referring to the same value. As a result, the comparison will produce 'equal', since the object will compare equal to itself.

The difference between copies and references only adds to the confusion of operator overloading. As @Sebastian mentioned, Java and C# both have to deal with value and reference equality separately -- operator+ would likely deal with values and objects, but operator= is already implemented to deal with references.

In C++, you should only be dealing with one kind of comparison at a time, so it can be less confusing. For example, on Complex, operator= and operator== are both working on values -- copying values and comparing values respectively.

Ronironica answered 16/9, 2008 at 22:31 Comment(10)
Just FYI, I didn't ask this question, I only edited the tags. Click the time (it currenty say 'an hour ago') above my name for more info-- It looks like Rengolin (stackoverflow.com/users/14067/rengolin) asked the question.Kedgeree
It's pretty simple really... Just do like Python and have no overloaded assignment.Trier
This answer doesn't answer the question at all. You're simply harping on java's use of the equals sign. If b+C returned a new Complex, then a = b+c would be perfectly valid, and yes much simpler to read. Even if you wanted to modify a in place, a.set(b+c) is a ton simpler to read - especially when the arithmetic is any more than trivial: a.set((ab + bc)/5) or a = a.multiply(b).add(b.multiply(c)).divide(5). Your choice..Dialectal
Or I guess.. not your choice, as the case may beDialectal
In C++, Expression Templates solve the problem of the extra copy. Pretty much all major arithmetic libraries use this technique for this very reason. Also, this doesn't address the question, since a = b + c is just syntactic sugar for a.foo(b.bar(c)), which is really the initial observation in the question.Ectoblast
This is not the answer to the question asked. This is someone's speculations on certain differences between Java and C++.Aborigine
Look at the project Java-OO is a modular extension (plugin) to Java compilers github.com/amelentev/java-ooSinuosity
I think the java assign operator always does what it is supposed to do. Assign value a to value b. In case they are references/ pointers, obviously we would be assigning the pointer and not what is being pointed to; just like what C++ does. The confusion is that java doesnt have a special syntax for pointers. In the case of dot oper. This works just the same as -> operator in C++ on pointers/java references. It because like :: scoped operator when applied to a class/enum/interface/etc.Renn
A language having reference semantics doesn't rule out operator overloading. Look at C# or Python, for example.Ineffaceable
I don't care how hard it is for the computer. I want the language design to make it easier for developers.Empyreal
C
918

There are a lot of posts complaining about operator overloading.

I felt I had to clarify the "operator overloading" concepts, offering an alternative viewpoint on this concept.

Code obfuscating?

This argument is a fallacy.

Obfuscating is possible in all languages...

It is as easy to obfuscate code in C or Java through functions/methods as it is in C++ through operator overloads:

// C++
T operator + (const T & a, const T & b) // add ?
{
   T c ;
   c.value = a.value - b.value ; // subtract !!!
   return c ;
}

// Java
static T add (T a, T b) // add ?
{
   T c = new T() ;
   c.value = a.value - b.value ; // subtract !!!
   return c ;
}

/* C */
T add (T a, T b) /* add ? */
{
   T c ;
   c.value = a.value - b.value ; /* subtract !!! */
   return c ;
}

...Even in Java's standard interfaces

For another example, let's see the Cloneable interface in Java:

You are supposed to clone the object implementing this interface. But you could lie. And create a different object. In fact, this interface is so weak you could return another type of object altogether, just for the fun of it:

class MySincereHandShake implements Cloneable
{
    public Object clone()
    {
       return new MyVengefulKickInYourHead() ;
    }
}

As the Cloneable interface can be abused/obfuscated, should it be banned on the same grounds C++ operator overloading is supposed to be?

We could overload the toString() method of a MyComplexNumber class to have it return the stringified hour of the day. Should the toString() overloading be banned, too? We could sabotage MyComplexNumber.equals to have it return a random value, modify the operands... etc. etc. etc..

In Java, as in C++, or whatever language, the programmer must respect a minimum of semantics when writing code. This means implementing an add function that adds, and Cloneable implementation method that clones, and a ++ operator that increments.

What's obfuscating anyway?

Now that we know that code can be sabotaged even through the pristine Java methods, we can ask ourselves about the real use of operator overloading in C++?

Clear and natural notation: methods vs. operator overloading?

We'll compare below, for different cases, the "same" code in Java and C++, to have an idea of which kind of coding style is clearer.

Natural comparisons:

// C++ comparison for built-ins and user-defined types
bool    isEqual          = A == B ;
bool    isNotEqual       = A != B ;
bool    isLesser         = A <  B ;
bool    isLesserOrEqual  = A <= B ;

// Java comparison for user-defined types
boolean isEqual          = A.equals(B) ;
boolean isNotEqual       = ! A.equals(B) ;
boolean isLesser         = A.comparesTo(B) < 0 ;
boolean isLesserOrEqual  = A.comparesTo(B) <= 0 ;

Please note that A and B could be of any type in C++, as long as the operator overloads are provided. In Java, when A and B are not primitives, the code can become very confusing, even for primitive-like objects (BigInteger, etc.)...

Natural array/container accessors and subscripting:

// C++ container accessors, more natural
value        = myArray[25] ;         // subscript operator
value        = myVector[25] ;        // subscript operator
value        = myString[25] ;        // subscript operator
value        = myMap["25"] ;         // subscript operator
myArray[25]  = value ;               // subscript operator
myVector[25] = value ;               // subscript operator
myString[25] = value ;               // subscript operator
myMap["25"]  = value ;               // subscript operator

// Java container accessors, each one has its special notation
value        = myArray[25] ;         // subscript operator
value        = myVector.get(25) ;    // method get
value        = myString.charAt(25) ; // method charAt
value        = myMap.get("25") ;     // method get
myArray[25]  = value ;               // subscript operator
myVector.set(25, value) ;            // method set
myMap.put("25", value) ;             // method put

In Java, we see that for each container to do the same thing (access its content through an index or identifier), we have a different way to do it, which is confusing.

In C++, each container uses the same way to access its content, thanks to operator overloading.

Natural advanced types manipulation

The examples below use a Matrix object, found using the first links found on Google for "Java Matrix object" and "C++ Matrix object":

// C++ YMatrix matrix implementation on CodeProject
// http://www.codeproject.com/KB/architecture/ymatrix.aspx
// A, B, C, D, E, F are Matrix objects;
E =  A * (B / 2) ;
E += (A - B) * (C + D) ;
F =  E ;                  // deep copy of the matrix

// Java JAMA matrix implementation (seriously...)
// http://math.nist.gov/javanumerics/jama/doc/
// A, B, C, D, E, F are Matrix objects;
E = A.times(B.times(0.5)) ;
E.plusEquals(A.minus(B).times(C.plus(D))) ;
F = E.copy() ;            // deep copy of the matrix

And this is not limited to matrices. The BigInteger and BigDecimal classes of Java suffer from the same confusing verbosity, whereas their equivalents in C++ are as clear as built-in types.

Natural iterators:

// C++ Random Access iterators
++it ;                  // move to the next item
--it ;                  // move to the previous item
it += 5 ;               // move to the next 5th item (random access)
value = *it ;           // gets the value of the current item
*it = 3.1415 ;          // sets the value 3.1415 to the current item
(*it).foo() ;           // call method foo() of the current item

// Java ListIterator<E> "bi-directional" iterators
value = it.next() ;     // move to the next item & return the value
value = it.previous() ; // move to the previous item & return the value
it.set(3.1415) ;        // sets the value 3.1415 to the current item

Natural functors:

// C++ Functors
myFunctorObject("Hello World", 42) ;

// Java Functors ???
myFunctorObject.execute("Hello World", 42) ;

Text concatenation:

// C++ stream handling (with the << operator)
                    stringStream   << "Hello " << 25 << " World" ;
                    fileStream     << "Hello " << 25 << " World" ;
                    outputStream   << "Hello " << 25 << " World" ;
                    networkStream  << "Hello " << 25 << " World" ;
anythingThatOverloadsShiftOperator << "Hello " << 25 << " World" ;

// Java concatenation
myStringBuffer.append("Hello ").append(25).append(" World") ;

Ok, in Java you can use MyString = "Hello " + 25 + " World" ; too... But, wait a second: This is operator overloading, isn't it? Isn't it cheating???

:-D

Generic code?

The same generic code modifying operands should be usable both for built-ins/primitives (which have no interfaces in Java), standard objects (which could not have the right interface), and user-defined objects.

For example, calculating the average value of two values of arbitrary types:

// C++ primitive/advanced types
template<typename T>
T getAverage(const T & p_lhs, const T & p_rhs)
{
   return (p_lhs + p_rhs) / 2 ;
}

int     intValue     = getAverage(25, 42) ;
double  doubleValue  = getAverage(25.25, 42.42) ;
complex complexValue = getAverage(cA, cB) ; // cA, cB are complex
Matrix  matrixValue  = getAverage(mA, mB) ; // mA, mB are Matrix

// Java primitive/advanced types
// It won't really work in Java, even with generics. Sorry.

Discussing operator overloading

Now that we have seen fair comparisons between C++ code using operator overloading, and the same code in Java, we can now discuss "operator overloading" as a concept.

Operator overloading existed since before computers

Even outside of computer science, there is operator overloading: For example, in mathematics, operators like +, -, *, etc. are overloaded.

Indeed, the signification of +, -, *, etc. changes depending on the types of the operands (numerics, vectors, quantum wave functions, matrices, etc.).

Most of us, as part of our science courses, learned multiple significations for operators, depending on the types of the operands. Did we find them confusing, then?

Operator overloading depends on its operands

This is the most important part of operator overloading: Like in mathematics, or in physics, the operation depends on its operands' types.

So, know the type of the operand, and you will know the effect of the operation.

Even C and Java have (hard-coded) operator overloading

In C, the real behavior of an operator will change according to its operands. For example, adding two integers is different than adding two doubles, or even one integer and one double. There is even the whole pointer arithmetic domain (without casting, you can add to a pointer an integer, but you cannot add two pointers...).

In Java, there is no pointer arithmetic, but someone still found string concatenation without the + operator would be ridiculous enough to justify an exception in the "operator overloading is evil" creed.

It's just that you, as a C (for historical reasons) or Java (for personal reasons, see below) coder, you can't provide your own.

In C++, operator overloading is not optional...

In C++, operator overloading for built-in types is not possible (and this is a good thing), but user-defined types can have user-defined operator overloads.

As already said earlier, in C++, and to the contrary to Java, user-types are not considered second-class citizens of the language, when compared to built-in types. So, if built-in types have operators, user types should be able to have them, too.

The truth is that, like the toString(), clone(), equals() methods are for Java (i.e. quasi-standard-like), C++ operator overloading is so much part of C++ that it becomes as natural as the original C operators, or the before mentioned Java methods.

Combined with template programming, operator overloading becomes a well known design pattern. In fact, you cannot go very far in STL without using overloaded operators, and overloading operators for your own class.

...but it should not be abused

Operator overloading should strive to respect the semantics of the operator. Do not subtract in a + operator (as in "do not subtract in a add function", or "return crap in a clone method").

Cast overloading can be very dangerous because they can lead to ambiguities. So they should really be reserved for well defined cases. As for && and ||, do not ever overload them unless you really know what you're doing, as you'll lose the the short circuit evaluation that the native operators && and || enjoy.

So... Ok... Then why it is not possible in Java?

Because James Gosling said so:

I left out operator overloading as a fairly personal choice because I had seen too many people abuse it in C++.

James Gosling. Source: http://www.gotw.ca/publications/c_family_interview.htm

Please compare Gosling's text above with Stroustrup's below:

Many C++ design decisions have their roots in my dislike for forcing people to do things in some particular way [...] Often, I was tempted to outlaw a feature I personally disliked, I refrained from doing so because I did not think I had the right to force my views on others.

Bjarne Stroustrup. Source: The Design and Evolution of C++ (1.3 General Background)

Would operator overloading benefit Java?

Some objects would greatly benefit from operator overloading (concrete or numerical types, like BigDecimal, complex numbers, matrices, containers, iterators, comparators, parsers etc.).

In C++, you can profit from this benefit because of Stroustrup's humility. In Java, you're simply screwed because of Gosling's personal choice.

Could it be added to Java?

The reasons for not adding operator overloading now in Java could be a mix of internal politics, allergy to the feature, distrust of developers (you know, the saboteur ones that seem to haunt Java teams...), compatibility with the previous JVMs, time to write a correct specification, etc..

So don't hold your breath waiting for this feature...

But they do it in C#!!!

Yeah...

While this is far from being the only difference between the two languages, this one never fails to amuse me.

Apparently, the C# folks, with their "every primitive is a struct, and a struct derives from Object", got it right at first try.

And they do it in other languages!!!

Despite all the FUD against used defined operator overloading, the following languages support it: Kotlin, Scala, Dart, Python, F#, C#, D, Algol 68, Smalltalk, Groovy, Raku (formerly Perl 6), C++, Ruby, Haskell, MATLAB, Eiffel, Lua, Clojure, Fortran 90, Swift, Ada, Delphi 2005...

So many languages, with so many different (and sometimes opposing) philosophies, and yet they all agree on that point.

Food for thought...

Crone answered 16/9, 2008 at 22:4 Comment(29)
@Douglas Leeder : Thanks! Operator overloading is like OOP. The first time you learn to do it, you write overloads everywhere as you would put base classes and inheritance everywhere (like, sweet irony, the Java API). But this passes quite fast and then you appreciate the possibility all the while not abusing it. My own 10-years+ experience about C++ is that the number of bad overloads I saw both in my code and code from other coders is so low I believe I could count them on one hand. And this is a lot less than the number of overall bugs with sprintf, strcat, memset and buffer overruns.Crone
I now have 7 years of working experience with C++. The only operator overrides I written or interacted with have been stream operator - which are definitely an abuse of shifting operators. On the other hand shift operators for output are rather convenient, and as a special case, I guess it's acceptable.Olathe
@Douglas Leeder : About the use on the << and >> operators with streams : I don't even remember using them outside the context of a stream (multiplying/dividing an unsigned integer by 2 should not need its special operator), which explains, I guess, why this is the overloading that bothers me the less. My problem with overloading was more of the "this is bad code" kind. For example, the operator + whose return value is a static variable inside the function, for "optimization purposes", or an inconsistant operator [] (the method was const, but returned reference was not).Crone
@Douglas Leeder : I believe, after discussing about that in another SO question, that the gap between "lovers" and "haters" of operator overload is probably caused by a difference in their approach of the code: "Haters" are more "functions are what matters", meaning that they expect a function to do one thing, and one thing only. Thus operators should work as designed by the language. "Lovers" are more about "objects should behave", meaning that they accept more readily that function (and thus, operators) can change their behaviour according to the type of their parameters.Crone
Actually I think it should be 1.0/2, because 1/2 == 0. Also, you can write it->foo(), which is a lot nicer than (*it).foo(). Great post!Bussy
@Niklas B. : Thanks! I corrected the 1/2 into 0.5. As for it->foo(), I had decided to let it as (*it).foo() because it is easier to decompose, and thus, understand by Java people (apply the * operator, as in the line before, the get, the value, and then, the . to call the method of the value).Crone
I was thinking something like that was the reason you put it this way. Thanks for the followup!Bussy
You know, single line comments (//...) work in C, just like they do in C# and Java.Monogamist
@Hassan : single line comments (//...) work in C IIRC, single line comments work in C99, not in C89.Crone
The examples given above makes sense for stuff like + -, the arithmatic ones.... the other ones are very confusing to understand, such as the << for stringstreams, Functors. java syntax might be verbose, but things like.. next(), append() has a very clear meaning. that makes it more easy to readAbecedary
@user1216838 : Like in mathematics, or in quantum physics, operators depend on the context. In C++, using "<<" for streams of "()" for functors is so natural no C++ developer would argue against them. Now, a C (or Java) developer coming to C++ would be surprised, but, hey, you're learning a new language. You should then expect to learn new ways. As for "append()" it is so natural they decided against it for Java strings, and instead overloaded the "+" and "+="... :-)Crone
@Crone for sure they depend on context, I'm just arguing for the benefit of more verbose and more clear meaning syntax. as opposed to looking through the documentation for every new declared type. Java also decided to use double quotes for static strings, instead of writing new String("") for every string u declare. but even tho its inconsistent with other operators, no programmer will ever mistaken the meaning of these operators.Abecedary
@user1216838 : for the benefit of more verbose and more clear meaning syntax : This is a glaring contradiction. The matrix is the best example here. Look at the actual notation in mathematics and in physics and you'll realize that nowhere they use a notation like Java's notation, and that, indeed, their notation is similar to C++'s. This alone is proof that clear and verbose doesn't go together. What you are arguing about is your own coding habits and reluctance of using operator overloading. C++ developers (and indeed, other languages devs,) don't have the same limitations.Crone
I agree and disagree. I would want to use operator overloading myself, especially with complex numbers and the BigInteger and BigDecimal class. However I wouldn't want to see anyone else abuse it.Pony
@Pony : However I wouldn't want to see anyone else abuse it : From my own 14 years-old professional experience, "operator overloading abuse" is a much hyped-up concept bordering on paranoia. I predict this paranoia will end the day Java will get it, too (probably with Java structs, around Java 10, in 2020). In my current job, with 100+ C/C++ developers and a C codebase evolving fast into C++, the major problems are casts (mostly C-style casts), void * and a legacy C framework mimicking OOP features. Not operator overloading despite it now being available and wisely used (functors, mostly).Crone
@user7610 : Please read the original question, before it was edited: stackoverflow.com/revisions/77718/1 and you'll see there was multiple questions inside, and that I answered them. The question was simplified in 4 years later, after I did my last non-trival edit.Crone
@Crone Fair enough. Peace.Deed
I can not believe after such a clean logic answer people still can not get OP's point ! And arguing about trivial things such as whether "<<" is confusing or not. It has nothing to do with OP's reasoning. The point is you don't ban some features just because some people will abuse it, everything can be abused. If an knife is used to cutting meats, if someone used it to kill a person, do you decide to make all knife dull, so dull that it won't even cut a fruit ?Crustal
This completely misses the fact that developers often don't expect for + to have a different implementation / meaning than the default. Something like a = b + c can suddenly have a lot of different meanings. This also plays up since in Java things are often automatically converted to strings (I'm not saying that this is a good thing) so a = b + c can get confusing quickly. This is where obfuscation comes in. Operator overloading is a balancing act and Gosling preferred minimizing side effects over conciseness. Calling that "screwing someone over" is not just wrong, it's abusive as well.Jornada
@MaartenBodewes : Developer's expectations are dictated by the language. In C++, no developer expects a + b to call the builtin operator +. Instead, they expect the right operator + will be called. The fact C and Java developers have such expectations on builtin operators are due to their knowledge of their language's limitations. Then, for some reason, such expectations borne from limitations are raised as something they can't live without, despite all other languages having proved otherwise. Gosling's decision was a matter of personal taste.Crone
@Crone Of course it was, language design is not a democratic process (fortunately). Any kind of decision basically is "a matter of personal taste". But as the goal of Java was a maintainable, relatively simple language (both for users and for compiler/tool builders, mind you) leaving out operator overloading is - or at least was - entirely in the spirit of Java. Every construct in popular languages can be defended the way you do, but if you put them all together you get D, a language mainly produced to fill in all the marks of features supported - and therefore largely not maintainable.Jornada
@MaartenBodewes In addition to Gosling's School of "Decision by Taste", there's also Stroustrup's school of "Decision by taking into account both your experience and those of other experts, including those who disagree with you". I tend to favor the last school. Also, operator overloading is not a technical challenge, nor it is complicated to understand/assimilate, as demonstrated by the myriad of other languages (including Java's twin, C#) enabling it. Operator overloading is just something that rubs some people the wrong way. Too bad, because as I demonstrated, it can make code much clearer.Crone
Sorry, but the reason that Java is Java is by largely ignoring developers requests. On their own all features are defendable. Mop them all up into a language and you get C++ or D. Java is limited by design. It could use a next step (such as Kotlin maybe). But whatever this discussion, the above answer blames Goslin. I'm fine with people disagreeing, but putting blame on someone only makes the discussion subjective.Jornada
@MaartenBodewes : All the examples I wrote above, and all that bothers you is the "as a developer, you're screwed because Gosling's personal choice"? Please, write your own answer, defending the "you developers are stupid, let the genius people decide for you what you need" angle. This discussion serves no purpose.Crone
matlab's operator overloading is broken in my opinion. All operations are dispatched to the highest parent object, so a.b.c() is dispatched to a's implementation!Illuminism
But the situation with Java does not even seem consistent. For example, the foreach loop "operator" is "overridden" with my definition of Iterable, but the "<" is not overridden with my definition of Comparable. Seems rather illogical and perhaps something that can be addressed in future JLS's.Threadbare
I personally like operator overloading, its a tool. But I don't use it every where because it is not appropriate to use it every where. Like all tools, use it when you should, don't when you shouldn't. James's statement that he left them out of Java because developers abuse them I find a bit insulting.Apocalyptic
To quote James Gosling in his work, “The Evolution of Numerical Computing in Java,” “Everyone I’ve talked to who does numerical work insists that operator overloading is totally essential. The method invocation style for writing expressions is so cumbersome as to be essentially useless.”Hooch
Wasn't Perl 6 renamed to Raku in October 2019?Currier
V
44

James Gosling likened designing Java to the following:

"There's this principle about moving, when you move from one apartment to another apartment. An interesting experiment is to pack up your apartment and put everything in boxes, then move into the next apartment and not unpack anything until you need it. So you're making your first meal, and you're pulling something out of a box. Then after a month or so you've used that to pretty much figure out what things in your life you actually need, and then you take the rest of the stuff -- forget how much you like it or how cool it is -- and you just throw it away. It's amazing how that simplifies your life, and you can use that principle in all kinds of design issues: not do things just because they're cool or just because they're interesting."

You can read the context of the quote here

Basically operator overloading is great for a class that models some kind of point, currency or complex number. But after that you start running out of examples fast.

Another factor was the abuse of the feature in C++ by developers overloading operators like '&&', '||', the cast operators and of course 'new'. The complexity resulting from combining this with pass by value and exceptions is well covered in the Exceptional C++ book.

Veronique answered 16/9, 2008 at 22:46 Comment(24)
Could you provide a code example of "the complexity of operator overloading combined with pass-by-value and exceptions"? Despite a few years playing with the language, and owning and having read all effective/exceptional books on C++, I fail to understand what you mean by that.Crone
What works for James Gosling isn't going to work for everyone. He's incredibly shortsighted for extrapolating his "interesting" packing experiment to mean "Throw away everything in the world that I don't need, so no one can use that stuff." He clearly doesn't know what I need or use.Dialectal
@B T : Most enlightning is Gosling's viewpoint when compared to Stroustrup's viewpoint on this issue: Many C++ design decisions have their roots in my dislike for forcing people to do things in some particular way [...] Often, I was tempted to outlaw a feature I personally disliked, I refrained from doing so because I did not think I had the right to force my views on others. (B. Stroustrup).Crone
@Paercebal: "Most enlightening is Gosling's ... compared to Stroustrup's". Interesting, yet I would have thought, subjectively, that the difference has resulted in one language, C++, widely reviled vs. the other, Java, widely liked. Perhaps there is a place for experts to say "that's a bad idea".Overplus
@Software Monkey : "C++, widely reviled vs. the other, Java, widely liked" This is marketing hype. Remember that C++ grew alone, whereas Java (and .NET) profited from marketing bulldozers. Doesn't it seem strange that for a "widely liked language", Java is limited to server applications, whereas "widely reviled" (probably by Java developers and managers wanting to lower the cost of code production) C++ goes from very-high-performance servers to high performance games? [...]Crone
@Software Monkey : [...] My own comparison between Java/.NET and C++ was not so favorable to Java/.NET. To summarize it: It's easier and faster to produce average quality code in Java/.NET than in C++, but the moment you want excellent-to-perfect high-performance quality code, Java/.NET will hinder you, whereas C++ will make it easy. For more information about that, see my answer at: https://mcmap.net/q/75460/-c-performance-vs-java-c/…Crone
"Or not to do things... just because they're concise"? Sorry for putting words in your mouth James Gosling, but this is one Java design principle I do not agree with at the usage level. At the language design & implementation level, sure, since it makes language maintainers' jobs that much simpler.Goles
I like this answer. Sure, many people here like to think that C++ gives you more flexibility, but I'd like them to go have a look at some C++ code out there that is hideously put together with weird hacks and "exceptional" features of the language. If these features weren't available in the first place, the code would be written just as easily, yet it would be much easier to read and maintain.Monogamist
@Hassan : Each language has its hacks, Java's generics being one great example of that. Now, about I'd like them to go have a look at some C++ code out there that is hideously put together with weird hacks and "exceptional" features of the language : Bad programmers will write bad code no matter the language. Just try to emulate a "pass-by-reference" for function parameters in Java to have an idea. I've seen the code, and laughed so hard it hurt. This is the kind of things Gosling didn't use, thus, needed horrible hacks to have in Java, yet, exists natively, at zero cost, in both C# and C++.Crone
@Crone Of course, I agree that each language has its hacks. I'm not arguing for one language or the other, just that each language has its advantages and disadvantages, making it better suited for certain problems. I think Java is the clear winner with code reusability, because it requires the programmer to follow the same organization patterns, partly by removing exceptional features in the language itself. In your answer, you said that operator overloading should not be abused. Unfortunately, there will always be someone who abuses this feature and others, making the code unmaintainable.Monogamist
@Hassan : The strange thing about "operator overloading abuse" is that I saw only two instances of that in my career (12 years of C++), and the code was not unmaintainable. . . Now, every time someone reports that kind of abuse, that someone either comes from the C or Java crowd and is usually unable to detail an example he/she personally experienced. It smells like rationalization, to me. . . Now, about the "simplicity" of Java, we agree. Google for the term "Javaschools" to understand what this "simplicity" really means: encrypted.google.com/search?q=javaschoolsCrone
@Crone But again, this idea seems to focus on very specific shortcomings of Java. I read the blog post that was the first hit on that google search, and the author focuses on Java's weaknesses which make it unsuitable for certain tasks (he gave operating systems as an example. He also mentioned MapReduce, although there are Java implementations of that). Anyway, I still agree there. Java isn't the right tool for every job. But I don't know how badly "Javaschools" generate programmers, since I happen to be a CS student at the moment. I hope you guys are wrong there!Monogamist
"Basically operator overloading is great for a class that models some kind of point, currency or complex number. But after that you start running out of examples fast." how about Dates? or one of dozens of orderable datatypes that the java designers never thought of?Contrition
"Basically operator overloading is great for a class that models some kind of point, currency or complex number. But after that you start running out of examples fast." How about any data type that you want to do any sort I/O on? Java's I/O routines are quite ugly, especially with layers of abstraction and databases. Also, any container class where you want to access the Nth item, or do some sort of key->value mapping makes excellent use of operator overloading. Without operator overloading or default parameter values, I'm surprised anyone uses this language, especially w/ Oracle owning it.Orphaorphan
Many things about Java stem from Gosling's personal perceptions, which may not always jibe with reality. He refused to provide an unsigned byte type, claiming that unsigned types cause problems, when in reality the only unsigned types which cause problems are those which are larger than the default promotion type (a Byte type, of course, would not be; I don't think any Pascal programmers have had trouble with Byte being signed). With regard to operator overloading, however, I think it's important for a reference-based-OOP language like Java have an reference-compare operator.Interdigitate
Thus, if == is going to be used for both primitive comparisons and reference comparisons, that will make most other sort of operator overloading problematic. Of course, Java later went ahead and messed up that distinction by allowing automatic unboxing, but I think there was a sound philosophical reason why a language which uses == as Java did shouldn't support overloading.Interdigitate
@Crone One of your stated possible reasons for not adding operator overloading now is compatibility with the previous JVMs. This brings an interesting question, i.e. would operator overloading be possible without altering the JVM? I assert that it can be purely syntactic sugar (that might break Java syntax, but not JVM)Microorganism
@Microorganism : IMHO, the model where my Java 8 code should produce Java 1.2 compatible bytecode is dumb, and is cause for a huge technical debt (e.g. Java generics' laughable implementation). I should be able, like in .NET, to target a minimum JVM version, and let the user either install that JVM (or more recent) or not use my code.Crone
Gosling also left out function pointers for the same reason, and look where we are today...Piscator
+1 for being the only one, true answer to this question. While Gosling's view may be debatable, it is definitely the reason for Java's omission of operator overloading. This should definitely be the top answer, and the accepted one!Kaduna
"Basically operator overloading is great for a class that models some kind of point, currency or complex number. But after that you start running out of examples fast." Adding to @samboosalis and @jbo5112: Also consider how frequently you want to support overloading for container types; + for sequences (which Java's string actually provides, but no other sequence can), the various set operations (typically expressed with bit-wise operator overloads, e.g. | for union, & for intersection, < for is-subset, etc.). These overloads are common and well understood in many other languages.Izettaizhevsk
It worth adding such thing just for the sake of acessing characters in string using [] at least. Seriously, you can do this in almost all other languagesMontez
Even James Gosling in his work, “The Evolution of Numerical Computing in Java,” admits that operator overloading is essential!Hooch
I never felt operator overloading was essential until I started working with matrices and linear algebra. Now I am convinced that operator overloading should be added.Empyreal
A
24

Check out Boost.Units: link text

It provides zero-overhead Dimensional analysis through operator overloading. How much clearer can this get?

quantity<force>     F = 2.0*newton;
quantity<length>    dx = 2.0*meter;
quantity<energy>    E = F * dx;
std::cout << "Energy = " << E << endl;

would actually output "Energy = 4 J" which is correct.

Arris answered 17/9, 2008 at 13:1 Comment(1)
"How exactly if complicates maintenance and where on earth does this obfuscate code?"Brokenhearted
V
16

The Java designers decided that operator overloading was more trouble than it was worth. Simple as that.

In a language where every object variable is actually a reference, operator overloading gets the additional hazard of being quite illogical - to a C++ programmer at least. Compare the situation with C#'s == equality operator overloading and Object.Equals and Object.ReferenceEquals.

Valrievalry answered 16/9, 2008 at 22:11 Comment(0)
R
12

Assuming you wanted to overwrite the previous value of the object referred to by a, then a member function would have to be invoked.

Complex a, b, c;
// ...
a = b.add(c);

In C++, this expression tells the compiler to create three (3) objects on the stack, perform addition, and copy the resultant value from the temporary object into the existing object a.

However, in Java, operator= doesn't perform value copy for reference types, and users can only create new reference types, not value types. So for a user-defined type named Complex, assignment means to copy a reference to an existing value.

Consider instead:

b.set(1, 0); // initialize to real number '1'
a = b; 
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail

In C++, this copies the value, so the comparison will result not-equal. In Java, operator= performs reference copy, so a and b are now referring to the same value. As a result, the comparison will produce 'equal', since the object will compare equal to itself.

The difference between copies and references only adds to the confusion of operator overloading. As @Sebastian mentioned, Java and C# both have to deal with value and reference equality separately -- operator+ would likely deal with values and objects, but operator= is already implemented to deal with references.

In C++, you should only be dealing with one kind of comparison at a time, so it can be less confusing. For example, on Complex, operator= and operator== are both working on values -- copying values and comparing values respectively.

Ronironica answered 16/9, 2008 at 22:31 Comment(10)
Just FYI, I didn't ask this question, I only edited the tags. Click the time (it currenty say 'an hour ago') above my name for more info-- It looks like Rengolin (stackoverflow.com/users/14067/rengolin) asked the question.Kedgeree
It's pretty simple really... Just do like Python and have no overloaded assignment.Trier
This answer doesn't answer the question at all. You're simply harping on java's use of the equals sign. If b+C returned a new Complex, then a = b+c would be perfectly valid, and yes much simpler to read. Even if you wanted to modify a in place, a.set(b+c) is a ton simpler to read - especially when the arithmetic is any more than trivial: a.set((ab + bc)/5) or a = a.multiply(b).add(b.multiply(c)).divide(5). Your choice..Dialectal
Or I guess.. not your choice, as the case may beDialectal
In C++, Expression Templates solve the problem of the extra copy. Pretty much all major arithmetic libraries use this technique for this very reason. Also, this doesn't address the question, since a = b + c is just syntactic sugar for a.foo(b.bar(c)), which is really the initial observation in the question.Ectoblast
This is not the answer to the question asked. This is someone's speculations on certain differences between Java and C++.Aborigine
Look at the project Java-OO is a modular extension (plugin) to Java compilers github.com/amelentev/java-ooSinuosity
I think the java assign operator always does what it is supposed to do. Assign value a to value b. In case they are references/ pointers, obviously we would be assigning the pointer and not what is being pointed to; just like what C++ does. The confusion is that java doesnt have a special syntax for pointers. In the case of dot oper. This works just the same as -> operator in C++ on pointers/java references. It because like :: scoped operator when applied to a class/enum/interface/etc.Renn
A language having reference semantics doesn't rule out operator overloading. Look at C# or Python, for example.Ineffaceable
I don't care how hard it is for the computer. I want the language design to make it easier for developers.Empyreal
B
9

Groovy has operator overloading, and runs in the JVM. If you don't mind the performance hit (which gets smaller everyday). It's automatic based on method names. e.g., '+' calls the 'plus(argument)' method.

Buoyage answered 16/9, 2008 at 22:24 Comment(4)
I wish all syntax-heavy languages with operator overloading would have used that technique. I've never understood why they have to invent a special version of method naming and lookup. Stroustrup doesn't mention any alternatives in D&EC++. The C# team took the right approach with Linq syntax (where ... becomes .Where(i => ... ). If only they'd done the same with arithmetic operators, so many things would be simpler and more powerful. Java has the advantage of a clean slate and could get this right (though for religous reasons, it probably never will).Palish
@DanielEarwicker, I've often noted that when there are complicated disagreements that people will tag the motivations for either side as being "religious" in nature.Zaslow
@noah, I could live with a limited subset of operator overloading such as this, provided that there was a special tag to the method names that keep them visually distinct. Something like defining a __plus() method for the implementation of a "+" OL, and staying far away overloading things like casts and even array subscripts. What I'm not willing to live with is the way C++ and C# saw fit to implement it.Zaslow
Not an answer. There are many languages running on the VM. Operator overloading should not be a good reason in itself to switch languages.Jornada
T
8

Some people say that operator overloading in Java would lead to obsfuscation. Have those people ever stopped to look at some Java code doing some basic maths like increasing a financial value by a percentage using BigDecimal ? .... the verbosity of such an exercise becomes its own demonstration of obsfuscation. Ironically, adding operator overloading to Java would allow us to create our own Currency class which would make such mathematical code elegant and simple (less obsfuscated).

It would be awesome to be able to create a Financial class or Complex number class and use simple +, -, /, * operators on their instances ... like I could in C++ way back in 1999!

It's now 2024 but "Tonight I want to code like it's nineteen ninety nine..."

Tetrafluoroethylene answered 16/9, 2008 at 22:4 Comment(1)
BigDecimal is indead the main reason for operator overloading, every financial/accounting application have this readability problem.Freedwoman
E
5

Technically, there is operator overloading in every programming language that can deal with different types of numbers, e.g. integer and real numbers. Explanation: The term overloading means that there are simply several implementations for one function. In most programming languages different implementations are provided for the operator +, one for integers, one for reals, this is called operator overloading.

Now, many people find it strange that Java has operator overloading for the operator + for adding strings together, and from a mathematical standpoint this would be strange indeed, but seen from a programming language's developer's standpoint, there is nothing wrong with adding builtin operator overloading for the operator + for other classes e.g. String. However, most people agree that once you add builtin overloading for + for String, then it is generally a good idea to provide this functionality for the developer as well.

A completely disagree with the fallacy that operator overloading obfuscates code, as this is left for the developer to decide. This is naïve to think, and to be quite honest, it is getting old.

+1 for adding operator overloading in Java 8.

Everybody answered 16/9, 2008 at 22:4 Comment(1)
Java's use of + to concatenate anything string-ish is IMHO pretty hideous, as is the overloading of / in C and FORTRAN for whole and fractional division. In many versions of Pascal, use of arithmetic operators on any numeric type will yield results numerically equivalent to casting the operands to Real, though results which might not be whole numbers must be fed through Trunc or Round before they can be assigned to integers.Interdigitate
C
5

I think this may have been a conscious design choice to force developers to create functions whose names clearly communicate their intentions. In C++ developers would overload operators with functionality that would often have no relation to the commonly accepted nature of the given operator, making it nearly impossible to determine what a piece of code does without looking at the definition of the operator.

Certitude answered 16/9, 2008 at 22:10 Comment(16)
In C++ developers would overload operators with functionality that would often have no relation to the commonly accepted nature of the given operator : This is a gratuitous assertion. I'm a professionnal C++ developer since 12 years, and I rarely encountered this issue. In fact, the most bugs and design errors I saw in C++ were in the C-style code (void *, casts, etc.)Crone
-1. Every variable you assign is a symbol, just like the arithmetic operator symbols. Whether you use a phrase to name that variable, a single word, or a single letter, is your (or your team's) decision. Who is to say what is meaningful and what is not? The answer is you, the programmer. Within pure mathematics, multiplication between matrices means something different to multiplication between two numbers in basic arithmetic. Yet we use the same symbols for both types of multiplication.Goles
@paercebal: The assertion is unfortunately correct. You have to look no farther than IOstreams to see it in action. Thankfully most developers are more circumspect about inventing new semantics for existing operators.Paddock
@BenVoigt : I disagree. iostream's use of operator << is both well known since 30 years, and visually easier to understand (e.g. output << my_value ;) than its C counterpart ('my_int << my_other_int ;' which I can't even describe what it exactly does without getting my K&R). I believe the answer is wrong, not because it is false, but because it implies only operators can be misused that way. What user says, in essence, is that we could code a add functions that isn't about addition. But Java's Vector.add clearly uses the add for insertion. Should add be forbidden, too? [...]Crone
@BenVoigt : [...] And I'm not even mentioning the fact the add function could be really really misused (like doing a multiplication, or acquiring a mutex)... The abuse mentioned by user14128 is not limited to operators, but there is some kind pathological fear about operator overloading that I believe comes from the earlier days of C vs. C++, a fear that went unmodified right into Java, but thankfully, didn't go into C#... In the end, respecting semantics and writing clear functions/operators is the developer's job. Not the language's.Crone
@parcebal: By not knowing that << is a bit shift operator without side effects, you've proved the point. And that is not "the C counterpart", that is the C++ meaning as well. Using << for stream insertion fails pretty miserably, because it has the precedence of bit shifting, which is subtly wrong for insertion. That causes far more bugs than a fluent function call syntax for streams.Paddock
@BenVoigt If << gets picked up as the wrong precedent, then the code usually produces a compile time error (e.g. cout << 5&3 << endl fails to compile). I should note that there aren't many operators that would cause this failure in C++ (e.g. bitwise, relational, logical, assignment, ternary), and any failing code would be getting pretty crazy. I think in such cases the 5&3 should be written as (5&3) anyway, to further clarify this is one item to output, and that Java's I/O routines are a testament to how necessary operator overloading is to having clean, concise, readable code.Orphaorphan
@jbo5112: Example: cout << f() || g(); The parentheses don't make it clearer, they make it correct. And it the bit shift operators were not being abused, they would not be necessary. Why is cout << (5&3) << endl; better than cout.fmt(5&3)(endl); ? Using the function call operator on a functor member variable would be an infinitely better design for streams than repurposing bitwise operators just because the glyph looks nice. But this is far from the only thing wrong with streams.Paddock
The answer is right that some C++ developers misuse the feature; that's an argument against adopting the work of those developers into the Standard, not an argument against having the feature. (Which is where Java erred, but it's always been more of a "force developers to do the right thing" vs C++'s emphasis on complete control)Paddock
@BenVoigt cout << f() || g(); is the same as cout << f(); cout || g();. Unless you overloaded the class ostream so that you can use the || operator with the return type of g(), then that will not compile. The reason why cout << (5&3) << endl; is better than cout.fmt(5&3)(endl); is that the first consistently uses the same function, while the second calls the fmt function (which is wordy), then operator() (e.g. my_object(std::endl)).Orphaorphan
@BenVoigt If C++ used operator() instead of operator<<(), then that would function better at the expense of looking pretty. Calling cout("hello ")(name); can get kind of ugly and slow to type, especially when stringing together 350 of them to create a single line of output (e.g. long csv record). Using operator,() might be better cout,"hello ",name;, but cout,c1,',',c2,',',c3,',',c4... gets a little messy.Orphaorphan
@jbo5112: I think you're overlooking the iostream->bool conversion.Paddock
@BenVoigt Java's solution still doesn't force developers to create functions whose names clearly communicate their intentions. You are still free to write the function public int add(int num1, int num2) {return ((num1*num2/3)^0xFAFAFAFA);}.Orphaorphan
@jbo5112: I don't think you understand my position. Every language can be abused; that doesn't make it bad. C++ operator overloading can be abused; iostreams shows that it has (in exactly the same way you keep arguing). That doesn't mean that not having operator overloading would be a better choice. I quote myself "Thankfully most developers are more circumspect about inventing new semantics for existing operators." But I do look forward to a standardized replacement to iostreams, which is terrible in many more ways than just operator abuse.Paddock
@BenVoigt You are correct. I did overlook the automatic cast. I tend to avoid most of iostream, just for being slow for my uses. If the return of g() will cast to a bool, then that would run, but I'm hoping g() is at least code to handle a failed ostream operation. Sorry for misreading your distaste of iostream overloading the bitshift operators as agreeing with Java's design choice. I'm still trying to wrap my head around how James Gosling was so daft to force the creation of some inane library interfaces (e.g. any Java math library), and people still willingly choose the language.Orphaorphan
Just seeing the nature of the back and forth here, including the clarifications and reclarifications, is enough to make me run from operator overloading as fast as I can.Zaslow
I
4

Saying that operator overloading leads to logical errors of type that operator does not match the operation logic, it's like saying nothing. The same type of error will occur if function name is inappropriate for operation logic - so what's the solution: drop the ability of function usage!? This is a comical answer - "Inappropriate for operation logic", every parameter name, every class, function or whatever can be logicly inappropriate. I think that this option should be available in respectable programing language, and those that think that it's unsafe - hey no bothy says you have to use it. Lets take the C#. They drooped the pointers but hey - there is 'unsafe code' statement - program as you like on your own risk.

Impudicity answered 16/9, 2008 at 22:4 Comment(0)
C
4

Well you can really shoot yourself in the foot with operator overloading. It's like with pointers people make stupid mistakes with them and so it was decided to take the scissors away.

At least I think that's the reason. I'm on your side anyway. :)

Chapman answered 16/9, 2008 at 22:6 Comment(2)
Like for example this stupid mistake...Adrieneadrienne
That's a very bad way of thinking. You can shoot yourself in the foot, we rather cut your hands down, so you won't be able to. And of course we suppose that you are an idiot who will shoot himself.Incretion
B
3

Assuming Java as the implementation language then a, b, and c would all be references to type Complex with initial values of null. Also assuming that Complex is immutable as the mentioned BigInteger and similar immutable BigDecimal, I'd I think you mean the following, as you're assigning the reference to the Complex returned from adding b and c, and not comparing this reference to a.

Isn't :

Complex a, b, c; a = b + c;

much simpler than:

Complex a, b, c; a = b.add(c);
Bill answered 16/9, 2008 at 22:12 Comment(1)
Am I? ;) Equals can both mean assignment or comparison, but = is always assignment and == is always comparison. Names can introduce big sources of errors themselves.Karrykarst
A
2

Alternatives to Native Support of Java Operator Overloading

Since Java doesn't have operator overloading, here are some alternatives you can look into:

  1. Use another language. Groovy, Scala, and Kotlin have operator overloading, and are based on Java.
  2. Use java-oo, a plugin that enables operator overloading in Java. Note that it is NOT platform independent. Also, it has many issues, and is not compatible with the latest releases of Java (i.e. Java 10). (Original StackOverflow Source)
  3. Use JNI, Java Native Interface, or alternatives. This allows you to write C or C++ methods for use in Java. Of course this is also NOT platform independent.

If anyone is aware of others, please comment, and I will add it to this list.

Arrio answered 16/9, 2008 at 22:4 Comment(1)
Kotlin also supports operator overloading.Ninette
V
1

Part of the reason they decided not to include operator overloading is to keep the language small. I used to love C++, but it was a huge language, which meant there was a lot to learn. And you had to learn the whole thing to be able to maintain a project, especially one you didn't write. And learning C++ means learning about its quirks. But the bigger the language, the more quirks there are. And C++ was a very quirky language. So we not only had to learn all the features of the language, we had to learn them well, to learn their quirks. The developers of Java wisely (in my view) decided to keep the language small. The also eliminated a lot of the features that made the language quirky. This makes Java easy to learn, which means we can start being productive pretty quickly. I really appreciate that.

One quirky aspect of operator overloading was it led to unreadable code. Imagine if, in English, a novelist decided to redefine certain words. And gave them meanings that were so different from their original meaning that it wouldn't be obvious what the meaning was. Would that make the book hard to read? You bet it would. (In "A Clockwork Orange," the meaning of the slang that the author invented could usually be discerned from the context, but even with that, it made the book harder to read.) That's what James Gosling was referring to when he spoke of how the feature was abused. It can make the code very hard to maintain, because it's not always clear what the operators mean.

Vasti answered 16/9, 2008 at 22:4 Comment(0)
C
1

This is not a good reason to disallow it but a practical one:

People do not always use it responsibly. Look at this example from the Python library scapy:

>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=TCP |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=55 |<TCP |>>

Here is the explanation:

The / operator has been used as a composition operator between two layers. When doing so, the lower layer can have one or more of its defaults fields overloaded according to the upper layer. (You still can give the value you want). A string can be used as a raw layer.

Chapman answered 16/9, 2008 at 22:4 Comment(0)
C
1

Sometimes it would be nice to have operator overloading, friend classes and multiple inheritance.

However I still think it was a good decision. If Java would have had operator overloading then we could never be sure of operator meanings without looking through source code. At present that's not necessary. And I think your example of using methods instead of operator overloading is also quite readable. If you want to make things more clear you could always add a comment above hairy statements.

// a = b + c
Complex a, b, c; a = b.add(c);
Castlereagh answered 16/9, 2008 at 22:57 Comment(3)
Of course, as mentioned elsewhere you can never be sure of the meaning of the add function either.Pronouncement
True, I still find it comforting to know that at least my operators are hard coded. Of course, having the features and using them sensibly would only do us good. The problem is that it's hard to know if someone has used them sensibly. And that you agree on the definition of sensibly. :-)Castlereagh
The comment added to clarify the code, is what the code would look like in a language which supported operator overloading. Furthermore, the fact the the comment is written in terms of operators belies your opposition to operator overloading.Piscator
Q
0

I think that people making decisions simply forgot about complex values, matrix algebra, set theory and other cases when overloading would allow to use the standard notation without building everything into the language. Anyway, only mathematically oriented software really benefits from such features. A generic customer application almost never needs them.

They arguments about the unnecessary obfuscation are obviously valid when a programmer defines some program-specific operator where it could be the function instead. A name of the function, when clearly visible, provides the hint that it does. Operator is a function without the readable name.

Java is generally designed about philosophy that some extra verbosity is not bad as it makes the code more readable. Constructs that do the same just have less code to type in used to be called a "syntax sugar" in the past. This is very different from the Python philosophy, for instance, where shorter is near always seen as better, even if providing less context for the second reader.

Quire answered 16/9, 2008 at 22:4 Comment(1)
I agree that some extra verbosity is not bad when it makes code more readable. However, I do not agree that more verbosity always makes code more readable. Nor do I think that less verbosity always makes code more readable (e.g. Python). I think that readability and verbosity are independent metrics.Empyreal
F
-1

Java doesn't permit operator overloading because its creator didn't add the functionality to associate different meanings with the same operator. They just wanted to keep things simple by just retaining the meaning of an operator uniform throughout the programming language.

Overloading the operators makes things messy and creates a steep learning curve for new programmers. So, they just kept operator overloading out of the syllabus.

Faus answered 16/9, 2008 at 22:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.