What does it mean for opCmp and opEquals to be consistent?

dnspies dspies at ualberta.ca
Thu Apr 3 09:19:37 PDT 2014


On Thursday, 3 April 2014 at 10:42:33 UTC, monarch_dodra wrote:
> On Thursday, 3 April 2014 at 10:15:46 UTC, Jonathan M Davis 
> wrote:
>> _Any_ type which overloads both opEquals and opCmp and does 
>> not make them
>> match exactly is just plain broken.
>
> I disagree:
>
>> If a.opEquals(b) is true, then a.opCmp(b) must be 0.
>> If a.opCmp(b) is non-zero, then a.opEquals(b) must be false.
>
> Yes.
>
>> If a.opEquals(b) is false, then a.opCmp(b) must be non-zero.
>> If a.opCmp(b) is 0, then a.opEquals(b) must be true.
>
> I disagree.
>
> You could have types with full comparison, but only *partial 
> ordering*, depending on the "norm" you used to define their 
> weight.
>
> A trivial example would be a 2D coordinate object, where 
> opEquals is what you'd expect, and opCmp is some sort of norm 
> (say, Euclidian).
>
> In this context, (1, 0) and (0, 1) would not be equal, but 
> they'd have the same "weight" in terms of ordering.
>
> EG: They are not "equal", but they are "equivalent" (to quote 
> C++ terminology)
>
> Or for example, a "Person" object. You'd have strict equality. 
> But for ordering, you'd use height.
>
> So (John, 182cm) and (David, 182cm) would not be equal, but 
> they'd be equivalent.
>
> --------
>
> A correctly implemented AA would use opCmp to store objects in 
> each bucket in cases of hash collisions, but still use opEqual 
> in case of equivalence.


I would agree.  Formally, it seems natural that a comparison 
operator could expect the equivalence classes of some equivalence 
relation to be totally ordered, while the elements within each 
class are unordered (this is more strict than just having a 
partial ordering, but less strict than requiring the elements 
themselves to be totally ordered).

But the documentation together with the feedback I've gotten here 
seems to imply that the elements do have to be totally ordered if 
I want to use them as AA keys (which is fine, it just means that 
after sorting by height, you should use names as a tiebreaker so 
(David, 182cm) < (John, 182cm) ).



More information about the Digitalmars-d-learn mailing list