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) ).

Reply via email to