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