www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - __has_side_effects

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
https://www.reddit.com/r/programming/comments/88aqsf/the_joy_of_max/

Discussion aside, I notice with pleasant surprise gcc has an 
introspection primitive we didn't think of: __is_constant that (I 
assume) yields true if the given expression has no side effects.

In D the primitive would be called e.g. __has_side_effects to avoid 
confusion with the "const" qualifier.

I wonder how difficult it would be to define __has_side_effects (it 
would apply to an alias) and how it can be put to good use.


Andrei
Mar 30 2018
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 30 March 2018 at 20:28:27 UTC, Andrei Alexandrescu 
wrote:
 https://www.reddit.com/r/programming/comments/88aqsf/the_joy_of_max/

 Discussion aside, I notice with pleasant surprise gcc has an 
 introspection primitive we didn't think of: __is_constant that 
 (I assume) yields true if the given expression has no side 
 effects.

 In D the primitive would be called e.g. __has_side_effects to 
 avoid confusion with the "const" qualifier.

 I wonder how difficult it would be to define __has_side_effects 
 (it would apply to an alias) and how it can be put to good use.


 Andrei
It's actually quite easy. make a function literal annotated with pure and call your function, if that returns the function had no side effects. if something is constant you can determine by using at in ctfe context, if that function call does not compile then it is not a constant.
Mar 30 2018
parent reply Shachar Shemesh <shachar weka.io> writes:
On 30/03/18 23:35, Stefan Koch wrote:
 On Friday, 30 March 2018 at 20:28:27 UTC, Andrei Alexandrescu wrote:
 https://www.reddit.com/r/programming/comments/88aqsf/the_joy_of_max/

 Discussion aside, I notice with pleasant surprise gcc has an 
 introspection primitive we didn't think of: __is_constant that (I 
 assume) yields true if the given expression has no side effects.

 In D the primitive would be called e.g. __has_side_effects to avoid 
 confusion with the "const" qualifier.

 I wonder how difficult it would be to define __has_side_effects (it 
 would apply to an alias) and how it can be put to good use.


 Andrei
