Thought operator overloading was the devils work?

Posted on 07/04/

Traditionally operator overloading has been criticized and normally avoided to the point where it has fallen into the back of our memories. Java didn't even implement it! But looking at it better... It looks like all the arguments that disaprove operator overloading are pointing at statically typed languages. Resuming: operator overload only gives you syntactic sugar so you don't have to do a bunch of (ugly) method calls around your code, but you pay the price of high maintenance costs [1], and the potential to suffer pain [2]. But nothing is said of dynamically typed languages! And I think there are times where this "satanized" techinque comes in handy in dynamically typed languages. It has a use that is not only for "aesthetical" reasons in dynamic languages. It provides functionality that static languages can't provide with it: It lets the programmer outgrow it's API.

The thought came to me when I was trying to out-trick a class that someone else had wrote. The class I was using was programmed in Perl (not rare in my case). It expects you to call methods with scalars that contain numbers, and operates on them with their normal operators (+ - / *). Perl scalars cannot handle integers bigger than 2^32 on a Perl compiled with 32 bit Integers (note: bigger numbers are converted to floats, and therefore lose precision). I had to pass BIG Integers. So... I looked up the options Perl gave me for big integers, and found Math::BigInt. But now my worry was: the classes I use don't have explicit support for BigInts, and I'm not the author of some of them! Luckily i found this in Math::BigInt documentation: "All operators (including basic math operations) are overloaded". Bingo! Now I can pass BigInts into classes that never expected them, and they can operate without code change. And everything works without a single hick-up.

So for some new classes I'll publish to CPAN, that have to do some basic mathematical operations on data structures, I'm thinking of keeping the functionality to the bare bones, and relying on clever programmers to do clever things with the inputs.

Let me explain: I have to calulate growth rates from mesurements that get taken at different times. It's as simeple as:

Given:
M1: measurement 1 at timestamp t1
M2: measurement 2 at timestamp t2
M is growing (like your kids' height), therefor M2 >= M1

I have to do two basic operations: difference (substraction) and division to get rates (things mesured per second)

M2-M1/(t2-t1) ... (yes... We're Deriving (calculating the "rate of change"). (It's like calculating velocity from distance, but with "things" instead of meters (feet for people that drive on the wrong side of the road :D)(loooove nested parenthesis!))).

That's not complicated, and has nothing to do with overriding operators, but somehow, that's the point! My class only has to know how to substract and divide "things". I will really have to be doing these operations with lots of magnitudes that have been taken at the same time. So I could chose to put all them in hashrefs and then implement this:

sub rates {
  my ($self) = @_;
  my $delta_t = $self->{'t2'} - $self->{'t1'};
  my $rates = {};
  foreach my $key (keys %{$self->{'m2'}}){
      $rates->{$key} = $self->{'m2'}->{$key} - $self->{'m1'}->{$key}) / $delta_t;
  }
}

Leaving the implementation limited to one level deep hashrefs.

OR

sub rates {
  my ($self) = @_;
  return (($self->{'m2'} - $self->{'m1'}) / ($self->{'t2'} - $self->{'t1'});
}

And let m1 and m2 be MagicHashSets (for my use case) with the following operations defined:

MagicHashSet1 - MagicHashSet2: foreach key in MagicHashSet1: substract the corresponding keys' value from MagicHashSet2
MagicHashSet1 / scalar: foreach key in MagicHashSet1: divide the corresponding keys' value between scalar.

You can observe that MagicHashSets are easily converted to MagicArraySets.

Note that you get one more property for free from this design... If the values of the keys in the MagicHashSets are themselves MagicHashSets... You get free n level deep operations for substraction and division! Yay!

So expect me to be posting my findings on this adventure in my next postings :). I really hope they are good findings, and not very bad ones. After all... Maybe operator overloads are the devils work }:D