Cliff Hacks Things.

Saturday, February 11, 2006

Commutative arguments

Had a sick thought today.

In considering the binary operator problem (mentioned in my post on multimethods a few days back), I thought, "What if certain functions could define themselves as order-insensitive?"

The canonical example seems to be a function for testing if two objects are equal, which we'll call equals(a, b). Equality, in my mind, is commutative, like addition: equals(a, b) should always have the same result as equals(b, a). (Thus, equals(equals(a, b), equals(b, a)).)

In a lot of situations, you don't want objects of two different classes to ever be equal. I would argue that numeric types are an exception: if I have the number 5 represented as a base-2 integer, and as an arbitrary-precision decimal type, they can be interconverted without a loss of data, and thus should be equal.

Now, people wanting to compare Integers and Decimals might write the comparison either way — or even not know which value is which type when the comparison is written. Traditionally, if you wanted to define variants of equals to cover this case, you'd have to write two functions — if your language even allows it:
equals(Integer, Decimal)
equals(Decimal, Integer)

What if, instead, the equals function would reorder its arguments as necessary? (Assume the runtime order of evaluation is fixed, in case you have side effects in your argument expressions.) Only one of these two declarations would be necessary — and, in fact, declaring both would be an error.

Addition and any other commutative operation would also benefit.

Now, of course, this doesn't solve the binary-operator problem for non-commutative operations like division, but it might be food for thought.


Post a Comment

<< Home