On Thursday, 1 February 2018 at 18:58:15 UTC, H. S. Teoh wrote:
However, if we go back to the idea of tail-const, we could
potentially eliminate the need for casts and also avoid
breaking immutable. Basically, the problem with writing
const(RefCounted!T) is that it's a one-way street: on the scale
of increasing restrictiveness, we have the series:
RefCounted!T < RefCounted!(const(T)) < const(RefCounted!T)
Once you've gone all the way down to const(RefCounted!T), you
can no
longer safely back out to RefCounted!(const(T)).
So that means we want to avoid const(RefCounted!T) completely.
I'm not really saying I disagree with that, but it's just not
realistic. Which code would you rather write?
void foo(T)(const T t) {}
foo(myValue);
or:
void foo(T)(T t) if (isTailConst!T) {}
foo(myValue.tailConst);
The beauty of .headMutable is it generally doesn't affect user
code. If we have to tell people not to use const(T) because its
semantics are broken, we've failed.
Now, if at any point in your program you have an
immutable(RefCounted!T), something's gone horribly wrong -
basically all of the RefCounted's semantics break down when it's
immutable, and any attempt at fixing it is undefined behavior. I
think we can safely disregard the problems of
immutable(RefCounted!T).
Once we've defined immutable(RefCounted!T) to be undefined
behavior, suddenly casting from const(RefCounted!T) to
RefCounted!(const(T)) is OK again.
--
Simen