Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
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." –  kiamlaluno Sep 10 '11 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 +)? –  delnan Sep 10 '11 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. –  dietbuddha Sep 11 '11 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 '12 at 21:48
add comment

8 Answers

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?

share|improve this answer
add comment

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.

share|improve this answer
1  
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 '11 at 18:23
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
    
How does this adress the question? –  delnan Sep 10 '11 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 '11 at 16:02
    
@delnan My answer its based in the description of the post, not the post' question ;-) –  umlcat Sep 10 '11 at 16:22
3  
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 '11 at 16:55
    
PS. Java has no support for this. –  quant_dev Sep 10 '11 at 16:56
show 1 more comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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