www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP 1029---Add throw as Function Attribute---Community Review Round 1

reply Mike Parker <aldacron gmail.com> writes:
This is the feedback thread for the first round of Community 
Review for DIP 1029, "Add throw as Function Attribute":

https://github.com/dlang/DIPs/blob/8c48c98a0495f73db9a2d5c4aef502b9febe9673/DIPs/DIP1029.md

All review-related feedback on and discussion of the DIP should 
occur in this thread. The review period will end at 11:59 PM ET 
on January 28, or when I make a post declaring it complete.

At the end of Round 1, if further review is deemed necessary, the 
DIP will be scheduled for another round of Community Review. 
Otherwise, it will be queued for the Final Review and Formal 
Assessment.

Anyone intending to post feedback in this thread is expected to 
be familiar with the reviewer guidelines:

https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

*Please stay on topic!*

Thanks in advance to all who participate.

#DIP1029
#throw
Jan 14 2020
next sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1029, "Add throw as Function Attribute":

 https://github.com/dlang/DIPs/blob/8c48c98a0495f73db9a2d5c4aef502b9febe9673/DIPs/DIP1029.md

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on January 28, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment.

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.

 #DIP1029
 #throw
The idea is great, inverse attributes are very powerful in practice and are definitely very good in usability for a lot of code for example applying attributes to the entire D source file. I don't think making the attribute "throw" is the best way to go though. Currently most attributes use the at-attribute syntax which makes them very unambiguous and easier to (visually) parse. I would suggest instead of having throw as attribute, the new attribute should be throws instead. `throws` can also be argued for that it is "better" to read like: "function foo throws" than "function foo throw" Additionally if we make this an at-attribute, it can very easily be extended in the future to have arguments what kind of exceptions are being thrown by this function, for example using template argument syntax to be the easiest and most consistent to parse. This also exists in other languages like Java and helps both with linting for try-catch, but also extremely helps with documentation. For symmetry with nothrow it might be worth looking into providing nothrow as nothrow attribute instead too.
Jan 14 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 3:21 AM, WebFreak001 wrote:
 I don't think making the attribute "throw" is the best way to go though. 
 Currently most attributes use the at-attribute syntax which makes them very 
 unambiguous and easier to (visually) parse. I would suggest instead of having 
 throw as attribute, the new attribute should be  throws instead. `throws` can 
 also be argued for that it is "better" to read like: "function foo throws"
than 
 "function foo throw"
It's already a keyword so there's no problem with having it be 'throw'. Having 'throw', 'nothrow' and 'throws' as keywords looks excessive.
 Additionally if we make this an at-attribute, it can very easily be extended
in 
 the future to have arguments what kind of exceptions are being thrown by this 
 function, for example using template argument syntax to be the easiest and
most 
 consistent to parse. This also exists in other languages like Java and helps 
 both with linting for try-catch, but also extremely helps with documentation.
 
 For symmetry with nothrow it might be worth looking into providing nothrow as 
  nothrow attribute instead too.
The syntax for this is simply unnecessary.
Jan 14 2020
parent reply James Blachly <james.blachly gmail.com> writes:
On 1/14/20 3:28 PM, Walter Bright wrote:
 On 1/14/2020 3:21 AM, WebFreak001 wrote:
 I don't think making the attribute "throw" is the best way to go 
 though. Currently most attributes use the at-attribute syntax which 
 makes them very unambiguous and easier to (visually) parse. I would 
 suggest instead of having throw as attribute, the new attribute should 
 be  throws instead. `throws` can also be argued for that it is 
 "better" to read like: "function foo throws" than "function foo throw"
It's already a keyword so there's no problem with having it be 'throw'. Having 'throw', 'nothrow' and 'throws' as keywords looks excessive.
 Additionally if we make this an at-attribute, it can very easily be 
 extended in the future to have arguments what kind of exceptions are 
 being thrown by this function, for example using template argument 
 syntax to be the easiest and most consistent to parse. This also 
 exists in other languages like Java and helps both with linting for 
 try-catch, but also extremely helps with documentation.

 For symmetry with nothrow it might be worth looking into providing 
 nothrow as  nothrow attribute instead too.
The syntax for this is simply unnecessary.
Walter: To back up WebFreak001's assertions: the seemingly random keyword versus attribute decorators for functions are very jarring and disconcerting for new and even intermediate users. This is a perfect opportunity to harmonize things that, for very little downside, improve the apparent coherence of the language. "throws" also sounds far more grammatical than "throw"
Jan 15 2020
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Thursday, 16 January 2020 at 02:27:22 UTC, James Blachly wrote:
 This is a perfect opportunity to harmonize things that, for 
 very little downside, improve the apparent coherence of the 
 language.

 "throws" also sounds far more grammatical than "throw"
On top of that having all attributes with syntax would allow for them to be defined as simple UDAs in runtime, make them available for introspection in templated code and allowing to getting rid of functionAtrributes traits. Moreover this would allow easy extension of those attributes with additional data, be it template arguments or struct fields. Best regards, Alexandru.
Jan 16 2020
prev sibling next sibling parent reply IGotD- <nise nise.com> writes:
I agree with this change. The suggested solution will have very 
little or no impact on the current codebase while adding a useful 
feature.

I was originally for that we should use the "throws" keyword in 
order to make it more searchable. However, now when I see the 
solution and that "nothrow" will still remain I think that 
"throw" is better for symmetry with "nothrow".

Correct me if I'm wrong, what I've understood in the text is that 
making "nothrow" the default is also a goal which is not covered 
in this DIP but perhaps in a future DIP.
Jan 14 2020
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Tuesday, 14 January 2020 at 11:53:17 UTC, IGotD- wrote:
 I was originally for that we should use the "throws" keyword in 
 order to make it more searchable. However, now when I see the 
 solution and that "nothrow" will still remain I think that 
 "throw" is better for symmetry with "nothrow".
On that specific note, perhaps the DIP author can include some code search strategies to differentiate between (i) functions marked `throw` and (ii) lines of code where an exception is thrown ... ? It's minor, but it would be a nice consideration to folks whose search rules-of-thumb might be thrown out of whack by this change.
Jan 14 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 3:53 AM, IGotD- wrote:
 Correct me if I'm wrong, what I've understood in the text is that making 
 "nothrow" the default is also a goal which is not covered in this DIP but 
 perhaps in a future DIP.
That is the plan. It has no flesh at the moment.
Jan 14 2020
prev sibling next sibling parent Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:
 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*
This is good.
Jan 14 2020
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
This is good. I like how Walter defined the overriding enclosing 
scope rule as well, and the rationale about aggregates inheriting 
it is also correct and I like that.

Unambiguous yes from me to this particular step and DIP.
Jan 14 2020
prev sibling next sibling parent reply Arine <arine123445128843 gmail.com> writes:
I really don't like how small these DIPs are. It seems they don't 
have direction on their own.

