Head Const

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Wed Feb 17 16:41:45 PST 2016


On Wednesday, 17 February 2016 at 23:47:54 UTC, Walter Bright 
wrote:
> On 2/17/2016 3:12 PM, Jonathan M Davis wrote:
>> On Wednesday, 17 February 2016 at 22:44:27 UTC, Walter Bright 
>> wrote:
>>
>>> It would seem that implementing headconst as a type 
>>> constructor would let
>>> people who wanted mutable members have their way, without 
>>> introducing
>>> backdoors in const.
>>
>> I really don't see how that's the same thing at all. The main 
>> problems with
>> const pop up when what folks need is something like C++'s 
>> mutable, because they
>> need to be able to do something like a reference count or a 
>> mutex which is not
>> really part of the logical state of the object but is still 
>> part of the object.
>> Having some form of non-transitive const allows for things 
>> like a const pointer
>> to non-const data, but it doesn't help at all when what you 
>> need to do is treat
>> most of the object as const while treating a small portion of 
>> it as mutable.
>> Sure, that's not completely transitive, because parts of the 
>> object are mutable,
>> but it's specific parts of the object, not which part of a 
>> pointer declaration
>> is const and which isn't. Maybe I'm missing something, but I 
>> don't see how
>> adding non-transitive const to D in order to solve the C++ 
>> declaration problem
>> would help at all with the complaints that folks have with D's 
>> const. The
>> complaints with D's const are almost entirely about the lack 
>> of backdoors (be
>> they well-defined like a mutable attribute or a free-for-all 
>> like casting away
>> const and mutating).
>
> If the headconst was one level up, the struct can have mutating 
> members.

Yes, but that really isn't going to help much code. It would be 
useless for ref-counting const objects, it wouldn't allow you to 
put a mutex in a const object, and you couldn't do anything with 
caching calculated properties in a const object. All it means is 
that you can do something like have a const pointer to a mutable 
object, which in my experience is usually useless. There have 
been plenty of complaints about having to use Rebindable instead 
of having tail-const for classes, but I've rarely seen anyone 
complain about the lack of head-const. And what's usually the 
case is that folks want logical const, and I don't see how that's 
possible without either having something similar to C++'s mutable 
or make it well-defined to cast away const and mutate.

Having something similar to C++'s mutable would at least solve 
most of the problem while making it explicit and safe, whereas 
allowing casting away const and mutating would just throw all of 
the guarantees of const out the window and risk serious problems 
with immutable, making it so that all const really did was 
prevent accidental mutation and serve as documentation of intent. 
Something like @mutable would at least retain the guarantees that 
we currently have when @mutable isn't used and restrict the 
effects of removing const to very well defined areas such that it 
wouldn't run afoul of immutable.

So, if we want to actually solve the problems that folks 
typically complain about with const, I think that something like 
@mutable is the way to go. Now, we can certainly decide that 
that's not worth it and that those idioms simply won't work in D 
as long as const is used, but I really don't think that 
head-const is going to solve the same problem at all or really 
make much of anyone much happier aside from how it helps with C++ 
interoperability. Adding tail-const for classes to the language 
would make a whale of a lot more people happy than head-const 
would even though Rebindable ostensibly solves that problem 
already.

- Jonathan M Davis


More information about the Digitalmars-d mailing list