Head Const

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Wed Feb 17 14:31:00 PST 2016


On Wednesday, 17 February 2016 at 22:06:20 UTC, Walter Bright 
wrote:
> On 2/17/2016 10:54 AM, Marc Schütz wrote:
>> That's already covered in the DIP, see my reply to Dicebot.
>
> Note that D supports opaque types, meaning it is not always 
> possible to transitively follow all types to see if they have 
> mutable members.

We _could_ have something like @mutable on member variables which 
made them mutable in spite of being in a const object and which 
made it illegal for that type to ever be immutable, but we'd be 
forced to have an additional attribute on the type itself (e.g. 
@contains_mutable) because of the opaque type issue, and at that 
point, the compiler could just look at the attribute on the type 
to know that it couldn't be immutable, and similar to abstract, 
it could then require that any type that it's a member of t hen 
be marked with that attribute. So, it's uglier than simply 
marking a member variable with @mutable, but it's certainly 
feasible.

The question really is whether we want such a backdoor in const 
and whether it's worth the extra complication. It _would_ be 
explicitly marked, making it fairly easy to determine when a 
const type might actually mutate some of its state (though 
presumably, if it's used responsibly, it would only mutate state 
that was really part of the logical state of the object - e.g. a 
mutex or a reference count). So, while const would be weakened on 
some level, it wouldn't be completely invisible, and you couldn't 
accidentally have a member variable with an @mutable member, 
since you'd be forced to mark the type containing it with 
@contains_mutable. And it _would_ allow a number of idioms that 
many folks keep wanting and complaining about without actually 
making it defined behavior to cast away const and mutate (even 
Andrei has been running into issues lately with containers and 
RCString where he's needed @mutable and then done stuff like cast 
away const and mutating, thinking that that was okay as long as 
the underlying object wasn't immutable). It would be a backdoor, 
but it would be a well-defined one rather than allowing a 
free-for-all.

I honestly don't know whether adding something like @mutable is a 
good idea or not, but it is very clear that there are a number of 
idioms that are impossible in D when const is involved that lead 
a lot of programmers to either not use const or to cast it away 
and mutate, thinking that that's okay, because it's okay in C++, 
and it does tend to work as long as immutable isn't involved, 
much as it's undefined behavior. Having @mutable would make const 
usable for a lot of programs that otherwise have to mostly 
abandon it, but it would add some extra complication to the 
language, and it would mean that there's a backdoor in const, 
even if it's one that's actually safe to use (unlike casting away 
const and mutating).

But what _is_ clear to me is that transitive const has been a big 
win, and while I can definitely live with C++'s version of const 
if I have to, it drives me nuts now that it's not transitive. 
Without transitivity, it's too easy to end up with mutable 
references to stuff from const functions, just because they're 
not directly part of the object. Transitivity fixes all that.

- Jonathan M Davis


More information about the Digitalmars-d mailing list