digitalmars.D.learn - A purity change
- bearophile (20/20) Jul 11 2013 This used to compile (probably dmd 2.060):
- H. S. Teoh (12/35) Jul 11 2013 [...]
- Meta (3/9) Jul 11 2013 Isn't it okay for pure functions to access global immutable
- H. S. Teoh (6/16) Jul 11 2013 True, I didn't think of that. :) So in this case it looks like a
- monarch_dodra (4/21) Jul 11 2013 It's not a global static though. It's a member immutable, but
- Maxim Fomin (7/28) Jul 11 2013 My guess is that before 2.063 immutable int y was implicitly
- bearophile (5/11) Jul 11 2013 I think you are right. So is it right to ask D to infer such
- Maxim Fomin (5/17) Jul 11 2013 I think delegate here can be allowed to be pure. However, I
- bearophile (7/9) Jul 11 2013 Yet, in the code I used to initialize y in the normal constructor
- Maxim Fomin (5/15) Jul 11 2013 The reason it worked in normal constructor prior the change was
- monarch_dodra (4/8) Jul 11 2013 Daym. Who thought it was a good idea to make immutable static by
This used to compile (probably dmd 2.060): struct Foo { immutable int y; void bar(TF)(TF f) pure { f(1); } void spam() pure { bar((int x) => y); } } void main() {} But now it gives: test.d(4): Error: pure function 'test.Foo.bar!(immutable(int) delegate(int x) nothrow safe).bar' cannot call impure delegate 'f' test.d(7): Error: template instance test.Foo.bar!(immutable(int) delegate(int x) nothrow safe) error instantiating Is it a correct error? Bye, bearophile
Jul 11 2013
On Thu, Jul 11, 2013 at 05:25:09PM +0200, bearophile wrote:This used to compile (probably dmd 2.060): struct Foo { immutable int y; void bar(TF)(TF f) pure { f(1); } void spam() pure { bar((int x) => y); } } void main() {} But now it gives: test.d(4): Error: pure function 'test.Foo.bar!(immutable(int) delegate(int x) nothrow safe).bar' cannot call impure delegate 'f' test.d(7): Error: template instance test.Foo.bar!(immutable(int) delegate(int x) nothrow safe) error instantiating Is it a correct error?[...] Hmm. This seems to be a tricky corner case. The delegate itself is impure, as it accesses y which is outside of its definition and isn't part of its arguments; however, in the larger context of spam(), this shouldn't be a problem since y is accessed via 'this', and 'this' is part of spam's input. I'm not sure how feasible it is for the compiler to statically check such cases, though. But IMO we should at least look into this. T -- Why can't you just be a nonconformist like everyone else? -- YHL
Jul 11 2013
On Thursday, 11 July 2013 at 16:14:13 UTC, H. S. Teoh wrote:On Thu, Jul 11, 2013 at 05:25:09PM +0200, bearophile wrote: Hmm. This seems to be a tricky corner case. The delegate itself is impure, as it accesses y which is outside of its definition and isn't part of its arguments; however, in the larger context of spam(), this shouldn't be a problem since y is accessed via 'this', and 'this' is part of spam's input.Isn't it okay for pure functions to access global immutable state, such as what the delegate is doing here?
Jul 11 2013
On Thu, Jul 11, 2013 at 06:31:13PM +0200, Meta wrote:On Thursday, 11 July 2013 at 16:14:13 UTC, H. S. Teoh wrote:True, I didn't think of that. :) So in this case it looks like a regression. T -- Mediocrity has been pushed to extremes.On Thu, Jul 11, 2013 at 05:25:09PM +0200, bearophile wrote: Hmm. This seems to be a tricky corner case. The delegate itself is impure, as it accesses y which is outside of its definition and isn't part of its arguments; however, in the larger context of spam(), this shouldn't be a problem since y is accessed via 'this', and 'this' is part of spam's input.Isn't it okay for pure functions to access global immutable state, such as what the delegate is doing here?
Jul 11 2013
On Thursday, 11 July 2013 at 16:53:30 UTC, H. S. Teoh wrote:On Thu, Jul 11, 2013 at 06:31:13PM +0200, Meta wrote:It's not a global static though. It's a member immutable, but accessed via the (impure) context pointer. It should work, but it's not just straight up global immutableOn Thursday, 11 July 2013 at 16:14:13 UTC, H. S. Teoh wrote:True, I didn't think of that. :) So in this case it looks like a regression. TOn Thu, Jul 11, 2013 at 05:25:09PM +0200, bearophile wrote: Hmm. This seems to be a tricky corner case. The delegate itself is impure, as it accesses y which is outside of its definition and isn't part of its arguments; however, in the larger context of spam(), this shouldn't be a problem since y is accessed via 'this', and 'this' is part of spam's input.Isn't it okay for pure functions to access global immutable state, such as what the delegate is doing here?
Jul 11 2013
On Thursday, 11 July 2013 at 15:25:10 UTC, bearophile wrote:This used to compile (probably dmd 2.060): struct Foo { immutable int y; void bar(TF)(TF f) pure { f(1); } void spam() pure { bar((int x) => y); } } void main() {} But now it gives: test.d(4): Error: pure function 'test.Foo.bar!(immutable(int) delegate(int x) nothrow safe).bar' cannot call impure delegate 'f' test.d(7): Error: template instance test.Foo.bar!(immutable(int) delegate(int x) nothrow safe) error instantiating Is it a correct error? Bye, bearophileMy guess is that before 2.063 immutable int y was implicitly static, but now it is per instance data which requires context pointer which is deduced to be impure - that why compilation fails (try placing static attribute). In other words, before 2.063 this was a function and now it is a delegate. And delegates currently don't play well with constness/immutability.
Jul 11 2013
Maxim Fomin:My guess is that before 2.063 immutable int y was implicitly static, but now it is per instance data which requires context pointer which is deduced to be impure - that why compilation fails (try placing static attribute). In other words, before 2.063 this was a function and now it is a delegate. And delegates currently don't play well with constness/immutability.I think you are right. So is it right to ask D to infer such delegate as pure? Bye, bearophile
Jul 11 2013
On Thursday, 11 July 2013 at 17:59:22 UTC, bearophile wrote:Maxim Fomin:I think delegate here can be allowed to be pure. However, I wouldn't expect this issue to be fixed soon since it touches a general problem of delegates vs. immutability problem. There were many discussions and DIP but there is still no solution.My guess is that before 2.063 immutable int y was implicitly static, but now it is per instance data which requires context pointer which is deduced to be impure - that why compilation fails (try placing static attribute). In other words, before 2.063 this was a function and now it is a delegate. And delegates currently don't play well with constness/immutability.I think you are right. So is it right to ask D to infer such delegate as pure? Bye, bearophile
Jul 11 2013
Maxim Fomin:My guess is that before 2.063 immutable int y was implicitly static,Yet, in the code I used to initialize y in the normal constructor of Foo. If now I tag y as static, that's not possible any more (Error: can only initialize static const member scale inside static constructor), so I don't understand again. Bye, bearophile
Jul 11 2013
On Thursday, 11 July 2013 at 18:03:14 UTC, bearophile wrote:Maxim Fomin:The reason it worked in normal constructor prior the change was probably the same bug. This docs covers the issue - http://dlang.org/changelog.html#staticfieldsMy guess is that before 2.063 immutable int y was implicitly static,Yet, in the code I used to initialize y in the normal constructor of Foo. If now I tag y as static, that's not possible any more (Error: can only initialize static const member scale inside static constructor), so I don't understand again. Bye, bearophile
Jul 11 2013
On Thursday, 11 July 2013 at 18:28:19 UTC, Maxim Fomin wrote:The reason it worked in normal constructor prior the change was probably the same bug. This docs covers the issue - http://dlang.org/changelog.html#staticfieldsDaym. Who thought it was a good idea to make immutable static by default? Seems I've been confused in my prior answer because of that.
Jul 11 2013