This is given as part of the rationale:

     void bar(); // may throw

     struct S1 {
         nothrow void foo() { bar(); } // error, bar() throws
     }

     nothrow {
         struct S2 {
             void foo() { bar(); } // no error, as the nothrow 
block does not apply
         }
     }


Why isn't this being fixed so that `nothrow{}` then applies to 
`S2.foo()`? Why is it even part of the rationale if there's no 
intention to fix this?

If you are going to add `throw` why aren't the rest of the 
attributes getting inverses? Pure?  nogc? etc...

 Although this DIP does not propose making exceptions opt-in, 
 the throw attribute is a key requirement for it.
It seems this DIP's sole purpose is as a stepping stone for the next DIP to change the default of nothrow to be the default. On its' own it doesn't make sense, if your are trying to fix the disparity of being able to turn off attributes there's no reason to not include the rest of the attributes as well. Otherwise this shouldn't be it's own DIP. If the intention is this is only required for another DIP, this should just be included in that DIP. If the intention is the fix the problem that attributes don't have inverses to be able to turn them on/off, then I don't see why you need a separate DIP for each and every attribute. Include them all in the same DIP as well as address the strange behavior with structs/classes that was included as part of the rationale. If this is really just a stepping-stone DIP, what if the next DIP is rejected, but this one is accepted? What purpose would it have served? Just adding `throw` isn't a significant/meaningful enough change on it's own, if you look solely at this DIP.
Jan 14 2020
next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Tuesday, 14 January 2020 at 15:18:41 UTC, Arine wrote:
 If you are going to add `throw` why aren't the rest of the 
 attributes getting inverses? Pure?  nogc? etc...
