3 ms·
I think a big source of confusion regarding operator overloading comes from the primary exposure to it being in C++, where it is poorly implemented. Java decide
by jmillikin 18y ago
I think a big source of confusion regarding operator overloading comes from the primary exposure to it being in C++, where it is poorly implemented. Java decided to omit it entirely, as a reaction against C++ -- this sort of "they didn't do it right, so we shouldn't do it at all" behavior is my greatest gripe against Java. The problems with operator overloading in C++ are thus:
* First, C++ severely limits the set of available operators. You can't define () to mean exponentiation, (^^) to mean boolean XOR, etc. This results in contortions to fit various useful operations into inappropriate operators. For example, anybody that's experienced C++'s mis-use of (<<) for stream insertion or (+) for sequence concatenation is a victim of this.
An aside on concatenation: this is one of the few cases where I think PHP has it right. Arithmetic addition and sequence concatenation are entirely separate, and merging them into the same operator is a terrible idea. Think of these cases of concatenation on strings:
(1 + 2) = (2 + 1)
(1 + 1 + 1) = (2 + 1)
("1" + "2") /= ("2" + "1")
("1" + "1" + "1") /= ("2" + "1")
Concatenation behaves quite differently from addition, and shouldn't share the same operator.
* Second, there's no base classes for operator parameters in the C++ standard. Ideally, you'd have a `class Number`, a global procedure: `Number operator+ (Number a, Number b){ return a.Add(b); }`, and no need to define odd non-class procedures everywhere.
* Third, C++ culture encourages poor use of operators. The standard library itself uses bit-shift operators (<<) and (>>) for string formatting operations! Python has many of the same "freedoms" as C++, but community mores prevents these things from working their way into major libraries (excepting grandfathered-in poor choices like (+) concatenation and (%) formatting).
* Fourth, C++'s operators are used as crutches to work around other problems with the language. The most galling problem is a lack of syntax for declaring collections. There would be no need for `ostream<<` if you could have something like `cout.Write("foo = %d, bar = %d\n", vector[foo, bar])`.
Of course, most of the potential changes to C++ involve some level of integration between the language and its standard library. For various reasons, such as poor API of the stdlib itself and a desire to maintain the charade of being suitable for low-level development, the C++ designers refuse to do this.
- dkarl 18y agoThird, C++ culture encourages poor use of operators. The standard library itself uses bit-shift operators (<<) and (>>) for string formatting operations! You can see elsewhere I slagged on C++ for its limited choice of operators, but this criticism never made sense to me. Using << and >> for stream operations isn't confusing to me. They aren't intrinsically shift operators; that's just the only way they were used in C. Perhaps this kind of disagreement is why operator overloading is so despised. I see no reason not to use the same operator to mean two different things in two completely different contexts. I don't especially love the iostreams library, but the choice of << and >> to denote insertion and extraction seems perfectly sane to me, and obviously seems insane to you. For some reason method naming isn't so contentious. The most galling problem is a lack of syntax for declaring collections. There would be no need for `ostream<<` if you could have something like `cout.Write("foo = %d, bar = %d\n", vector[foo, bar])`. This example doesn't make any sense. First, the iostream designers didn't use format strings because they thought IO type-checking should be handled via the same mechanism as type-checking for other operations. This decision might have been infeasible without operator overloading, but the motivation was type safety. Second, you don't need a collection here. It isn't even helpful. If you wanted to use format strings, you could use the same function signature as printf.