7

A common argument against operator overloading is that it can be and is abused, e.g. A+B doing something completely different to addition. Examples are often quoted in C++ snippets, where the functions overloading the operators don't name the operators (e.g. operator+()). Compare this to Python, where the operators are named (e.g. __add__).

Does this help to deter programmers from abusing overloading in the aforementioned manner? Anyone have any experiences of Python operator overloading being abused?

4
  • 3
    If an operator is abused, then it is abused in any way you need to call it. You can call it __add__ or operator+(), but that doesn't stop the "abuse."
    – apaderno
    Sep 10, 2011 at 14:31
  • 1
    Where do you draw the line between "abuse" and "creative use", e.g. for DSL creation where the semantics of the operator obviously don't match quite, but are close (e.g. using + for sequencing parsers and concatenating the results with +)?
    – user7043
    Sep 10, 2011 at 14:41
  • I think it has more to do with the history of how people used to program C++. Then taking those lessons learned and proactively applying them to the documentation and teaching for other languages.
    – snakehiss
    Sep 11, 2011 at 3:57
  • 1
    I think C++ is especially prone to problems because of its confusing semantics, especially in the presence of templates. Most other languages are much more transparent and therefore operator overloading should be less problematic in those languages.
    – Nate C-K
    Aug 7, 2012 at 21:48

8 Answers 8

4
Does this help to deter programmers from abusing overloading 
in the aforementioned manner?

Well, I think first we should define what the abuse is? File.Delete in C# simply deletes a file without even notifying the user about it. Thus, as a developer, I can simply write this code:

List<string> files = Directory.GetFile("path").ToList();
files.ForEach(f => {
    File.Delete(f);
});

Is it considered abuse? OK, you're free to define + symbol (character) as an operator which votes up and - as a vote-down operator. But is it considered abuse?

Also, are you forced to misuse these features? For example, a driver can simply turn the wheel to get to pedestrian area and kill may people? Should we lock the wheel?

I mean, after all, even if there is an opportunity for any kind of abuse, who's gonna get hurt? Developer.

In spite of highly OO infrastructure, you can write procedurally in C#. Is it abuse?

2

You can do the same things with function names, like using list.next () to return the length of the list, or list.length () to return a boolean.

A difference is, that we have strong expectations from math, that

a + b == b + a 

which is, for example, violated in String concatenation, but I never meet a person, who had problems to accept + as concatenation operator, and who expected "foo" + "bar" to return "barfoo".

In my opinion it is an argument from phantasy. Yes - we can imagine things go wrong, but in reality, they don't occur.

Another pitfall would be to expect

a + b * c to be evaluated a + (b * c), and 
(a + b) * c to be the same as (a*c) + (b*c) 

But is it a problem in reality? I don't think so.

1
  • 2
    Actually, C++ always evaluates a + b * c as a + (b * c), no matter what the operators do. Using + for concatenation in Java may get a bit confusing with things like 1+2+"a"+4+5 returning 3a45.
    – maaartinus
    Sep 10, 2011 at 18:23
1

It doesn't make any difference. It may be that Python programmers are less prone to abusing operator overloading. If that is true, it is due to the skill of the programmers, not the difference in syntax.

For a time, C++ was being used by a huge number of commercial programmers writing in-house Windows applications. It's a powerful language designed by experts for experts. It's no surprise that its features were widely misunderstood and abused.

Any language feature, including operator overloading, can be used badly. Removing (or barring the use of) a language features won't prevent poor programmers from coding badly, just as removing words from English won't prevent bad writers from writing badly. Instead, it will frustrate good programmers, forcing them to work around the missing feature.

1

Definition

First you need to define abuse in this context.

To me this means re-defining the operators so that they do not work intuitively for anybody reading the code.

But of course intuitively is also dependent on the context, but not only the context but the classes that are involved. So it boils down too will the use of operator overloading make the code harder to read or lead to any misunderstanding by somebody naively reading the code without understanding the full context.

Matrix   x;
Matrix   y;
Matrix   z  = x * y; // Is this abuse.

That depends. Is your primary audience mathematicians (or smart CS students). If yes then the this is not abuse but tidy short hand. If your primary audience is an English Literature professor then maybe you should have written it like this:

WordUsage      Hamlet;
WordUsage      Othello;
WordUsage      Shakespeare = Hamlet.DeduceLoveCorrelation(Othello);
           // OK that was not clear to me but I am not an Literature buff.
           // But to a literature person those identifiers may mean something.

Usage

So in C++ you can redefine the operators to do anything (C++ gives you a lot of flexibility (but this is also how the stream operators were introduced)). So abuse can turn into common usage if the idiom is accepted by the community as useful shortcut.

Does this help to deter programmers from abusing overloading in the aforementioned manner?

Does making it more convoluted to define operator overloading deter abuse. No. Its not as if using __add __ is any less hard than using operator+().

Anyone have any experiences of Python operator overloading being abused?