Because those changes are not contingent on one another. One can make this change without impacting any of the other attributes. Where changes don't _need_ to be coupled, let's make the case for each of them on their own merits. It makes for a much simpler change management process. (Or if you really think it's worthwhile in its own right, write up your own DIP for a comprehensive set of invertible attributes.)
Jan 14 2020
parent reply bachmeier <no spam.net> writes:
On Tuesday, 14 January 2020 at 15:28:29 UTC, Joseph Rushton 
Wakeling wrote:
 On Tuesday, 14 January 2020 at 15:18:41 UTC, Arine wrote:
 If you are going to add `throw` why aren't the rest of the 
 attributes getting inverses? Pure?  nogc? etc...
Because those changes are not contingent on one another. One can make this change without impacting any of the other attributes. Where changes don't _need_ to be coupled, let's make the case for each of them on their own merits. It makes for a much simpler change management process.
I disagree. That's how your language turns into C++. The tough part of language design is making decisions conditional on what the language as a whole looks like, and what it's going to be in ten years. My opinion is that it's an ugly inconsistency to give only one attribute an inverse. Maybe others don't agree, but lately there's been an attempt to stifle discussion on major changes. That's fine, but then get rid of the DIP process, as it doesn't serve a purpose. Walter can push changes to master and then there can be announcement that the change has been made. No point pretending there's a process in place if you're not going to allow relevant discussion.
 (Or if you really think it's worthwhile in its own right, write 
 up your own DIP for a comprehensive set of invertible 
 attributes.)
This is a terrible idea. You don't need a DIP to counter a DIP. The DIP author has to write a document that can be defended. The ultimate goal is to make the right decision, not "best DIP wins".
Jan 14 2020
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Tuesday, 14 January 2020 at 15:58:31 UTC, bachmeier wrote:
 I disagree. That's how your language turns into C++. The tough 
 part of language design is making decisions conditional on what 
 the language as a whole looks like, and what it's going to be 
 in ten years.
I agree that one should think holistically when considering smaller changes. But one should also be clear about what couplings really _need_ to exist, and which don't.
 My opinion is that it's an ugly inconsistency to give only one 
 attribute an inverse.
OK. That's essentially an aesthetic concern, though: introducing an inverse for one attribute (where there is a particular motivation) doesn't block introducing other such inverses in future. (Actually, it increases the likelihood of being able to do this, by proving the usefulness of invertible attributes.) OTOH blocking this one motivated change with the argument that one must do this for all attributes or none, gets in the way of something useful. BTW, as the DIP noted, the inconsistency already exists in the form of safe and system.
 Maybe others don't agree, but lately there's been an attempt to 
 stifle discussion on major changes.
Discuss away, as far as I'm concerned. But if you want to push back on a small useful change on the grounds that it should be part of a much larger change, then it might be a good idea to bring stronger evidence of the _definite_ harm that will result from not taking the bigger-change route. Too many folks have a tendency to say things like "It will turn D into C++!" when that is merely an opinion, not a demonstrable fact. A lot of incompatible small feature steps can be problematic ... but that doesn't mean that a lot of small feature steps are a problem _in general_.
 That's fine, but then get rid of the DIP process, as it doesn't 
 serve a purpose. Walter can push changes to master and then 
 there can be announcement that the change has been made. No 
 point pretending there's a process in place if you're not going 
 to allow relevant discussion.
Who's forbidding any discussion? I simply offered an argument as to why this change should not be coupled with other changes to attributes, in response to an argument that it should be. You have every right to articulate your disagreement -- just as I did.
 This is a terrible idea. You don't need a DIP to counter a DIP. 
 The DIP author has to write a document that can be defended. 
 The ultimate goal is to make the right decision, not "best DIP 
 wins".
No, you don't need to write up a DIP to counter a DIP, but comprehensively introducing invertible attributes _will_ need a DIP. So if you (or anyone else) thinks that is needed or valuable, it's worth putting that DIP together. But if a DIP solves problem A, then it's not an argument against it to say, "But it doesn't solve B, C, D, ...". It's necessary to show that solving A _without_ B, C, D, ... is actively harmful -- or that the particular solution to A is problematic in its own right.
Jan 14 2020
next sibling parent reply bachmeier <no spam.net> writes:
On Tuesday, 14 January 2020 at 16:32:51 UTC, Joseph Rushton 
Wakeling wrote:
 On Tuesday, 14 January 2020 at 15:58:31 UTC, bachmeier wrote:
 I disagree. That's how your language turns into C++. The tough 
 part of language design is making decisions conditional on 
 what the language as a whole looks like, and what it's going 
 to be in ten years.
I agree that one should think holistically when considering smaller changes. But one should also be clear about what couplings really _need_ to exist, and which don't.
 My opinion is that it's an ugly inconsistency to give only one 
 attribute an inverse.
OK. That's essentially an aesthetic concern, though:
Is it a big deal? Maybe not, but it's strange to say "You can invert [random attribute] but no others." "Oh, why is that?" "Because that's all that was in the DIP." It's just sloppy and amateurish to design a language like that.
 No, you don't need to write up a DIP to counter a DIP, but 
 comprehensively introducing invertible attributes _will_ need a 
 DIP.  So if you (or anyone else) thinks that is needed or 
 valuable, it's worth putting that DIP together.
I don't even know if that's a good idea. All I'm asking for is a sensible argument in favor of adding an inverse of one and only one attribute. It makes absolutely no sense to me to have negation of nothrow but not nogc.
Jan 14 2020
next sibling parent IGotD- <nise nise.com> writes:
On Tuesday, 14 January 2020 at 17:01:42 UTC, bachmeier wrote:
 I don't even know if that's a good idea. All I'm asking for is 
 a sensible argument in favor of adding an inverse of one and 
 only one attribute. It makes absolutely no sense to me to have 
 negation of nothrow but not nogc.
I'm guessing that the reason is that one goal of this DIP was that it shouldn't have any breaking changes. However, if there is a future DIP for having "nothrow" as default, then it actually matters more.
Jan 14 2020
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Tuesday, 14 January 2020 at 17:01:42 UTC, bachmeier wrote:
 Is it a big deal? Maybe not, but it's strange to say "You can 
 invert [random attribute] but no others." "Oh, why is that?" 
 "Because that's all that was in the DIP." It's just sloppy and 
 amateurish to design a language like that.
Yes, but that's not the answer, is it? The answer to "Why is that?" is, possibly among other things, "Because it enables a transition path to exceptions being opt-in rather than opt-out." (Note there is no reason in principle why `nothrow` might not get deprecated and dropped if such a transition actually happens, so long run we may not end up with the one invertible attribute.) However, that does raise a good piece of review feedback: is it appropriate to introduce this new attribute as a DIP in its own right, rather than as a migration path for the nothrow-by-default DIP? Are there use-cases other than the transition that motivate the `throw` attribute or make it valuable? It would be good if the DIP could articulate those arguments if they exist -- and if they do not, perhaps its acceptance should be made conditional on the (not yet finalized) nothrow-by-default DIP.
 No, you don't need to write up a DIP to counter a DIP, but 
 comprehensively introducing invertible attributes _will_ need 
 a DIP.  So if you (or anyone else) thinks that is needed or 
 valuable, it's worth putting that DIP together.
I don't even know if that's a good idea. All I'm asking for is a sensible argument in favor of adding an inverse of one and only one attribute. It makes absolutely no sense to me to have negation of nothrow but not nogc.
You could look at that from the opposite point of view: what's the point in introducing an inverse to a particular attribute unless it has a practical motivation beyond the concept that "attributes should be invertible"? FWIW I do think it would be helpful for the DIP to offer a response to your question.
Jan 14 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Tuesday, 14 January 2020 at 16:32:51 UTC, Joseph Rushton 
Wakeling wrote:
 But if a DIP solves problem A, then it's not an argument 
 against it to say, "But it doesn't solve B, C, D, ...".  It's 
 necessary to show that solving A _without_ B, C, D, ... is 
 actively harmful -- or that the particular solution to A is 
 problematic in its own right.
It's not even solving a problem. That's the problem. This DIP is just a change that should be included in the DIP that plans to make nothrow default. Then it solves a problem for *that* DIP. *This* DIP doesn't illustrate a problem, and as such can't be a solution to a problem that doesn't exist (in this DIP). If the problem is that attributes don't have inverses, then this isn't a sufficient enough solution to that problem.
Jan 14 2020
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Tuesday, 14 January 2020 at 17:24:04 UTC, Arine wrote:
 It's not even solving a problem. That's the problem. This DIP 
 is just a change that should be included in the DIP that plans 
 to make nothrow default. Then it solves a problem for *that* 
 DIP.
I agree that it should be clarified if this is the case (see my post above).
Jan 14 2020
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 14.01.20 18:24, Arine wrote:
 
 It's not even solving a problem.
That's just plainly untrue. It solves the problem that if you put nothrow: There is no way to invert it for specific functions that you want to be able to throw. It's explained in the DIP.
Jan 14 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 15.01.20 06:05, Arine wrote:
 On Wednesday, 15 January 2020 at 02:42:09 UTC, Timon Gehr wrote:
 On 14.01.20 18:24, Arine wrote:
 It's not even solving a problem.
That's just plainly untrue. It solves the problem that if you put nothrow: There is no way to invert it for specific functions that you want to be able to throw. It's explained in the DIP.
The first sentence
The remainder of your post was just more of the same bad logic. I can reformulate my answer to make more clear how it relates to your post: It's clearly solving a problem. The DIP illustrates a problem and solves a problem that exists. The problem is that `nothrow` does not have an inverse and it is a sufficient enough solution to that problem.
 of a comment in the middle of someone else's discussion
This is the Community Review for DIP 1029. If you don't want your comments criticized, please don't post them here. This is not the place to have private conversations. Thanks!
Jan 14 2020
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 14 January 2020 at 15:18:41 UTC, Arine wrote:
 If this is really just a stepping-stone DIP, what if the next 
 DIP is rejected, but this one is accepted?
This is still a positive step.. I think we have a bad habit of rejecting small good steps in favor of larger better steps that don't come to pass. nothrow/throws itself is not amazing, but it would make it more likely to be used even by itself.
Jan 14 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 7:18 AM, Arine wrote:
 Why isn't this being fixed so that `nothrow{}` then applies to `S2.foo()`? Why 
 is it even part of the rationale if there's no intention to fix this?
Because it's the way the other attributes work. Trying to change this would be very disruptive. The reason it works this way is it is unkind to the purpose of scoping. If the attributes passed into nested scopes, then you'll pretty much force a coding guideline to "list all the attributes needed at the beginning of each scope" so it won't silently break when someone adds a: attribute: at the top.
 If you are going to add `throw` why aren't the rest of the attributes getting 
 inverses? Pure?  nogc? etc...
Since we already have a keyword available, it makes sense to use it. throw/nothrow nicely complement each other.
 Just adding `throw` 
 isn't a significant/meaningful enough change on it's own, if you look solely
at 
 this DIP.
It does add value on its own, as the user can now decide what his default is and override it as necessary. The value isn't huge, but the change is trivial, so the cost/benefit ratio is still good.
Jan 14 2020
next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 14 January 2020 at 20:35:44 UTC, Walter Bright wrote:
 [snip]

 Because it's the way the other attributes work. Trying to 
 change this would be very disruptive. The reason it works this 
 way is it is unkind to the purpose of scoping. If the 
 attributes passed into nested scopes, then you'll pretty much 
 force a coding guideline to "list all the attributes needed at 
 the beginning of each scope" so it won't silently break when 
 someone adds a:

  attribute:

 at the top.

 [snip]
I agree that it is disruptive, but I would hang my hat on the argument not being germane because such a change would affect other attributes as well. Keeping the change small is good, IMO. Nevertheless, I think a case could be made for changing the behavior. However, I would limit the change to attribute: while keeping the behavior of attribute { code } unchanged. I would phrase this as attribute: being for scope-wide defaults (including nested), while attribute { code } would be for scope-level defaults only. That makes these two features a bit more orthogonal, though potentially at a cost of some disruption. However, attribute: can currently be replaced by an attribute { code } wherever it is used. That means that if you change attribute: to pass into nested scopes, while leaving attribute { code } unchanged, then any code that could be broken by the change could be easily fixed by using attribute { code }. It becomes a lot more disruptive if you change attribute { code } too.
Jan 14 2020
prev sibling parent Arine <arine123445128843 gmail.com> writes:
On Tuesday, 14 January 2020 at 20:35:44 UTC, Walter Bright wrote:
 On 1/14/2020 7:18 AM, Arine wrote:
 Why isn't this being fixed so that `nothrow{}` then applies to 
 `S2.foo()`? Why is it even part of the rationale if there's no 
 intention to fix this?
Because it's the way the other attributes work. Trying to change this would be very disruptive. The reason it works this way is it is unkind to the purpose of scoping. If the attributes passed into nested scopes, then you'll pretty much force a coding guideline to "list all the attributes needed at the beginning of each scope" so it won't silently break when someone adds a: attribute: at the top.
You already have to do that if you don't want the defaults. It's not even optional, you're forced to do it for the very reason you are giving for why it is the way it is to avoid putting attributes at each new scope. Lol ironic. It's not something that will be very silent either. As all the attributes for nogc, pure, and nothrow will error when any other function tries to call those functions and those attributes have somehow been overwritten.
 If you are going to add `throw` why aren't the rest of the 
 attributes getting inverses? Pure?  nogc? etc...
Since we already have a keyword available, it makes sense to use it. throw/nothrow nicely complement each other.
There's problems to using "throw", as others have mentioned. I agree with others that "throws" is better. It's not low hanging fruit you make it out to be.
 Just adding `throw` isn't a significant/meaningful enough 
 change on it's own, if you look solely at this DIP.
It does add value on its own, as the user can now decide what his default is and override it as necessary. The value isn't huge, but the change is trivial, so the cost/benefit ratio is still good.
Great! Include ` gc` and `impure` in this DIP and I'm sold.
Jan 14 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 7:18 AM, Arine wrote:
 Otherwise this shouldn't be it's own DIP. If the intention is this is only 
 required for another DIP, this should just be included in that DIP.
It does make sense on its own. Furthermore, I don't want to distract the coming discussion on "nothrow as default" with all the debate about throw vs throws vs throw, etc. BTW, anyone wanting to discuss the merits of "nothrow as default" please use the "nothrow by default" thread started by Steven Schveighoffer on Jan 4.
Jan 14 2020
parent Arine <arine123445128843 gmail.com> writes:
On Tuesday, 14 January 2020 at 20:42:48 UTC, Walter Bright wrote:
 On 1/14/2020 7:18 AM, Arine wrote:
 Otherwise this shouldn't be it's own DIP. If the intention is 
 this is only required for another DIP, this should just be 
 included in that DIP.
It does make sense on its own.
It doesn't. Not with what's written in the DIP. If you don't care to elaborate I guess that's the end of that discussion.
 Furthermore, I don't want to distract the coming discussion on 
 "nothrow as default" with all the debate about throw vs throws 
 vs  throw, etc.
So talking about something that's part of the DIP is distracting from the DIP? Why are you trying to control the narrative that takes place in a DIP? You shouldn't be splitting up DIPs into non-nonsensical pieces just so you can tell people to not discuss certain aspects that relate to the current DIP because they are also part of another DIP.
 BTW, anyone wanting to discuss the merits of "nothrow as 
 default" please use the "nothrow by default" thread started by 
 Steven Schveighoffer on Jan 4.
I'd say as long as it mentions making nothrow the default in the DIP, this is fair to discuss here. It is part of this DIP after all.
Jan 14 2020
prev sibling next sibling parent reply Dukc <ajieskola gmail.com> writes:
This would be a step forward, of course. But would not it be 
better to kill the one-way attribute problem in one go -meaning, 
making an antiattribute for `pure` and ` nogc` too?

In addition, I suggest that there should be a way to use 
[`pure:`/`nothrow:`/` nogc:`/` safe:`/their antiattributes] so 
that they only apply when attributes are not inferred - not for 
templated functions. This would also remove a big obstacle from 
front of DIP1028, as one could just mark the whole module 
` system` with one statement without killing template ` safe` or 
` live` inference.

Also a few smaller things:

-Why `throw` instead of ` throw`? I'm not saying it's a bad idea, 
but write the rationale in DIP.

-You mention that due to lack of an antiattribute, aggregates 
don't propagate  nothrow to their member function. Since you 
claimed "no breaking changes", I guess you meant it to be left 
that way. But the DIP should be explicit about that.
Jan 14 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 8:44 AM, Dukc wrote:
 This would be a step forward, of course. But would not it be better to kill
the 
 one-way attribute problem in one go -meaning, making an antiattribute for
`pure` 
 and ` nogc` too?
Because for the anti-nothrow we already have a trivial solution staring us in the face, we just have to pick it up. I have no explanation for not seeing the obvious before.
 In addition, I suggest that there should be a way to use 
 [`pure:`/`nothrow:`/` nogc:`/` safe:`/their antiattributes] so that they only 
 apply when attributes are not inferred - not for templated functions. This
would 
 also remove a big obstacle from front of DIP1028, as one could just mark the 
 whole module ` system` with one statement without killing template ` safe` or 
 ` live` inference.
It turns out that there's another "attribute" under the covers - the default. Only when an attribute is the default does inference come into play. Hence, when "nothrow" becomes the default, there will be actually three states - throw, nothrow, and default. It works out rather nicely. It's in play for safe/trusted/system already, and has been since the beginning.
Jan 14 2020
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 14 January 2020 at 22:30:40 UTC, Walter Bright wrote:
 Hence, when "nothrow" becomes the default
IF, not when. I support this DIP as a nice independent move, but I am going to fight you on the step of changing the default. But, my plan here: http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html#my-attribute-proposal---no-changes-to-defaults to make `nothrow:` (etc) go into the child scopes except templates means we have a less disruptive way to make this work without formally changing the defaults.
Jan 14 2020
next sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Tuesday, 14 January 2020 at 23:04:02 UTC, Adam D. Ruppe wrote:
 On Tuesday, 14 January 2020 at 22:30:40 UTC, Walter Bright 
 wrote:
 Hence, when "nothrow" becomes the default
IF, not when. but I am going to fight you on the step of changing the default.
Same here.
 I support this DIP as a nice independent move,
It just needs gc, and impure and i'd say it'd be good to go.
 But, my plan here:
 http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html#my-attribute-proposal---no-changes-to-defaults

 to make `nothrow:` (etc) go into the child scopes except 
 templates means we have a less disruptive way to make this work 
 without formally changing the defaults.
This makes more sense than what we have right now for this DIP. Good work.
Jan 14 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 15.01.20 06:31, Arine wrote:
 
 It just needs  gc, and impure and i'd say it'd be good to go.
concrete, explicit, mutable, endorsed, runtime, internal, virtual, hide, unshared, dynamic, unsynchronized, dependable, __ungshared, ...
Jan 14 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 3:04 PM, Adam D. Ruppe wrote:
 to make `nothrow:` (etc) go into the child scopes except templates means we
have 
 a less disruptive way to make this work without formally changing the defaults.
As I remarked before, this will have the unintended consequence of causing the "best practice" to be listing all the attributes at the opening brace of all struct declarations just in case someone 5000 lines previously added an: attribute: Best practice: struct S { throw safe pure nogc etc. etc. etc. etc. ... ... } and then have to remember to add to that list for every new attribute. It's ugly, and people are going to hate it.
Jan 14 2020
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Wednesday, 15 January 2020 at 07:33:14 UTC, Walter Bright 
wrote:
 Best practice:

     struct S
     {
         throw  safe pure  nogc etc. etc. etc. etc. ...
         ...
     }

 and then have to remember to add to that list for every new 
 attribute. It's ugly, and people are going to hate it.
Honestly, based on experience of maintaining larger D codebases, I'm not sure it isn't anyway best practice to apply attributes (including protection attributes) only ever to individual symbols and functions. It can look a bit verbose, and obviously it can be annoying in the way you describe, but it really helps avoid any doubt what attributes apply in any given case.
Jan 15 2020
prev sibling next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 15 January 2020 at 07:33:14 UTC, Walter Bright 
wrote:
 [snip]

 Best practice:

     struct S
     {
         throw  safe pure  nogc etc. etc. etc. etc. ...
         ...
     }

 and then have to remember to add to that list for every new 
 attribute. It's ugly, and people are going to hate it.
Is that only an issue for child scopes? If you have a 5000 line file full of functions at the module level, then you run the risk of having to annotate all of them if someone puts attribute: at the top. It's also interesting that safe flows through, both with safe: and safe { code }.
Jan 15 2020
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 15 January 2020 at 07:33:14 UTC, Walter Bright 
wrote:
 As I remarked before, this will have the unintended consequence 
 of causing the "best practice" to be listing all the attributes 
 at the opening brace
I don't agree this is substantially different than the status quo, the unit of D's encapsulation is the module and it is expected things "spill over" inside a module boundary (see: private's semantics). But we can have this discussion later if it is too far from this thread's purpose.
 and then have to remember to add to that list for every new 
 attribute. It's ugly, and people are going to hate it.
People just won't do that. If you're happy with defaults, you'd simply not change the default at the top of the module!
Jan 15 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Wednesday, 15 January 2020 at 07:33:14 UTC, Walter Bright 
wrote:
 On 1/14/2020 3:04 PM, Adam D. Ruppe wrote:
 to make `nothrow:` (etc) go into the child scopes except 
 templates means we have a less disruptive way to make this 
 work without formally changing the defaults.
As I remarked before, this will have the unintended consequence of causing the "best practice" to be listing all the attributes at the opening brace of all struct declarations just in case someone 5000 lines previously added an: attribute: Best practice: struct S { throw safe pure nogc etc. etc. etc. etc. ... ... } and then have to remember to add to that list for every new attribute. It's ugly, and people are going to hate it.
I already have ` nogc nothrow pure:` at the top of almost every module. I also have the same at the top of every struct. It's happening right now, and it's not optional because you have to set the attributes based on the default. The only reason you never would have come across this is if you don't care about using those attributes as the default. *Current Day Best Practice, That's unavoidable if you want these attributes for everything*: module blah; nogc nothrow pure: struct A { nogc nothrow pure: } struct B { nogc nothrow pure: } struct C { nogc nothrow pure: void foo() { static struct D { nogc nothrow pure: } } }
     struct S
     {
         throw **** safe**** pure  nogc etc. etc. etc. etc. ...
         ...
     }
safe already passes it's value onto a struct's scope. Yet the problem you are describing doesn't exist for it. safe: struct S { void foo() { int* a = cast(int*)0; // error not allowed in safe } } That problem **does** exist now, because of the very thing you are saying prevents it. Because I can't just do ` nogc nothrow pure:` at the top of the module, I have to specify every single scope to be ` nogc nothrow pure:`. The language literally forces you to do it, unless you want to label each and every function with those attributes. I'm completely blown away, you don't even know that safe passes through to the next scope? Or did you just add that attribute to exaggerate the problem? The more I see this problem, and just how little Walter seems to understand of it. Being able to set defaults at the module level seems to make the most sense to me. Leave the garbage `attribute:` behavior the way it is, even if it is garbage. And add it so you can set the default based on the module. safe module blah; // defaults to safe system nothrow module blah2; // default is system and nothrow This breaks the least amount of code, and if you want to set safe to be the default. All someone has to do to get their code to work again is add ` system` in front of the module. nothrow module blah; throw: // same awful behavior with scope void foo(); // "throw" struct A { void bur(); // nothrow } Whatever I guess, this has just gone from one bad DIP to another to another to another since Andrei left.
Jan 15 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/15/2020 7:26 AM, Arine wrote:
 I'm completely blown away, you don't even know 
 that  safe passes through to the next scope?
My mistake. What actually happens is here: sc2.stc &= STC.safeGroup; https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.d#L136 where the storage class passed from the outer scope to the struct/class scope is zeroed out except for safe/ trusted/ system. So safe "flows through" to the struct scope, while nothrow, pure, nogc, etc., do not. For functions, the line is: sc2.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.abstract_ | STC.deprecated_ | STC.override_ | STC.TYPECTOR | STC.final_ | STC.tls | STC.gshared | STC.ref_ | STC.return_ | STC.property | STC.nothrow_ | STC.pure_ | STC.safe | STC.trusted | STC.system); https://github.com/dlang/dmd/blob/master/src/dmd/semantic3.d#L316 Interestingly, nogc does flow through here. So, the flow through behavior depends on the attribute. My mistake I did not check first before posting.
Jan 16 2020
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
https://github.com/dlang/dmd/pull/10728
Jan 16 2020
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 16.01.20 09:04, Walter Bright wrote:
 
 For functions, the line is:
 
    sc2.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | 
 STC.abstract_ | STC.deprecated_ | STC.override_ |
                 STC.TYPECTOR | STC.final_ | STC.tls |
STC.gshared | 
 STC.ref_ | STC.return_ | STC.property |
                 STC.nothrow_ | STC.pure_ | STC.safe |
STC.trusted | 
 STC.system);
 
 https://github.com/dlang/dmd/blob/master/src/dmd/semantic3.d#L316
 
 Interestingly,  nogc does flow through here.
This is just plain broken and cannot be explained as anything but as an oversight. It's the root cause of this issue: https://issues.dlang.org/show_bug.cgi?id=18439 Why should nogc functions not be able to use the GC within lambdas that are executed exclusively during CTFE?
Jan 16 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 16.01.20 09:35, Timon Gehr wrote:
 On 16.01.20 09:04, Walter Bright wrote:
 For functions, the line is:

    sc2.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | 
 STC.abstract_ | STC.deprecated_ | STC.override_ |
                 STC.TYPECTOR | STC.final_ | STC.tls |
STC.gshared | 
 STC.ref_ | STC.return_ | STC.property |
                 STC.nothrow_ | STC.pure_ | STC.safe |
STC.trusted | 
 STC.system);

 https://github.com/dlang/dmd/blob/master/src/dmd/semantic3.d#L316

 Interestingly,  nogc does flow through here.
