Why are opEquals/opCmp arguments not in or const for Objects?

Jonathan M Davis jmdavisProg at gmx.com
Mon Mar 18 16:06:23 PDT 2013


On Monday, March 18, 2013 22:11:49 Stewart Gordon wrote:
> On 18/03/2013 01:05, Jonathan M Davis wrote:
> > On Monday, March 18, 2013 00:53:52 Stewart Gordon wrote:
> >> Why would some class want to implement these methods in a way that alters
> >> the object?
> > 
> > Because const in D is physical const, not logical const. So, for instance,
> > const prevents caching. And it's quite possible that a type which really
> > cared about efficiency would cache the calculated value for toHash. Make
> > toHash const would make that impossible. Another possible problem would
> > be lazy initialization. If opEquals is const, then lazy initialization
> > becomes impossible.
> 
> Look up std.functional.memoize.

It doesn't work with pure as it forces you to put state outside of the object, 
and it's only applicable to caching, not lazy initialization. In either case, 
by making opEquals const, it's impossible to have any state cached in the 
object or to have any state in the object which is lazily initialized.

> > We've discussed this on a number of occasions, and it's clear that forcing
> > these functions to be const is a major problem, and yet they do need to be
> > const for them to work with const objects. What was finally decided during
> > the last big discussion on this a few months back was that we would
> > remove opEqulas, opCmp, toHash, and toString from Object. They don't need
> > to be there. As long as everything in the runtime which deals with them
> > is templated, then there's no technical reason why Object would need
> > them.
> <snip>
> 
> That's true. It would even grant the benefit of being able to use
> opEquals, opCmp, toHash or some combination of them in the AA
> implementation, depending on which methods exist.
> 
> But the drawback of this approach (compared with making Object
> const-correct) is that some library programmers will (continue to)
> neglect const-correctness when implementing these methods, just as
> Walter did. Either by simply forgetting to declare them const, by
> caching information wihtin the object instead of using memoize, or by
> inadvertently doing something else that changes the object's state.

structs don't have any restrictions on them either with regards to opEquals 
and friends, and that works just fine. Given how strict D's const is, it just 
plain doesn't work to force it on people. Yes, it's great to use it as much as 
you reasonably can, but unlike C++, const comes at a very high cost in D, and 
it must be used with care. You just can't assume that it'll work in the 
general case.

- Jonathan M Davis


More information about the Digitalmars-d mailing list