Why do we have transitive const, again?
Jonathan M Davis
jmdavisProg at gmx.com
Thu Sep 22 01:12:13 PDT 2011
On Wednesday, September 21, 2011 10:15:31 Mehrdad wrote:
> I can't find the thread, but I remember someone (bearophile?) mentioned
> that the reason we have transitive const is to support purity.
>
> I don't think I understand why this is necessary, though -- could
> someone please explain why we have transitive const, and what problems
> it fixes?
I believe that it comes down primarily to three things:
1. To provide strong compiler guarantees (unlike C++)
2. immutability
3. simplicity
Take this C++ code for example
class C
{
public:
....
vector<int*> getter() const
{
return _var;
}
private:
vector<int*> _var;
}
int func(const C& c)
{
...
vector<int*> v = c.getter();
*v[2] = 3;
...
}
c is const, and yet func changes its state. That makes it very difficult (if not
impossible) for the compiler to give any guarantees about const beyond
complaining when you directly try and alter a const variable. So, the compiler
can't use const for optimizations or whatnot unless it's dealing with a
primitive type - even if there was no mutable and you couldn't cast away const
and alter variables.
Now, what if you add immutable into the mix? The compiler _must_ be able to
make guarantees about immutable. If the above were D code (with non-
transivitive const/immutable) with immutable, then the compiler couldn't
actually do anything useful with immutable, because it couldn't guarantee that
c was actually immutable. In order to do stuff like pass objects across threads
with send and receive, you must have compiler guarantees that the object is
actually immutable. And because anything which is const could actually be
immutable (aside from value types where there is no difference between const
and immutable), const must provide all of the guarantees that immutable does.
And so, they must both be transitive.
Now, on some level at least, we could avoid the need for fully transitive
const using some sort of tail and head const where we fully specified what was
and wasn't const or immutable. Stuff would still have to be fully immutable to
be passed along with functions like send and receive, and you'd lose some
optimizations when using head or tail const instead of fully transitive const,
but it could be done, and there are situations where it would be useful.
However, doing that gets far too complicated. It would make const too hard to
use. It was explored early in D2 and dropped precisely because of the
usability issues. Instead, we went with fully transitive const which could be
minimally restricted with parens.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list