This is just plain broken and cannot be explained as anything but as an oversight. It's the root cause of this issue: https://issues.dlang.org/show_bug.cgi?id=18439 Why should nogc functions not be able to use the GC within lambdas that are executed exclusively during CTFE?
Also, alarmingly, 'pure' the same issue even though it appears in that expression: int bar(){ return 2; } pure nogc: auto foo(){ enum x={ return bar(); }(); // error for no reason } pragma(msg, typeof(&foo)); I.e., the compiler contains additional logic for `pure` that makes it broken even though there is no reason to treat it any differently to, e.g., nothrow.
Jan 16 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 16 January 2020 at 08:47:01 UTC, Timon Gehr wrote:
 Also, alarmingly, 'pure' the same issue even though it appears 
 in that expression:
Since lambdas are inferred, the attr: should not apply to them anyway. That's my proposal - exempt anything that is inferred from the attr: things (you can still attach attributes directly to it to force the issue). There's no reason to force the issue with these; attr: is to kinda change the default and inference already is a more generally useful default.
Jan 16 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 16.01.20 13:51, Adam D. Ruppe wrote:
 On Thursday, 16 January 2020 at 08:47:01 UTC, Timon Gehr wrote:
 Also, alarmingly, 'pure' the same issue even though it appears in that 
 expression:
Since lambdas are inferred, the attr: should not apply to them anyway. That's my proposal - exempt anything that is inferred from the attr: things (you can still attach attributes directly to it to force the issue). There's no reason to force the issue with these; attr: is to kinda change the default and inference already is a more generally useful default.
Yes, I fully support that.
Jan 16 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Thursday, 16 January 2020 at 08:04:35 UTC, Walter Bright wrote:
 On 1/15/2020 7:26 AM, Arine wrote:
 I'm completely blown away, you don't even know that  safe 
 passes through to the next scope?
My mistake. What actually happens is here: sc2.stc &= STC.safeGroup; https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.d#L136 where the storage class passed from the outer scope to the struct/class scope is zeroed out except for safe/ trusted/ system. So safe "flows through" to the struct scope, while nothrow, pure, nogc, etc., do not.
So when you were proposing system: as a solution to the change to default of safe, you thought you had to add system to the top of every struct, and that's the solution you promoting as a best practice? Honestly I'd prefer rebuttal about my point regarding defaults. If the defaults aren't what you want them to be, the language forces you to pollute your code with `attributes:` because they don't flow into the next scope. If that's the only reason, and there's no other reason why it behaves this way. It'd be best to change it so that the user the option to choose what is best for them. If they feel it is best add it to every scope, that's their option to. But right now it's forced onto us.
Jan 16 2020
parent Jan =?UTF-8?B?SMO2bmln?= <hrominium gmail.com> writes:
On Thursday, 16 January 2020 at 20:19:24 UTC, Arine wrote:
 On Thursday, 16 January 2020 at 08:04:35 UTC, Walter Bright 
 wrote:
 On 1/15/2020 7:26 AM, Arine wrote:
 I'm completely blown away, you don't even know that  safe 
 passes through to the next scope?
My mistake. What actually happens is here: sc2.stc &= STC.safeGroup; https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.d#L136 where the storage class passed from the outer scope to the struct/class scope is zeroed out except for safe/ trusted/ system. So safe "flows through" to the struct scope, while nothrow, pure, nogc, etc., do not.
So when you were proposing system: as a solution to the change to default of safe, you thought you had to add system to the top of every struct, and that's the solution you promoting as a best practice? Honestly I'd prefer rebuttal about my point regarding defaults. If the defaults aren't what you want them to be, the language forces you to pollute your code with `attributes:` because they don't flow into the next scope. If that's the only reason, and there's no other reason why it behaves this way. It'd be best to change it so that the user the option to choose what is best for them. If they feel it is best add it to every scope, that's their option to. But right now it's forced onto us.
(I am in the safe and throw camp as default.) I really like Adam's ideas about the attributes: http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html That way we can easily get code, how we like to, without much pollution (i would not consider one line in a module a pollution), no matter what the defaults are. This DIP is just a little step, which might or might not go in any direction afterwards.
Jan 22 2020
prev sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 14 January 2020 at 23:04:02 UTC, Adam D. Ruppe wrote:
 On Tuesday, 14 January 2020 at 22:30:40 UTC, Walter Bright 
 wrote:
 Hence, when "nothrow" becomes the default
IF, not when. I support this DIP as a nice independent move, but I am going to fight you on the step of changing the default.
+1 it's a strange misguided idea in the absence of something better than exceptions. In my best passive-aggressive way, let me quote: "The basic answer is: Using exceptions for error handling makes your code simpler, cleaner, and less likely to miss errors." [C++] Why use exceptions? https://isocpp.org/wiki/faq/exceptions#why-exceptions "What do you do when an error occurs in a program? In many languages, error conditions are signaled by unusual return values like 1. Programmers often don't check for exceptional values because they may assume that errors "can't happen." On the other hand, adding error detection and recovery to what should be a straightforward flow of logic can complicate that logic to the point where the normal flow is completely obscured. An ostensibly simple task such as reading a file into memory might require about seven lines of code. Error checking and reporting expands this to 40 or more lines. Making normal operation the needle in your code haystack is undesirable." The Java programming language - Arnold, Gosling & Holmes -------------------->3-------------------- And we all know that, exceptions clean-up the normal path, in a way that no other alternative seeems to do. Isn't readability important? If one can understand why safe-by-default can be a moneymaker years from now, nothrow-by-default on the contrary would imo be a very costly mistake. I spent a lot of my life optimizing programs. If there is a way to make a program faster, people will find it eventually. Even if speed is important, safety is usually a lot more important (why get the wrong results fast?). I've come to the conclusion that "you only pay for whay you use" is really wrong, since you WILL pay anyway for the increased bugs, lessened readability etc. Speed shouldn't be optimized for as some kind of most desirable property. This is an "appeal-to-speed" logical fallacy, since in reality more bugs often mean less time to optimize; you might well end up slower in the end. See_also: "fast" C++ projects that don't move fast, and get destroyed by a Java competitor.
Jan 15 2020
next sibling parent reply Aliak <something something.com> writes:
On Wednesday, 15 January 2020 at 17:16:18 UTC, Guillaume Piolat 
wrote:
 On Tuesday, 14 January 2020 at 23:04:02 UTC, Adam D. Ruppe 
 wrote:
[...]
+1 it's a strange misguided idea in the absence of something better than exceptions. [...]
Speed is not the reason to have nothrow as default. It’s so that you are forced to be aware of functions that throw and then you either handle it or not. With the current status quo you get surprise exceptions which is less than ideal. Making nothrow as default does not remove your ability to use exceptions as error handling, it makes it more reliable.
Jan 15 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 15 January 2020 at 17:34:46 UTC, Aliak wrote:
 It’s so that you are forced to be aware of functions that throw 
 and then you either handle it or not.
Ironically, this was one of the reasons given for exceptions being used in the first place. And we have 25 years of history showing exceptions do a better job on reliability than the alternatives D currently offers. It is possible that other techniques could be added to D, and then maybe we can revisit this decision after they prove themselves in practice. But as it is now, exceptions (and I'm critical of certain details of D's exceptions; strings considered harmful lol) are the best we have and discouraging them is a step backwards.
Jan 15 2020
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 15, 2020 at 05:16:18PM +0000, Guillaume Piolat via Digitalmars-d
wrote:
 On Tuesday, 14 January 2020 at 23:04:02 UTC, Adam D. Ruppe wrote:
 On Tuesday, 14 January 2020 at 22:30:40 UTC, Walter Bright wrote:
 Hence, when "nothrow" becomes the default
IF, not when. I support this DIP as a nice independent move, but I am going to fight you on the step of changing the default.
+1 it's a strange misguided idea in the absence of something better than exceptions.
[...] As I already pointed out in another thread, I suspect that Walter's beef against exceptions is not really the exceptions themselves, but their *current implementation* in the form of mandatory stack frames and their associated setup, and stack unwinding which is unwieldy to implement and expensive at runtime to execute. Elsewhere in said other thread we've already come up with a potential alternative implementation that still allows you to throw errors -- just in a more lightweight form that doesn't require expensive stack frame setup and unwieldy stack unwinding code. At the user code level, it could even retain exactly the same syntax, and work pretty much the same as before, just the actual implementation will follow a different scheme. T -- Too many people have open minds but closed eyes.
Jan 15 2020
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 15 January 2020 at 18:20:00 UTC, H. S. Teoh wrote:
 As I already pointed out in another thread, I suspect that 
 Walter's beef against exceptions is not really the exceptions 
 themselves, but their *current implementation* in the form of 
 mandatory stack frames and their associated setup, and stack 
 unwinding which is unwieldy to implement and expensive at 
 runtime to execute.
If that was the case then he would have suggested to fix the implementation, not the default... You certainly can fix exception performance in the implementation with inter-procedural analysis.
 Elsewhere in said other thread we've already come up with a 
 potential alternative implementation that still allows you to 
 throw errors -- just in a more lightweight form that doesn't 
 require expensive stack frame setup and unwieldy stack 
 unwinding code.  At the user code level, it could even retain 
 exactly the same syntax, and work pretty much the same as 
 before, just the actual implementation will follow a different 
 scheme.
D needs to use the same unwind code as C++ if it is going to integrate well with C++. If C++ interop is the goal then D has to focus on aligning its semantics with C++... obviously.
Jan 15 2020
parent Mike Parker <aldacron gmail.com> writes:
On Wednesday, 15 January 2020 at 19:25:23 UTC, Ola Fosheim 
Grøstad wrote:
 On Wednesday, 15 January 2020 at 18:20:00 UTC, H. S. Teoh wrote:
 As I already pointed out in another thread, I suspect that 
 Walter's beef against exceptions is not really the exceptions 
 themselves, but their *current implementation* in the form of 
 mandatory stack frames and their associated setup, and stack 
 unwinding which is unwieldy to implement and expensive at 
 runtime to execute.
If that was the case then he would have suggested to fix the implementation, not the default... You certainly can fix exception performance in the implementation with inter-procedural analysis.
 Elsewhere in said other thread we've already come up with a 
 potential alternative implementation that still allows you to 
 throw errors -- just in a more lightweight form that doesn't 
 require expensive stack frame setup and unwieldy stack 
 unwinding code.  At the user code level, it could even retain 
 exactly the same syntax, and work pretty much the same as 
 before, just the actual implementation will follow a different 
 scheme.
D needs to use the same unwind code as C++ if it is going to integrate well with C++. If C++ interop is the goal then D has to focus on aligning its semantics with C++... obviously.
Please everyone, let’s keep this thread focused on reviewing this DIP. There is another thread discussing default nothrow. Any further off topic posts in this thread will be deleted. Thanks!
Jan 15 2020
prev sibling parent Dukc <ajieskola gmail.com> writes:
On Tuesday, 14 January 2020 at 22:30:40 UTC, Walter Bright wrote:
 On 1/14/2020 8:44 AM, Dukc wrote:
 This would be a step forward, of course. But would not it be 
 better to kill the one-way attribute problem in one go 
 -meaning, making an antiattribute for `pure` and ` nogc` too?
Because for the anti-nothrow we already have a trivial solution staring us in the face, we just have to pick it up. I have no explanation for not seeing the obvious before.
Good.
 In addition, I suggest that there should be a way to use 
 [`pure:`/`nothrow:`/` nogc:`/` safe:`/their antiattributes] so 
 that they only apply when attributes are not inferred - not 
 for templated functions. This would also remove a big obstacle 
 from front of DIP1028, as one could just mark the whole module 
 ` system` with one statement without killing template ` safe` 
 or ` live` inference.
It turns out that there's another "attribute" under the covers - the default. Only when an attribute is the default does inference come into play. Hence, when "nothrow" becomes the default, there will be actually three states - throw, nothrow, and default.
Yes, correct. But what is worth mentioning ew are actually discussing about FOUR attributes: `throw`, `nothrow`, present default and the `nothrow` default. If the latest someday becomes the default, we suddently lose our ability to use the current default. What I was saying that it would be worthwhile to make all those "default" attributes accessible so that is the scope already is, say `throw`, you can change it to the (current or likely-future) default behaviour. This will make the transition to nothrow-default much easier, as people can set their whole modules to the old default to keep legacy code running, or set the whole module to the new default so that the checks are done even before the transition.
 It works out rather nicely. It's in play for 
 safe/trusted/system already, and has been since the beginning.
Setting the default this way should also be possible for ` system/` safe/` live` too (in theory, for ` trusted` too, but why in the world would anyone want to default to it?). And for other inferred attributes, if they get their antiattributes.
Jan 15 2020
prev sibling next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:
 #DIP1029
 #throw
First of all thanks for adding the section with a grammar diff and adding it to FunctionAttribute. I forgot to mention during draft review it should probably be added to StorageClass as well: https://dlang.org/spec/grammar.html#StorageClass Otherwise it can't appear in an AutoFunctionDeclaration unlike nothrow. ``` void main() { nothrow foo() {} // currently allowed throw foo() {} // not allowed after this DIP because `throw` is no `StorageClass` } ``` However, adding it to StorageClass adds an ambiguity: ``` void foo()() { nothrow bar(); // allowed according to grammar spec throw bar(); // throw statement or function declaration? } ``` Now it should be noted that dmd doesn't actually parse that. I opened an issue for that: https://issues.dlang.org/show_bug.cgi?id=20504 That could make the problem away in this case, but I think the DIP should consider possible ambiguities like that that might be introduced. Further feedback: - I still think that other attributes should be considered for this DIP. As I mentioned during draft review:
 pure isn't fortunate enough to have an opposite keyword for it. 
 If we end up going with e.g. pure(false) or !pure, then you'll 
 end up with either inconsistently not allowing nothrow(false) 
 or !nothrow, or multiple ways to specify a throw function.
It would be annoying to users if soon after the introduction of `throw` as a function attribute it would be phased out because a new consistent mechanism is introduced for all function attributes. On the other hand, adding an option to negate the nothrow attribute in the short term is welcome, and it can still be kept around with little harm even if it gets superceded. - I still think it should be stated how the new attribute interacts with __traits(getFunctionAttributes): ``` void t0() nothrow; // tuple("nothrow", " system") void t1() throw; // tuple("throw", " system") void t2(); // tuple(" system") or tuple("throw", " system")? ```
Jan 14 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/14/2020 1:22 PM, Dennis wrote:
 On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:
 #DIP1029
 #throw
First of all thanks for adding the section with a grammar diff and adding it to FunctionAttribute. I forgot to mention during draft review it should probably be added to StorageClass as well: https://dlang.org/spec/grammar.html#StorageClass Otherwise it can't appear in an AutoFunctionDeclaration unlike nothrow. ``` void main() {     nothrow foo() {} // currently allowed     throw foo() {} // not allowed after this DIP because `throw` is no `StorageClass` } ``` However, adding it to StorageClass adds an ambiguity: ``` void foo()() {     nothrow bar(); // allowed according to grammar spec     throw bar(); // throw statement or function declaration? } ```
I'm pretty sure the parser can take care of that with lookahead.
Feb 07 2020
parent Dennis <dkorpel gmail.com> writes:
On Friday, 7 February 2020 at 08:56:06 UTC, Walter Bright wrote:
 ```
 void foo()() {
      nothrow bar(); // allowed according to grammar spec
      throw bar(); // throw statement or function declaration?
 }
 ```
I'm pretty sure the parser can take care of that with lookahead.
But which one is it? I think declarations usually have priority (e.g. `A * b;` is always a declaration with pointer type instead of multiplication) but arguably parsing it as a throw statement makes more sense here.
Feb 07 2020
prev sibling next sibling parent reply user1234 <user1234 1234.de> writes:
On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1029, "Add throw as Function Attribute":

 https://github.com/dlang/DIPs/blob/8c48c98a0495f73db9a2d5c4aef502b9febe9673/DIPs/DIP1029.md

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on January 28, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment.

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.

 #DIP1029
 #throw
Impossible without cleaning a bit the attributes before. instead of adding a new keyword we should make all the function attributes ' ' attributes, and deprecate 'nothrow' as a keyword and encourage nothrow instead. This DIP encourages the bizarre situation where function attributes can be ' ' attribs or keywords.
Jan 22 2020
parent user1234 <user1234 1234.de> writes:
On Wednesday, 22 January 2020 at 22:47:51 UTC, user1234 wrote:
 On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:
 [...]
Impossible without cleaning a bit the attributes before. instead of adding a new keyword we should make all the function attributes ' ' attributes, and deprecate 'nothrow' as a keyword and encourage nothrow instead. This DIP encourages the bizarre situation where function attributes can be ' ' attribs or keywords.
in my opinion something like void foo() safe nogc pure nothrow {} should become void foo() safe nogc pure nothrow {} so "throw" as a function attribute is just a big no. This will create a debt in case attribs syntax got normalized one day.
Jan 22 2020
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, January 14, 2020 3:44:17 AM MST Mike Parker via Digitalmars-d 
wrote:
 This is the feedback thread for the first round of Community
 Review for DIP 1029, "Add throw as Function Attribute":

 https://github.com/dlang/DIPs/blob/8c48c98a0495f73db9a2d5c4aef502b9febe967
 3/DIPs/DIP1029.md

 All review-related feedback on and discussion of the DIP should
 occur in this thread. The review period will end at 11:59 PM ET
 on January 28, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, the
 DIP will be scheduled for another round of Community Review.
 Otherwise, it will be queued for the Final Review and Formal
 Assessment.

 Anyone intending to post feedback in this thread is expected to
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.

 #DIP1029
 #throw
I do think that we should consider adding something like pure(true) and pure(false) - and possibly something like pure(default) or pure(inferred) - for attributes where that makes sense, because it would work better with metaprogramming (at least if an expression can be provided instead of only boolean literals). And if we went with something like that, arguably it doesn't make sense to add throw in addition to nothrow, since throw could just be nothrow(false). However, the double negative is arguably undesirable, and even if a boolean solution would be desirable, this DIP is an improvement over the current sitution and does not make it so that we can't add a more flexible solution for negating function attributes in general later. - Jonathan M Davis
Jan 22 2020
parent Zoadian <no no.no> writes:
On Thursday, 23 January 2020 at 05:06:21 UTC, Jonathan M Davis 
wrote:
 I do think that we should consider adding something like 
 pure(true) and pure(false) - and possibly something like 
 pure(default) or pure(inferred) - for attributes where that 
 makes sense, because it would work better with metaprogramming 
 (at least if an expression can be provided instead of only 
 boolean literals). And if we went with something like that, 
 arguably it doesn't make sense to add throw in addition to 
 nothrow, since throw could just be nothrow(false). However, the 
 double negative is arguably undesirable, and even if a boolean 
 solution would be desirable, this DIP is an improvement over 
 the current sitution and does not make it so that we can't add 
 a more flexible solution for negating function attributes in 
 general later.

 - Jonathan M Davis
I constantly need to turn on/off safe and nothrow based on version(WebAssembly). so i'm all for adding a simple way to toggle attributes. my proposal would be something like this: ``` struct pure { private: enum P { Yes,No,Default,Inferred, } W _pure; this(P p) { _pure = p; } public: this(bool b = true) { _pure = b ? P.Yes : P.No; } enum default = pure(P.Default); enum inferred = pure(P.Inferred); } alias impure(bool b = true) = pure!(!b); ``` so we can have: ``` pure impure pure!false impure!false pure.default pure.inferred impure.default impure.inferred ```
Jan 23 2020
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 January 2020 at 10:44:17 UTC, Mike Parker wrote:

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on January 28, or when I make a post declaring it complete.
This review round has finished. Please save further feedback for the next review round.
Jan 30 2020