WAT: opCmp and opEquals woes

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 23 18:12:58 PDT 2014


On Thursday, 24 July 2014 at 00:45:05 UTC, Andrei Alexandrescu 
wrote:
> std.algorithm.sort does not use equality at all. It just deems 
> objects for which pred(a, b) and pred(b, a) as unordered. --

I know. It uses < by default. What I'm disputing is that it's 
okay to define a type whose opCmp does not match its opEquals - 
or even that it has opCmp but doesn't have opEquals. I would 
strongly argue that such a type should not use opCmp for its 
ordering, because otherwise, its comparison operators are not 
consistent with how the comparison operators work for the 
built-in types.

I brought up sort, because that's usually where the question of 
ordering comes up, and our sort function is designed so that it 
does not require opCmp (the same with other Phobos constructs 
such as RedBlackTree). So, if a type needs to do its ordering in 
a manner which is inconsistent with opEquals, it can do so by 
providing a function other than opCmp for those comparisons.

But I think that it's a poor idea to have opCmp not be consistent 
with opEquals, since most generic code will assume that they're 
consistent. I'd strongly argue that an overloaded operate should 
be consistent with how the built-in operators work, or that 
functionality should not be using an overloaded operator. This is 
especially important when generic code comes into play, but it's 
also very important with regards to understanding how code works 
in general. Operators bring with them certain expectations of 
behavior, and they should maintain that and not be used in a 
manner which violates that. And having opCmp be inconsistent with 
opEquals violates that, indicating that opCmp should not be used 
in that case.

As such, I don't think that arguing that opCmp should be able to 
exist without an opEquals is a bad argument. I think that if you 
have opCmp, you should required to have opEquals (though not 
automatically defined as lhs.opCmp(rhs) == 0, because that would 
incur a silent performance hit).

- Jonathan M Davis


More information about the Digitalmars-d mailing list