digitalmars.D - Discussion Thread: DIP 1029--Add throw as Function Attribute--Final
- Mike Parker (21/21) Apr 17 2020 This is the discussion thread for the Final Review of DIP 1029,
- Mike Parker (3/8) Apr 17 2020 The feedback thread is here:
- James Lu (5/14) Apr 17 2020 If I understand correctly, nothrow functions may throw Errors,
- FeepingCreature (3/18) Apr 17 2020 Catching `Error` is always undefined. That's why nothrow may
- Adam D. Ruppe (4/4) Apr 17 2020 No objection to it as written, but there have been zero changes
- Steven Schveighoffer (5/8) Apr 17 2020 There is a difference between ignored and advice considered and not take...
- Adam D. Ruppe (11/13) Apr 17 2020 But even if it was all simply not taken, I'm OK with a response
- Steven Schveighoffer (15/27) Apr 17 2020 I think it's just part of the red tape we created for ourselves!
- Mike Parker (3/18) Apr 17 2020 Please start a new thread if you want to discuss the DIP process
- James Lu (6/9) Apr 17 2020 Have the ideas below been discussed?
- Jacob Carlborg (56/60) Apr 18 2020 I would like to see the "throw" keyword being used as an attribute to
- Paul Backus (8/20) Apr 18 2020 The big downside of this compared to exceptions is that you can
- Sebastiaan Koppe (2/16) Apr 18 2020 That part was only the lowered code.
- NaN (15/41) Apr 18 2020 You could have the caller pass an alternate return address to the
- Panke (4/18) May 05 2020 A paper describing the idea.
- Tove (9/15) May 05 2020 On Tuesday, 5 May 2020 at 14:39:24 UTC, Petar Kirov [ZombineDev]
- Paul Backus (5/11) May 05 2020 It seems more confusing to me to use template syntax for
- Petar Kirov [ZombineDev] (14/26) May 05 2020 If we turn the existing function attributes into compiler
- Tove (5/17) May 05 2020 It's not a function either and extern!C would be fine with me.
This is the discussion thread for the Final Review of DIP 1029, "Add throw as Function Attribute": https://github.com/dlang/DIPs/blob/9db80ddadcf5a220958ddcfec14b9c71cdb43d1c/DIPs/DIP1029.md The review period will end at 11:59 PM ET on May 1, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. Here in the discussion thread, you are free to discuss anything and everything related to the DIP. Express your support or opposition, debate alternatives, argue the merits, etc. However, if you have any specific feedback on how to improve the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I write at the end of this review round. I will post a link to that thread immediately following this post. Just be sure to read and understand the Reviewer Guidelines before posting there: https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md And my blog post on the difference between the Discussion and Feedback threads: https://dlang.org/blog/2020/01/26/dip-reviews-discussion-vs-feedback/ Please stay on topic here. I will delete posts that are completely off-topic.
Apr 17 2020
On Friday, 17 April 2020 at 11:28:05 UTC, Mike Parker wrote:However, if you have any specific feedback on how to improve the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I write at the end of this review round. I will post a link to that thread immediately following this post.The feedback thread is here: https://forum.dlang.org/post/qhtqeavhyzjfamhgcjjl forum.dlang.org
Apr 17 2020
On Friday, 17 April 2020 at 11:31:21 UTC, Mike Parker wrote:On Friday, 17 April 2020 at 11:28:05 UTC, Mike Parker wrote:If I understand correctly, nothrow functions may throw Errors, but throw functions may throw Errors and Exceptions? If a nothrow function throws an Error, may the outer function catch it in a well-defined manner?However, if you have any specific feedback on how to improve the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I write at the end of this review round. I will post a link to that thread immediately following this post.The feedback thread is here: https://forum.dlang.org/post/qhtqeavhyzjfamhgcjjl forum.dlang.org
Apr 17 2020
On Friday, 17 April 2020 at 12:58:56 UTC, James Lu wrote:On Friday, 17 April 2020 at 11:31:21 UTC, Mike Parker wrote:Catching `Error` is always undefined. That's why nothrow may throw them in the first place.On Friday, 17 April 2020 at 11:28:05 UTC, Mike Parker wrote:If a nothrow function throws an Error, may the outer function catch it in a well-defined manner?However, if you have any specific feedback on how to improve the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I write at the end of this review round. I will post a link to that thread immediately following this post.The feedback thread is here: https://forum.dlang.org/post/qhtqeavhyzjfamhgcjjl forum.dlang.org
Apr 17 2020
No objection to it as written, but there have been zero changes to the text between this review and the last, except adding the summary of the (apparently ignored by the author) previous round. What's the point of going over an identical document again?
Apr 17 2020
On 4/17/20 8:52 AM, Adam D. Ruppe wrote:No objection to it as written, but there have been zero changes to the text between this review and the last, except adding the summary of the (apparently ignored by the author) previous round.There is a difference between ignored and advice considered and not taken. Though I think in at least one case (I posted on the review thread) something important was missed. -Steve
Apr 17 2020
On Friday, 17 April 2020 at 14:39:26 UTC, Steven Schveighoffer wrote:There is a difference between ignored and advice considered and not taken.But even if it was all simply not taken, I'm OK with a response "I don't care, take it or leave it" (though two of the bullets don't even have that, just nothing)... but why are we wasting our time doing a discussion thread to review the same document again? Again, the text is *identical* to the last review, so what does the DIP manager expect from us this time that would be any different than last time? We complain that newsgroup discussions go in circles. Well, this is literally called a "round" lol, but it just seems ridiculous.
Apr 17 2020
On 4/17/20 1:01 PM, Adam D. Ruppe wrote:On Friday, 17 April 2020 at 14:39:26 UTC, Steven Schveighoffer wrote:I think it's just part of the red tape we created for ourselves! But it also gives the chance to reiterate the importance of advice not taken, or rephrase the argument in a way that is more convincing.There is a difference between ignored and advice considered and not taken.But even if it was all simply not taken, I'm OK with a response "I don't care, take it or leave it" (though two of the bullets don't even have that, just nothing)... but why are we wasting our time doing a discussion thread to review the same document again?Again, the text is *identical* to the last review, so what does the DIP manager expect from us this time that would be any different than last time?This is how things like this work. There are responses to the points made, and Walter didn't make any changes based on that. It would also be possible to amend the DIP process such that if no changes are made before final review, it goes straight to formal assessment. Might not be a bad idea. It would save time too. The document is here: https://github.com/dlang/DIPs/blob/master/docs/process-reviews.md#final-review It says:The purpose of the Final Review is to provide one final opportunity to examine the revisions made in response to the Community Review rounds and further refine the DIP as necessary.So, just amend that to say "If no revisions were made in response to the Community reviews, the DIP manager may forego the Final Review stage". -Steve
Apr 17 2020
On Friday, 17 April 2020 at 17:01:31 UTC, Adam D. Ruppe wrote:On Friday, 17 April 2020 at 14:39:26 UTC, Steven Schveighoffer wrote:Please start a new thread if you want to discuss the DIP process and let's keep this one focused on the DIP. Thanks!There is a difference between ignored and advice considered and not taken.But even if it was all simply not taken, I'm OK with a response "I don't care, take it or leave it" (though two of the bullets don't even have that, just nothing)... but why are we wasting our time doing a discussion thread to review the same document again? Again, the text is *identical* to the last review, so what does the DIP manager expect from us this time that would be any different than last time? We complain that newsgroup discussions go in circles. Well, this is literally called a "round" lol, but it just seems ridiculous.
Apr 17 2020
On Friday, 17 April 2020 at 11:28:05 UTC, Mike Parker wrote:This is the discussion thread for the Final Review of DIP 1029, "Add throw as Function Attribute": [...]Have the ideas below been discussed? - an attribute "exception_aware": does the function body use catch or throw? - using "!!" to designate attribute remove: !!pure, !!nothrow. It is visible, it is explicit.
Apr 17 2020
On 2020-04-17 13:28, Mike Parker wrote:This is the discussion thread for the Final Review of DIP 1029, "Add throw as Function Attribute": https://github.com/dlang/DIPs/blob/9db80ddadcf5a220958ddcfec14b9c71cdb4 d1c/DIPs/DIP1029.mdI would like to see the "throw" keyword being used as an attribute to implement something like "Zero-overhead deterministic exceptions: Throwing values" [1]. I imagine it looking something like this: enum CopyError { permissionDenied } void copy(string src, string dest) throw(CopyError) { throw CopyError.permissionDenied; } void main() { try copy("foo", "bar"); catch (CopyError e) writeln(e); } Which would be lowered to something like the equivalent of the following code: struct Result(Value, Error) { bool isValue; union { Value value; Error error; } this(Value value) { this.value = value; isValue = true; } this(Error errro) { this.error = error; isValue = true; } } Result!(void, CopyError) copy(string src, string dest) { return Result!(void, CopyError)(CopyError.permissionDenied); } void main() { auto result = copy("foo", "bar"); if (!result.isValue) goto L1; L1: writeln(result.error); } [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf -- /Jacob Carlborg
Apr 18 2020
On Saturday, 18 April 2020 at 12:03:46 UTC, Jacob Carlborg wrote:Result!(void, CopyError) copy(string src, string dest) { return Result!(void, CopyError)(CopyError.permissionDenied); } void main() { auto result = copy("foo", "bar"); if (!result.isValue) goto L1; L1: writeln(result.error); }The big downside of this compared to exceptions is that you can forget to check the return value of `copy`, whereas exceptions cannot be ignored. respectively to force the programmer to check the return value. Without something equivalent in D, using algebraic data types for error handling is not really a viable approach.
Apr 18 2020
On Saturday, 18 April 2020 at 14:02:46 UTC, Paul Backus wrote:On Saturday, 18 April 2020 at 12:03:46 UTC, Jacob Carlborg wrote:That part was only the lowered code.void main() { auto result = copy("foo", "bar"); if (!result.isValue) goto L1; L1: writeln(result.error); }The big downside of this compared to exceptions is that you can forget to check the return value of `copy`, whereas exceptions cannot be ignored.
Apr 18 2020
On Saturday, 18 April 2020 at 12:03:46 UTC, Jacob Carlborg wrote:On 2020-04-17 13:28, Mike Parker wrote:You could have the caller pass an alternate return address to the callee. So... void copy(string src, string dest, void* err) { if (somethingbad) { EAX = errorcode; RET (to) err; } *** } void main() { auto result = copy("foo", "bar", &L1); return; L1: writeln("Oh noes!"); } *** So all the callee has to do is poke the alternate return address into the stack and RET as normal. (On x86 at least).This is the discussion thread for the Final Review of DIP 1029, "Add throw as Function Attribute": https://github.com/dlang/DIPs/blob/9db80ddadcf5a220958ddcfec14b9c71cdb43d1c/DIPs/DIP1029.mdI would like to see the "throw" keyword being used as an attribute to implement something like "Zero-overhead deterministic exceptions: Throwing values" [1]. I imagine it looking something like this: enum CopyError { permissionDenied } void copy(string src, string dest) throw(CopyError) { throw CopyError.permissionDenied; } void main() { try copy("foo", "bar"); catch (CopyError e) writeln(e); } Which would be lowered to something like the equivalent of the following code:
Apr 18 2020
On Saturday, 18 April 2020 at 16:28:59 UTC, NaN wrote:You could have the caller pass an alternate return address to the callee. So... void copy(string src, string dest, void* err) { if (somethingbad) { EAX = errorcode; RET (to) err; } *** } void main() { auto result = copy("foo", "bar", &L1); return; L1: writeln("Oh noes!"); } *** So all the callee has to do is poke the alternate return address into the stack and RET as normal. (On x86 at least).A paper describing the idea. https://dl.acm.org/doi/pdf/10.1145/1016848.1016864 I thought there was a more practical one, but only found this.
May 05 2020
On Friday, 17 April 2020 at 11:28:05 UTC, Mike Parker wrote:This is the discussion thread for the Final Review of DIP 1029, "Add throw as Function Attribute":On Tuesday, 5 May 2020 at 14:39:24 UTC, Petar Kirov [ZombineDev] wrote:Otherwise, I'd say that the best solution, which I think Andrei agreed with [1] is `attribute(true)` and `attribute(false)` or more generally: `attribute(boolExpr)`. [1]: https://forum.dlang.org/post/mknspb$1dgl$1 digitalmars.comGood digging! I agree with you and Andrei, but using template syntax would be an additional improvement, it's not about saving one char, but avoiding matching () in the common case. attribute!true attribute!false attribute!(boolExpr)
May 05 2020
On Tuesday, 5 May 2020 at 15:30:38 UTC, Tove wrote:Good digging! I agree with you and Andrei, but using template syntax would be an additional improvement, it's not about saving one char, but avoiding matching () in the common case. attribute!true attribute!false attribute!(boolExpr)It seems more confusing to me to use template syntax for something that isn't a template. We already use parentheses for stuff like `extern(C)`. Using them for function attributes is a natural extension of that.
May 05 2020
On Tuesday, 5 May 2020 at 15:55:30 UTC, Paul Backus wrote:On Tuesday, 5 May 2020 at 15:30:38 UTC, Tove wrote:If we turn the existing function attributes into compiler recognized UDAs, the template version is one char shorter: version (A) { struct nogc { bool enabled; } void foo() (nogc(true)) { } } else version (B) { struct nogc(bool enabled) { } void foo() (nogc!true) { } } ;)Good digging! I agree with you and Andrei, but using template syntax would be an additional improvement, it's not about saving one char, but avoiding matching () in the common case. attribute!true attribute!false attribute!(boolExpr)It seems more confusing to me to use template syntax for something that isn't a template. We already use parentheses for stuff like `extern(C)`. Using them for function attributes is a natural extension of that.
May 05 2020
On Tuesday, 5 May 2020 at 15:55:30 UTC, Paul Backus wrote:On Tuesday, 5 May 2020 at 15:30:38 UTC, Tove wrote:It's not a function either and extern!C would be fine with me. IIRC `extern(C)` existed long before the single argument template syntax. It may appear a minor feature, but I miss it a lot when forced to use other languages.Good digging! I agree with you and Andrei, but using template syntax would be an additional improvement, it's not about saving one char, but avoiding matching () in the common case. attribute!true attribute!false attribute!(boolExpr)It seems more confusing to me to use template syntax for something that isn't a template. We already use parentheses for stuff like `extern(C)`. Using them for function attributes is a natural extension of that.
May 05 2020