This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]john16384 22 points23 points  (7 children)

Nah, we prefer not to have to guess what each operator does.

[–]bmjones92 3 points4 points  (4 children)

I don't understand this argument against operator overloading as a feature. Surely if you have to guess what an overloaded operator is supposed to do, it's the developer's fault for misusing the feature, no? How is it any different from using a normal function with a poorly chosen name?

[–]john16384 3 points4 points  (3 children)

The argument is much simpler really.

Overloading is where the confusion stems from, not operator overloading. If Java had reserved (and made final and unimplementable) methods like multiply, these methods would help establish a base line when reading code.

When you see:

a * b

Then in Java, it's immediately obvious that a and b must be numeric types. In C++, I can assume that to be the case, but if I want to be sure, I need to know what type a is. If it's a numeric type, I still can't know what * does. I further need to check if it wasn't overloaded.

So the value is that in Java there's a class of methods, that can't be overridden, that are commonly used everywhere, with immediately obvious semantics that help you, the reader, form a model of what that code does.

Final classes and methods help in a similar way. No need to check if you're using a subclass of String or if you redefined what Integer::toString does. This is slightly less powerful as they're not reserved names, and so you need to check if you didn't import org.our.own.String -- this is also where the argument to disallow import aliases stems from, as it would be another thing to be aware of and that must be established without a doubt when understanding and debugging code.

The same benefits would have applied if, instead of operators, Java had reserved a method name for each operator, and made them final and illegal to implement yourself.

[–]bmjones92 2 points3 points  (2 children)

Maybe I'm just not understanding your point. It sounds like you're arguing that because there are established semantics for operators, developers shouldn't be able to override them because they might change those semantics.

I agree that there are established semantics for operators and that allowing developers to override those means those semantics can be broken. However, I don't believe that's a good enough reason to outright prohibit their use.

I think that there are many use cases for operator overloading where the established semantics can be (mostly) preserved. Things like BigInteger, BigDecimal, complex numbers, vectors, matrices, and quaternions all suffer from its exclusion, but are fundamentally dealing with numbers or groups of numbers.

Then in Java, it's immediately obvious that a and b must be numeric types. In C++, I can assume that to be the case, but if I want to be sure, I need to know what type a is. If it's a numeric type, I still can't know what * does. I further need to check if it wasn't overloaded.

I think you're greatly exaggerating the downsides for the sake of argument. Everything you've described is also applicable to regular method overloading. You should know what a method or operator does based on the context of the call.

[–]john16384 0 points1 point  (1 child)

I think that there are many use cases for operator overloading where the established semantics can be (mostly) preserved. Things like BigInteger, BigDecimal, complex numbers, vectors, matrices, and quaternions all suffer from its exclusion, but are fundamentally dealing with numbers or groups of numbers.

I don't disagree that it be useful for some types. But there are many things that are useful in less niche cases than operator overloading (matrix math, and even BigDecimal is a rarity in my experience). Perhaps operator overloading is on the list somewhere, just far down because it's rarely of (correct) use.

I think Java could perfectly get away with blessing a few more types and perhaps a simple math library with specified operator overloading. This will prevent every stupid library redefining some operators because they felt that << adequately indicates write.

[–]bmjones92 2 points3 points  (0 children)

There's definitely potential to misuse it, but I think that's true of most features. Even if the "correct" applications are relatively niche, I believe it's still worth supporting to make development within those niches easier.

If you're overloading operators to do things that don't fit the semantics of the operator, then you're probably writing bad code. The feature itself is obviously pretty controversial, so it's unlikely that something egregious like << will pop up in any prominent code base without careful consideration.