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

Reply via email to