Persistent list

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Sun Nov 15 21:31:02 PST 2015


On Sunday, 15 November 2015 at 19:57:12 UTC, Andrei Alexandrescu 
wrote:
> On 11/15/2015 01:50 PM, Jonathan M Davis wrote:
>> On Sunday, 15 November 2015 at 18:09:15 UTC, Andrei 
>> Alexandrescu wrote:
>>> On 11/15/2015 01:00 PM, Jonathan M Davis wrote:
>>>> Basically, we have to decide between having physical const 
>>>> with the
>>>> guarantees that it provides
>>>
>>> We have that - it's immutable. -- Andrei
>>
>> Yes and no. As it stands, I can know that
>>
>> const foo = getFoo();
>> foo.bar();
>>
>> won't mutate foo unless I have another, mutable reference to 
>> foo
>> somewhere that bar somehow accessed.
>
> That is an illusion, and we need to internalize that. Consider:
>
> // inside some module
> struct T
> {
>   int[] data;
>   void bar()
>   {
>     // look, ma, no hands
>     g_data[1]++;
>   }
> }
> static int[] g_data;
> const(T) getFoo()
> {
>   T result;
>   result.data = g_data = [1, 2, 3];
>   return result;
> }
>
> In other words, you truly need access to the implementation of 
> getFoo() in order to claim anything about the changeability of 
> stuff. Note that I could even afford to have getFoo() return 
> const, so no need for the caller to make it so!

Which is why I brought up pure. If either getFoo or bar is pure, 
then your backdoor doesn't work. Yes, without pure, globals work 
as a backdoor, but technically, they do that with immutable too, 
since you can put the entire state of the object outside of the 
object using globals.

> With immutable, it's all cool. Immutable data is truly 
> immutable, and that can be counted on. But const, even today, 
> cannot be assumed to be as strong.

No, const is not as strong as immutable. But my point is that 
as-is const still provides some guarantees about physical 
constness. And particularly when it's combined with pure, there 
are a lot of cases where you can rely on a const object not being 
mutated unless the programmer violates the type system. Contrast 
that with C++ where pretty much any function could choose to cast 
away const and mutate an object, making the const attribute 
essentially meaningless in principle. In practice, programmers 
are obviously better behaved than that, but it means that in D 
right now, const does provide actual compiler guarantees (even if 
they're not as strong as those for immutable), whereas in C++ it 
really only prevents accidental mutation.

If we go the route of making casting away const and mutating 
defined behavior (and possible adding something like @mutable), 
then what we'll end up with is a transitive version of C++'s 
const, and that definitely provides worse guarantees than we have 
now. So, we would be losing something if we made that change.

That being said, const as-is _is_ very restrictive, and a number 
of idioms are completely incompatible with it, and that sucks. 
But we've known that for some time, and the answer has generally 
been to either not use those idioms or to not use const - which 
unfortunately does mean that const often can't be used (and a 
container that needs to do fancy stuff with its internals is 
probably a prime place where it can't be used).

So, I'm not necessarily against changing how const works. It _is_ 
restrictive to the point of being impractical in a lot of code. 
But if we make such a change, we _will_ be losing out on the kind 
of compiler guarantees that Walter has been harping on for ages - 
how C++'s const is pretty much useless since it doesn't really 
guarantee anything, whereas D's const does provide compiler 
guarantees because it can't be legally cast away and mutated. And 
you don't seem to see that (at least based on what you've been 
saying).

There is a tradeoff to be made here. We've been choosing one side 
of that tradeoff for years now - the side that C++ didn't choose. 
Maybe we made the wrong choice and should switch sides. But it is 
a tradeoff, not a clear-cut decision.

- Jonathan M Davis


More information about the Digitalmars-d mailing list