Getting the const-correctness of Object sorted once and for all

kenji hara k.hara.pg at gmail.com
Sun May 13 18:10:28 PDT 2012


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.gehr at 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.


More information about the Digitalmars-d mailing list