December 30, 2020 Re: D does have head const (but maybe it shouldn't) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Haughton | On Wednesday, 30 December 2020 at 20:33:34 UTC, Max Haughton wrote: > On Tuesday, 29 December 2020 at 20:47:10 UTC, John Colvin wrote: >> On Tuesday, 29 December 2020 at 19:42:28 UTC, John Colvin wrote: >>> [...] >> >> It's so head-const that I made the beginnings of a friendly 100% @safe head-const with it. Please don't use it. >> >> [...] > > Isn't there already Final in experimental typecons? > > I think with any method like this you are slightly at the mercy of the ABI for structs but I haven't been bitten yet. It's perfectly ok to create a type that is un-reassignable like std.experimental.typecons.Final. What makes my code evil is it actually carrying the type-qualifier. |
December 30, 2020 Re: D does have head const (but maybe it shouldn't) | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On 29.12.20 17:15, ag0aep6g wrote: > Exercise: Consider the following `main` function. Define `f` and `g` so that the code is valid, compiles, and runs successfully. The asserts must be executed and they must pass. > > ---- > void main() pure @safe > { > int* x = new int; > const y = f(x); > *x = 1; > g(y); > assert(*x == 2); > } > ---- > > Hints: > * You can't store `x` in a global because the code is `pure`. > * You can't cast `const` away in `g` because that would be invalid. > * You're supposed to find a type for which `const` means head const. > > Solution: https://run.dlang.io/is/dsaGFS > > The validity of the given solution might be arguable, and I'd be in favour of outlawing it. It's surprising that there's a type for which `const` means head const when it means transitive const for everything else. It's so surprising that even DMD trips over it (<https://issues.dlang.org/show_bug.cgi?id=21511>). It's a bug. Here's a number of such "solutions" with links to the corresponding bug reports, the last one is the same as your suggested solution. They are all type system holes on the same level: they break aliasing invariants that the type system is supposed to preserve in `pure @safe` code. --- // https://issues.dlang.org/show_bug.cgi?id=17744 int* f(int* x)pure @safe{ return x; } void g(const(int)* y)pure @safe{ inout(int)* delegate(inout(int)*)pure @safe delegate()pure @safe foo(inout(int)* y)pure @safe{ inout(int)* bar(inout(int)* p)pure @safe{ return y; } return ()=>&bar; } int* x; *foo(y)()(x)=2; } --- --- // https://issues.dlang.org/show_bug.cgi?id=18566 auto f(int* x)pure @safe{ struct S{ void foo()const pure{ *x=2; } } return S(); } void g(S)(S s){ s.foo(); } --- --- // https://issues.dlang.org/show_bug.cgi?id=21517 // (this one is new, I found this while solving the challenge) auto f(int* x)pure @safe{ return x; } void g(const(int)* y)pure @safe{ int* foo(inout(int)* x)pure @safe{ int* bar(inout(int)* delegate(inout int)pure @safe z){ return z(2); } return bar((inout t)=>x); } *foo(y)=2; } --- --- // https://issues.dlang.org/show_bug.cgi?id=2947 class C{ int*[] a=[null]; } auto f(int* x)pure @safe{ (new C).a[0]=x; return x; } void g(const(int)* y)pure @safe{ *(new C).a[0]=2; } --- --- // https://issues.dlang.org/show_bug.cgi?id=9149#c11 auto f(int* x)pure @safe{ return (){ *x=2; }; } auto g(void delegate()pure @safe dg)pure @safe{ dg(); } --- |
December 31, 2020 Re: D does have head const (but maybe it shouldn't) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Wednesday, 30 December 2020 at 22:49:09 UTC, Timon Gehr wrote:
> On 29.12.20 17:15, ag0aep6g wrote:
>> [...]
>
> It's a bug. Here's a number of such "solutions" with links to the corresponding bug reports, the last one is the same as your suggested solution. They are all type system holes on the same level: they break aliasing invariants that the type system is supposed to preserve in `pure @safe` code.
>
> [...]
Is anyone working on those issues?
|
December 31, 2020 Re: D does have head const (but maybe it shouldn't) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 30.12.20 23:49, Timon Gehr wrote:
> ---
> // https://issues.dlang.org/show_bug.cgi?id=2947
> class C{ int*[] a=[null]; }
> auto f(int* x)pure @safe{
> (new C).a[0]=x;
> return x;
> }
> void g(const(int)* y)pure @safe{
> *(new C).a[0]=2;
> }
> ---
This is my favorite of the bunch. Ancient issue, many duplicates, has been argued to be working as intended, no fix on the horizon. It's lovely.
D does not have head const ... except when it does.
In D, `pure` functions cannot access global mutable state ... except when they can.
|
Copyright © 1999-2021 by the D Language Foundation