Tags

, , , ,

Is overloading a bad thing? Despite a wide variety of new languages supporting some form of it I continue to find articles that say overloading is bad. Worse, I find many articles that somehow think overloading operators is bad but that overloading functions is perfectly okay. Let’s take a quick look at the argument.

Evil Example

The example below often crops up as the evil of overloading.

a = b * c;

That seems innocent enough, doesn’t it? Well, many are quick to point out that in C++ that could mean anything, rather than simple multiplication. You see, you can overload the operator to change it’s meaning. In fact you can even change what that equal sign means. What at first glance appears to be a simple multiply and assign could in fact be absolutely anything!

I’ll gladly admit that you could do that in C++, but you probably wouldn’t. In fact if you completely changed the meaning of common operators you’re likely an idiot. But I don’t think a language should limit its features just to prevent fools from misusing them. That simply isn’t possible, some fool will always come around and mess it up. Consider the languages that allow overriding of functions, but not operators. We can rewrite the above as below.

a.assign( b.mul( c ) );

Though perhaps not quite as clear as the first bit of code, nobody would really doubt what that code was supposed to be doing. But what if mul wasn’t actually multiplying, and what if assign wasn’t actually assigning a value. What hose functions do is totally at the whim of the programmer. In fact, now that I look at it, this doesn’t even have anything to do with overloading. An idiot could write misleading code in any language with very little effort.

Good Uses

Overloading operators just makes sense in some case. It is unfortunate that C++ is one of the few languages to offer this ability. I personally find the first bit of code clearer than the second bit, provided that the operators actually do as expected. And why wouldn’t they? You see, the ability to overload an operator was intended to makeup for shortcomings in the standard library or available types. Used correctly overloading allows you to work with custom types as native types.

Don’t think so, so let’s look at example. In this code assume that the language doesn’t allow any overloading. You are doing some financial calculations, have a special Decimal number class, but still need to work with some integers and floating point.

Decimal  apply( Decimal base ) 
{
  Decimal r = base.add_int( 1 );
  r = r.mul_float( 3.5 );
  return base.sub_decimal( r );
}

It just seems like you’re typing a lot of things the compiler should already know. Doesn’t it just seem clearer to write the code below?

Double apply( Double base )
{
  Double r = base + 1;
  r = r * 3.5;
  return base - r;
}

The intent of this code is more apparent than in its previous form. Perhaps you’d like to argue that such overloaded types are a rarity, but that simply isn’t true. Between complex numbers, rationals, financial precision, stock ticks, astronomy, and any other number of specialized applications you can’t ever predict what numeric types might be needed. Further to that are any number of collection types that can make use of subscript notation. Or perhaps just a few data objects that would be nice to compare with less-than. In good hands operator overloading can make working with specialized types a lot easier.

Conclusion

I agree that obfuscating code by changing the meaning of operators is a bad idea. I hope however that my quick example can show that if used correctly it can be quite positive. It should also be clear that we can never protect languages from poor programmers, they will always find a way to wreak havoc. Arguing that a feature can be misused is simply a non-starter. Look at the features of the language and use them all appropriately. It is just as shame that very few have full overloading support.