I think the python community has learned from the abuse and subsequent press about abuse that C++ had over a decade ago. When C++ came out it was the first mainstream language that allowed overloading of operators and people went hog wild experiment with the concept. This lead to a lot of frustration from maintainers and articles about overloading operators is an abuse (which led to a backlash and languages like Java banning them for no good reason (other than the author was swayed by public opinion).

Note: A couple of less popular language did it first (operator overloading) but they were mainly used by sensible people in research establishments. So either they were smart enough not to abuse the operators, or there research was so narrow that few bothered to read their code and thus it got no press.

0

I haven't try much languages, neither Python, but, in case of C++ / Java / c# I think support for operator overloading is confusing, and maybe bad implemented.

In C++, a bad example is the "<<" and ">>" operators for streams, I acutally avoid using them.

Maybe you would want to rephrase your question like "How do I avoid operator overloading in Python or other languages ?".

Many times, If I using Object Oriented programming, and need to overload and operator, I rather use functions instead of operators.

6
  • How does this adress the question?
    – user7043
    Sep 10, 2011 at 15:56
  • Operator overloading is not actually badly implemented, but it is very complicated feature. In c++ for example it interacts with many other c++ features. It should really be a library feature instead of language feature, but that's not possible because every class needs to support it.
    – tp1
    Sep 10, 2011 at 16:02
  • @delnan My answer its based in the description of the post, not the post' question ;-)
    – umlcat
    Sep 10, 2011 at 16:22
  • 5
    I don't think there is anything wrong with operator overloading in C++ per se. It is sometimes abused, but it is overall a very useful feature. In numerical code, it feels much more natural to write a = b + c; than a = b.add(c);.
    – quant_dev
    Sep 10, 2011 at 16:55
  • 1
    Java does not have operator overloading. It has just the + for String concatenation, but it is fixed in the syntax of the language - not a possibility for any purpose else. You claim, that you don't use << or >> in C++, but without mentioning a reason. You avoid them - so what does it mean? For whom is this relevant and why? Sep 10, 2011 at 17:17
0

The abuse, or misuse, of the operator overloading depends from who writes the code, not from the syntax used by the programming language.

To make an example, if overloading the + operator to make it not commutative were considered a bad practice, the compiler (or the interpreter) could not do anything to avoid you create a non commutative version of the + operator, as it doesn't check if the result of a + b is equal to the result of b + a.
If the programmers that use a specific programming language consider a bad practice to overload the + operator to make a non-commutative version, then they will not overload that operator to use it as concatenation operator for strings.

0

There are several degrees between proper use of operator overloading and plain out abuse.

Proper use would be when the overloaded operator meets both the formal constraints of the original operator, AND matches intuitively and conceptually. For example, if you implement a bigint class in C++, then overloading the arithmetic operators is perfectly reasonably, because they do the bigint equivalents of integer operators.

On the other end of the spectrum, we have operator overloading that completely changes the meaning of the operator, introduces non-obvious side effects, violates the behavior of the operator it is supposed to be modelling (commutativity, associativity, destructiveness, etc.) or otherwise leads to misleading code. An example would be overloading the unary-minus operator to convert a string to all-uppercase: uppercasing is not reversible, and it has nothing to do, conceptually, with flipping the sign of a number.

Somewhere between these two extremes, there is a line; where exactly you draw it depends on personal preference. Language designers usually have ideas about where to draw that line, and the language reflects this in a way. The difference between the C++ way and the Python way, however, is merely syntax sugar.

I think operator overloading is a powerful tool that can lead to very expressive code, if used tastefully. Going wild should be avoided, but just like with any powerful language feature, it is the responsibility of the programmers, not the compiler, to guard this.

0

To start with my beloved quote on the subject:

I saw `cout' being shifted "Hello world" times to the left and stopped right there.
— Steve Gonedes

Much like any powerful feature, or like any feature, it can and will be misused by someone. That being said, making it a little harder to do it, is probably worth the effort.

What you really don't want to happen, is to have people defining non-evident operators. Let me give you some examples of binary operators (with a and b being the operands):

  • Array<T> * int : returns an Array<T> of length a.length * b by concatinating a b times to an empty array
  • Array<int> * int : returns an Array<int>, where each element of a is multiplied b
  • Array<T> * T->R : returns an Array<R>, where each element is the return value of calling b with the element from a (functional map)
  • Array<T> / T->bool: returns an Array<T>, where only those elements are included, for which b returns true
  • ...

You can have a lot of fun with this. And people do. And it's arguably ok, if it's not ambiguous (example 1 and example 2) and people understand it (example 3 and example 4), which is generally achieved by choosing relatively clear operators and then sticking to them consistently.

The only language, where I toyed with operator overloading was Ruby, which makes it very simple as well. Interestingly, people don't tend to abuse it. To speculate about some reasons:

  • Ruby's standard library includes most of the collections you will need and overloads operators on them in a sparse, yet very meaningful way. From a programmers perspective, the most commonly overloaded operator is probably the space ship operator, but for obvious reasons, with obvious consequences.
  • Ruby has a "tighter" community than C++ (probably rubygems play a role in this, or maybe the long time in the shadows before the hype did), so you don't have too many people writing their own collections-DSL through operator overloading
  • Ruby calls can omit parentheses. You'll probably laugh at that. Programmers are extremely lazy and parentheses are rather slow to type. Therefore writing a.add b is a viable alternative to overloading +.

So from that I would say: the best way to stop people from abusing operator overloading is to provide good alternatives.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.