D does have head const (but maybe it shouldn't)
John Colvin
john.loughran.colvin at gmail.com
Tue Dec 29 20:47:10 UTC 2020
On Tuesday, 29 December 2020 at 19:42:28 UTC, John Colvin wrote:
> On Tuesday, 29 December 2020 at 17:56:51 UTC, H. S. Teoh wrote:
>> On Tue, Dec 29, 2020 at 05:13:48PM +0000, Petar via
>> Digitalmars-d wrote:
>>> [...]
>> [...]
>>> > [...]
>> [...]
>>> [...]
>>
>> I don't see why this is considered head const, nor why this
>> should be considered a bug. In the proposed solution `y` is
>> not a value type but a delegate that wraps the reference to
>> *x. Since x itself is non-const, this is perfectly valid, and
>> the `const` in `const y` refers to the immutability of the
>> delegate reference, not to the immutability of the wrapped
>> reference.
>>
>>
>> T
>
> It's a const variable that contains a mutable reference. It's
> head-const.
It's so head-const that I made the beginnings of a friendly 100%
@safe head-const with it. Please don't use it.
https://run.dlang.io/is/sZLSvZ
struct HeadConstable(T) {
import std.traits : ReturnType;
ReturnType!makeAccessor accessor;
private static makeAccessor(return ref T v) {
ref T impl() {
return v;
}
return &impl;
}
this(return ref T v) const {
accessor = makeAccessor(v);
}
ref T get() const pure @safe {
return accessor();
}
void opAssign(Q)(Q rhs) const
if (__traits(compiles, { get() = rhs; })) {
get() = rhs;
}
}
auto headConst(T)(ref T v) {
return const HeadConstable!T(v);
}
void main() pure @safe
{
int x;
auto y = headConst(x);
static assert(is(typeof(y) == const));
version (TestConstness) {
int z;
y = headConst(z); // Error: cannot modify const
expression y
}
x = 1;
y = 2;
assert(x == 2);
}
also, you can replace const with immutable or shared and have
endless fun breaking language guarantees and library expectations.
More information about the Digitalmars-d
mailing list