WAT: opCmp and opEquals woes

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 23 18:37:22 PDT 2014


On Thu, Jul 24, 2014 at 12:51:31AM +0000, Jonathan M Davis via Digitalmars-d wrote:
> On Thursday, 24 July 2014 at 00:31:55 UTC, Jonathan M Davis wrote:
> >I would argue that the compiler should still be generating opEquals
> >even if opCmp is defined.
> 
> I take this back. As I later suggested in a post somewhere else in
> this thread (and the bug report that H.S. Teoh opened), I think that
> we should continue to not define opEquals, but we should add a way to
> tell the compiler to use the default-generated one (similar to what
> C++11 does). That way, the programmer is forced to consider what
> opEquals is supposed to do when opCmp is defined, but they're still
> able to use the default-generated one. The same goes for toHash.
> 
> Regardless, because automatically making opEquals be lhs.opCmp(rhs) ==
> 0 incurs a silent performance hit, I think that it's a bad idea.
[...]

This sounds like a reasonable compromise. If the user defines opCmp,
then it is an error not to define opEquals. However, opEquals can be
specified to be default, to get the compiler-generated version:

	struct S {
		int opCmp(S s) { ... }
		bool opEquals(S s) = default;
	}

Optionally, we could also allow opEquals to be @disabled, perhaps.

Same goes with toHash.

Keep in mind, though, that due to current AA changes in 2.066 beta,
existing code WILL break unless we autogenerate opEquals to be
opCmp()=0. In fact, issue 13179 was originally filed because 2.066 beta
broke Tango. My current stance is that these AA changes are an
improvement that we should keep, so then the question becomes, should we
break code over it, or should we introduce opEquals = (opCmp()==0),
which would allow existing code *not* to break?

Given the choice between (1) breaking code *and* allowing opCmp to be
inconsistent with opEquals, as the current situation is, and (2) *not*
breaking code and making opEquals consistent with opCmp by default, I
would choose (2) as being clearly more advantageous. The above
compromise solves the opEquals/opCmp consistency problem, but does not
address the inevitable code breakage that will happen when 2.066 is
released. Is it really worth the ire of D coders to have their existing
code break, for the questionable benefit of being able to make opEquals
inconsistent with opCmp just so we can support partial orderings on
types?

I don't know about you, but if it were up to me, I would much rather go
with the solution of setting opEquals = (opCmp()==0) by default, and let
the user redefine opEquals if they want partial orderings or eliminate
performance hits, etc..


T

-- 
Skill without imagination is craftsmanship and gives us many useful objects such as wickerwork picnic baskets.  Imagination without skill gives us modern art. -- Tom Stoppard


More information about the Digitalmars-d mailing list