www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - impure

reply Dom DiSc <dominikus scherkl.de> writes:
I'm creating a library that is completely pure, but it doesn't 
compile with pure: at the top because of one impure unittest 
(which uses random to  test some things only probabilistic)!

So do I really need to declare every function pure individually 
because of a test?!?

Can we please have a  impure attribute?
And by the way also  throws and  gc?
That would make live so much easier...
Mar 24
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 24, 2024 1:41:41 AM MDT Dom DiSc via Digitalmars-d-learn 
wrote:
 I'm creating a library that is completely pure, but it doesn't
 compile with pure: at the top because of one impure unittest
 (which uses random to  test some things only probabilistic)!

 So do I really need to declare every function pure individually
 because of a test?!?

 Can we please have a  impure attribute?
 And by the way also  throws and  gc?
 That would make live so much easier...
It's been brought up a number of times before that it would be desirable to have a way to negate attributes, and maybe we'll get that ability at some point, but for now, we don't have it. The only attributes that can be negated are safe, trusted, and system, because using one of them directly on a function overrides any others that are applied more globally. So, for now, you cannot apply pure to an entire module and then have it not apply to something within the module (though you could put that one test at the top before you apply pure). Another thing you could do would be to use debug {} to ignore attributes within that block (though then that code will only be run when building with -debug). How much sense that makes depends on what your test is doing, but it is a way to get around pure in code that isn't intended to be used in production. All of that being said, I'd be inclined to argue that in general, mass-applying attributes is asking for trouble. It works to a point, but it makes it easy to forget which attributes apply, and in some cases, attributes get ignored when they're mass-applied (though that's mostly on types IIRC). It makes more sense when you're applying an attribute to the entire module and not just a section of a module, but it does have a tendency to become a maintenance problem - particularly when it's code that more than one person works on. It also makes code harder to review, because diffs won't include any of the attributes that are being mass-applied, making it easy to miss the fact that a particular attribute applies to the code being changed. So, yes, you've run into a problem that it would be nice to have a better fix for, but even if we could negate attributes in general, there are good reasons to prefer to avoid mass-applying attributes. - Jonathan M Davis
Mar 24
parent reply Dom DiSc <dominikus scherkl.de> writes:
On Sunday, 24 March 2024 at 09:16:20 UTC, Jonathan M Davis wrote:
 So, yes, you've run into a problem that it would be nice to 
 have a better fix for, but even if we could negate attributes 
 in general, there are good reasons to prefer to avoid 
 mass-applying attributes.
I don't see it as "mass-applying attributes" rather than changing the default to something more sane, so that I have to apply *less* attributes to any single function. If the addition of new keywords (like "throws", " gc" and "impure") is a problem, why not doing it like nogc(false) or nogc=false (likewise for nothrow and pure)?
Apr 05
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, April 5, 2024 3:11:42 AM MDT Dom DiSc via Digitalmars-d-learn 
wrote:
 On Sunday, 24 March 2024 at 09:16:20 UTC, Jonathan M Davis wrote:
 So, yes, you've run into a problem that it would be nice to
 have a better fix for, but even if we could negate attributes
 in general, there are good reasons to prefer to avoid
 mass-applying attributes.
I don't see it as "mass-applying attributes" rather than changing the default to something more sane, so that I have to apply *less* attributes to any single function.
The core issue is that the place that is applying the attributes is far from what they're being applied to, which makes it extremely easy to miss them and not know which attributes are actually being applied - particularly when reviewing code, since then you tend to be looking primarily at diffs and not the entire file. It's going to be less of a problem with personal projects, but with any project where multiple people work on the code, it can start being a problem. Ultimately, having the attributes directly on what they apply to tends to result in fewer maintenance issues - particularly with larger projects.
 If the addition of new keywords (like "throws", " gc" and
 "impure") is a problem, why not doing it like  nogc(false) or
  nogc=false (likewise for nothrow and pure)?
There are a number of ways that it could be done, but regardless, we'd need a DIP and an implementation, and neither has happened. It's a known problem but hasn't been a big enough problem to have been made a priority. - Jonathan M Davis
Apr 06
prev sibling next sibling parent reply MrJay <mrjcraft2021 gmail.com> writes:
On Sunday, 24 March 2024 at 07:41:41 UTC, Dom DiSc wrote:
 I'm creating a library that is completely pure, but it doesn't 
 compile with pure: at the top because of one impure unittest 
 (which uses random to  test some things only probabilistic)!

 So do I really need to declare every function pure individually 
 because of a test?!?

 Can we please have a  impure attribute?
 And by the way also  throws and  gc?
 That would make live so much easier...
A better way to apply a attribute to an entire file is to use an explicit scope you can still apply this to basically the entire file but leave the tests out of it. second since these are test its better for them to be pure, so use debug as it implicitly tells you where all global mutation happen, if you need your unit tests to run without debug for what ever reason fall back to suggestion one. `dmd test.d -debug` ``` d // File name test.d import std.stdio; int var = 0; void main() { writeln(var); var = 1; writeln(var); foo(); writeln(var); baz(); writeln(var); } pure { int foo() { debug { var = 2;} return 2; } // you can nest scopes safe { int bar () { return 3; } } } void baz() { var = 4; } ```
Apr 07
parent Dom DiSc <dominikus scherkl.de> writes:
On Sunday, 7 April 2024 at 23:32:24 UTC, MrJay wrote:
 A better way to apply a attribute to an entire file is to use 
 an explicit scope you can still apply this to basically the 
 entire file but leave the tests out of it.
Better than an explicit impure (or pure=false) attribute? I don't think so. It heavily uglyfies the file, as single items without a specific attribute are interspersed in the file. So the scope need to end before and start again after the affected function or test. An it stops working at all if e.g. one test is impure and another test is gc, because then the scopes overlap and can no more be contained in each other. Really, having the counter-attributes would improve the language.
Apr 08
prev sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Sunday, 24 March 2024 at 07:41:41 UTC, Dom DiSc wrote:
 I'm creating a library that is completely pure, but it doesn't 
 compile with pure: at the top because of one impure unittest 
 (which uses random to  test some things only probabilistic)!

 So do I really need to declare every function pure individually 
 because of a test?!?

 Can we please have a  impure attribute?
 And by the way also  throws and  gc?
 That would make live so much easier...
Try `debug unittest {...}`?
Apr 08
parent reply Dom DiSc <dominikus scherkl.de> writes:
On Monday, 8 April 2024 at 07:03:40 UTC, Alexandru Ermicioi wrote:
 On Sunday, 24 March 2024 at 07:41:41 UTC, Dom DiSc wrote:
 I'm creating a library that is completely pure, but it doesn't 
 compile with pure: at the top because of one impure unittest 
 (which uses random to  test some things only probabilistic)!

 So do I really need to declare every function pure 
 individually because of a test?!?

 Can we please have a  impure attribute?
 And by the way also  throws and  gc?
 That would make live so much easier...
Try `debug unittest {...}`?
Cool. This seems to work. That's a nice workaroud for tests. Yay!
Apr 08
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Monday, 8 April 2024 at 07:53:01 UTC, Dom DiSc wrote:
 On Sunday, 24 March 2024 at 07:41:41 UTC, Dom DiSc wrote:
 Try `debug unittest {...}`?
Cool. This seems to work. That's a nice workaroud for tests. Yay!
Nice, fyi, you can use it with statements inside function bodies as well. Usefull for doing logging in pure functions.
Apr 08