It's actually quite easy. make a function literal annotated with pure and call your function, if that returns the function had no side effects. if something is constant you can determine by using at in ctfe context, if that function call does not compile then it is not a constant.
That would work in C++. It does not work with D. D is willing to call functions that have side effects "pure". struct S { int a; void func(int b) pure { // For some strange reason, this is not considered a pure violation. a+=b; } }
Mar 31 2018
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Saturday, 31 March 2018 at 19:18:24 UTC, Shachar Shemesh wrote:
 struct S {
   int a;

   void func(int b) pure {
     // For some strange reason, this is not considered a pure 
 violation.
     a+=b;
   }
 }
It's the exact equivalent of this code: void func(ref S s, int b) pure { S.a += b; } And that code is perfectly pure accordion to D rules - it does not modify any data not reachable through its arguments. -- Simen
Mar 31 2018
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/31/18 4:01 PM, Simen Kjærås wrote:
 On Saturday, 31 March 2018 at 19:18:24 UTC, Shachar Shemesh wrote:
 struct S {
   int a;

   void func(int b) pure {
     // For some strange reason, this is not considered a pure violation.
     a+=b;
   }
 }
It's the exact equivalent of this code: void func(ref S s, int b) pure {     S.a += b; } And that code is perfectly pure accordion to D rules - it does not modify any data not reachable through its arguments.
Yah, only strongly pure functions would qualify. Indeed that's easy for the compiler to figure - so I'm thinking pragma(isStronglyPure, expression) would be easy to define. What would be some good uses of this? Andrei
Mar 31 2018
next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Saturday, 31 March 2018 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
 Yah, only strongly pure functions would qualify. Indeed that's 
 easy for the compiler to figure - so I'm thinking 
 pragma(isStronglyPure, expression) would be easy to define.

 What would be some good uses of this?


 Andrei
Surely you mean __traits(isStronglyPure, expression)?
Mar 31 2018
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/31/18 8:35 PM, Nicholas Wilson wrote:
 On Saturday, 31 March 2018 at 20:44:13 UTC, Andrei Alexandrescu wrote:
 Yah, only strongly pure functions would qualify. Indeed that's easy 
 for the compiler to figure - so I'm thinking pragma(isStronglyPure, 
 expression) would be easy to define.

 What would be some good uses of this?


 Andrei
Surely you mean __traits(isStronglyPure, expression)?
Affirmative, thx for the correction.
Mar 31 2018
prev sibling parent Mark <smarksc gmail.com> writes:
On Saturday, 31 March 2018 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
 Yah, only strongly pure functions would qualify. Indeed that's 
 easy for the compiler to figure - so I'm thinking 
 pragma(isStronglyPure, expression) would be easy to define.

 What would be some good uses of this?


 Andrei
It can be used for some rudimentary compiler checks. Namely, in some contexts it doesn't make sense for an expression to have (or rather not have) any side effects: - The increment section in a for loop must have a side effect, unless it's empty. - An assert expression shouldn't have any side effects (because assertions disappear in release mode). Maybe the compiler already does such checks, I don't know. In general this seems far less useful than the concept of a pure function.
Apr 01 2018
prev sibling parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Friday, 30 March 2018 at 20:28:27 UTC, Andrei Alexandrescu 
wrote:
 https://www.reddit.com/r/programming/comments/88aqsf/the_joy_of_max/

 Discussion aside, I notice with pleasant surprise gcc has an 
 introspection primitive we didn't think of: __is_constant that 
 (I assume) yields true if the given expression has no side 
 effects.

 In D the primitive would be called e.g. __has_side_effects to 
 avoid confusion with the "const" qualifier.

 I wonder how difficult it would be to define __has_side_effects 
 (it would apply to an alias) and how it can be put to good use.


 Andrei
Just for the fun of it, I implemented this as a template: https://run.dlang.io/is/pXLndG
Mar 31 2018
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 1 April 2018 at 04:11:37 UTC, Uknown wrote:
 On Friday, 30 March 2018 at 20:28:27 UTC, Andrei Alexandrescu 
 wrote:
 https://www.reddit.com/r/programming/comments/88aqsf/the_joy_of_max/

 Discussion aside, I notice with pleasant surprise gcc has an 
 introspection primitive we didn't think of: __is_constant that 
 (I assume) yields true if the given expression has no side 
 effects.

 In D the primitive would be called e.g. __has_side_effects to 
 avoid confusion with the "const" qualifier.

 I wonder how difficult it would be to define 
 __has_side_effects (it would apply to an alias) and how it can 
 be put to good use.


 Andrei
Just for the fun of it, I implemented this as a template: https://run.dlang.io/is/pXLndG
You're missing classes, AAs, and pointers (possibly function pointers and delegates as well).
Mar 31 2018
parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Sunday, 1 April 2018 at 04:30:03 UTC, Nicholas Wilson wrote:
 On Sunday, 1 April 2018 at 04:11:37 UTC, Uknown wrote:
 On Friday, 30 March 2018 at 20:28:27 UTC, Andrei Alexandrescu 
 wrote:
 [...]
Just for the fun of it, I implemented this as a template: https://run.dlang.io/is/pXLndG
You're missing classes, AAs, and pointers (possibly function pointers and delegates as well).
I knew I was missing something. Fixed it, thanks https://run.dlang.io/is/tZeZrP
Mar 31 2018
parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Sunday, 1 April 2018 at 05:27:38 UTC, Uknown wrote:
 [...]

 I knew I was missing something. Fixed it, thanks

 https://run.dlang.io/is/tZeZrP
Sorry for the spam, but I also managed to miss `immutable`, `const` and when T has mutable indirections Final version that I'm sure covers all the cases: https://run.dlang.io/is/kGoU4X
Mar 31 2018
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/1/18 2:22 AM, Uknown wrote:
 On Sunday, 1 April 2018 at 05:27:38 UTC, Uknown wrote:
 [...]

 I knew I was missing something. Fixed it, thanks

 https://run.dlang.io/is/tZeZrP
Sorry for the spam, but I also managed to miss `immutable`, `const` and when T has mutable indirections Final version that I'm sure covers all the cases: https://run.dlang.io/is/kGoU4X
That's a great initiative, and a worthy trait for the stdlib. I think you'd have an easier time if you reasoned from the other end. A function is strongly pure if all of the following are true: * Each parameter: - is immutable, OR - can be converted automatically to immutable (i.e. has no mutable indirections) AND is passed by value * The return type: - is immutable, OR - can be converted automatically to immutable (We don't want to give const this much power yet for other reasons.) The template should support taking the function name as a string, too, and the parameter types so as to easily distinguish across overloads. This would be a great addition to std.traits. Once we have it, we'll have a precise unified definition of strongly pure across the language spec and the stdlib definition. Please follow up, thanks! Andrei
Apr 01 2018
next sibling parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Sunday, 1 April 2018 at 10:23:40 UTC, Andrei Alexandrescu 
wrote:
 On 4/1/18 2:22 AM, Uknown wrote:
 [...]
That's a great initiative, and a worthy trait for the stdlib. I think you'd have an easier time if you reasoned from the other end. A function is strongly pure if all of the following are true: [...]
I got a working implementation that satisfies your requirements in about 60 lines. I will make a Pull Request as soon as I write the Docs and unittests. Here's the implementation: https://run.dlang.io/is/kVpv36
Apr 01 2018
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/1/18 9:39 AM, Uknown wrote:
 On Sunday, 1 April 2018 at 10:23:40 UTC, Andrei Alexandrescu wrote:
 On 4/1/18 2:22 AM, Uknown wrote:
 [...]
That's a great initiative, and a worthy trait for the stdlib. I think you'd have an easier time if you reasoned from the other end. A function is strongly pure if all of the following are true: [...]
I got a working implementation that satisfies your requirements in about 60 lines. I will make a Pull Request as soon as I write the Docs and unittests. Here's the implementation: https://run.dlang.io/is/kVpv36
Terrific, thanks!!
Apr 01 2018
parent Uknown <sireeshkodali1 gmail.com> writes:
On Sunday, 1 April 2018 at 14:33:14 UTC, Andrei Alexandrescu 
wrote:
 On 4/1/18 9:39 AM, Uknown wrote:
 On Sunday, 1 April 2018 at 10:23:40 UTC, Andrei Alexandrescu 
 wrote:
 On 4/1/18 2:22 AM, Uknown wrote:
 [...]
Terrific, thanks!!
Created the PR: https://github.com/dlang/phobos/pull/6403
Apr 01 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, April 01, 2018 06:23:40 Andrei Alexandrescu via Digitalmars-d 
wrote:
 On 4/1/18 2:22 AM, Uknown wrote:
 On Sunday, 1 April 2018 at 05:27:38 UTC, Uknown wrote:
 [...]

 I knew I was missing something. Fixed it, thanks

 https://run.dlang.io/is/tZeZrP
Sorry for the spam, but I also managed to miss `immutable`, `const` and when T has mutable indirections Final version that I'm sure covers all the cases: https://run.dlang.io/is/kGoU4X
That's a great initiative, and a worthy trait for the stdlib. I think you'd have an easier time if you reasoned from the other end. A function is strongly pure if all of the following are true: * Each parameter: - is immutable, OR - can be converted automatically to immutable (i.e. has no mutable indirections) AND is passed by value * The return type: - is immutable, OR - can be converted automatically to immutable (We don't want to give const this much power yet for other reasons.)
In principle, a function which has const parameters could be treated as strongly pure if it's given immutable arguments, but I don't believe that the language does that, and in that case, you couldn't just test a function to see if it was strongly pure, since in some cases, it would depend on the arguments. So, to test for strong purity, you'd need both the function and the arguments, meaning that it wouldn't so much be the case that a function was strongly pure as a function call was strongly pure. Such a change to strong purity would increase the number of optimizations that could be based on pure, but I don't know that it would be worth it, especially since it would then be much harder to have a trait like this, and functions are so rarely called with the same arguments in the same expression or statement that I'm not sure that such a change would really add much in the way of optimization opportunities. - Jonathan M Davis
Apr 01 2018
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/1/18 9:46 AM, Jonathan M Davis wrote:
 In principle, a function which has const parameters could be treated as
 strongly pure if it's given immutable arguments
I want to give coders leeway to cheat on that. I'll explain later (allocators).
Apr 01 2018