No. toString, toHash, opCmp and opEquals should not change the object _in default_. It is valuable design.
And, If you want to change object through the methods, you still CAN define mutable version in derived classes. class YourClass : Object { string toString() { /*cache calculated string*/ return str; } striing toString() const { return super.toString(); // use Object.toString instead mutable version return (cast(YourClass)this).toString(); // bypass const type system } } But mutable version doesn't call const version *through Object class reference* But you cannot call mutable version from a class reference typed Object. auto my = new YourClass(); my.toString(); // call mutable version const cy = my; cy.toString(); // call const version Object mo = my; mo.toString(); // call _const_ version. const co = mo; co.toString(); // call const version. Yes, I can agree this may have problem in certain cases. But I argue that is better design than others from the view of minimum language design, and provides valuable restriction - that is correct in most cases - in default. Kenji Hara 2012/5/14 Timon Gehr <timon.g...@gmx.ch>: > On 05/13/2012 06:39 PM, Stewart Gordon wrote: >> >> http://d.puremagic.com/issues/show_bug.cgi?id=1824 >> >> This has gone on for too long. >> >> Object.toString, .toHash, .opCmp and .opEquals should all be const. > > > No, please. > > Transitive enforced const + OO -> epic fail. (especially for unshared data, > which is the default and most common) > > The lack of head-mutable class references does not make this any better. > > I'd rather keep the current state of affairs than blindly mark the existing > methods const. Caching/lazy evaluation is everywhere. One single lazily > cached class member implies that all of the relevant methods cannot use that > member. What if they have to? They certainly have to! > > Const/immutable are great for simple value-types. Classes can contain > immutable values as fields. > > >> (It's also been stated somewhere that they should be pure and nothrow, >> or something like that, but I forget where.) >> > > Similar concerns apply for them (but less so than for const). I don't want > to have to violate the type system to get basic stuff done in OO-ish style! > Forced const invariants are annoying enough already. > > >> This makes it a nightmare to use const objects in data structures, > > > Why on earth would you want to do that? > > >> among other things, at best forcing the use of ugly workarounds. There are >> probably other, more serious effects of this that can't easily be worked >> around. >> > > I wouldn't bet on that. Marking the methods const, on the other hand, > certainly would have serious effects. > > >> It seems that the main obstacle is rewriting the relevant methods in >> std.stream. The current implementation doesn't make sense anyway - >> reading the entire contents of a file is certainly not the way to >> generate a hash or string representation of the stream. I'm thinking the >> hash should probably be the stream handle, and the string representation >> could perhaps be the full pathname of the file. Of course, what it >> should be for non-file streams is another matter. (This would be a >> change at the API level, but when the API's as fundamentally flawed as >> this....) >> >> Are there any other bits of druntime/Phobos that need to be sorted out >> before these methods can be declared const/pure/nothrow once and for all? >> > > Almost _all_ of Phobos would have to become const "correct", and it cannot, > because 'const' is an over-approximation and there is no const-inference. > const on the top-class interface invades _everything_. > > Marking the methods const would break every non-trivial D program out there > and put programmers in a frustrating straitjacket.