digitalmars.D - why scope(success)?
- Ben Hinkle (16/16) May 09 2006 I hope this doesn't come of as a flame, but I'm wondering if anyone is u...
- BCS (7/27) May 09 2006 int fn(int i)
- Sean Kelly (6/8) May 09 2006 How about a DB transaction you only want to commit if there are no
- Serg Kovrov (12/48) May 10 2006 In this particular case I don't want rollback on returning false, just
- Sean Kelly (8/14) May 10 2006 True. But if the function is complex and has multiple return points,
- Ben Hinkle (3/11) May 10 2006 Are you using them in practice? Is there a link I can follow to see the
- Sean Kelly (8/18) May 10 2006 scope(success)? Not yet. I've only used scope(failure) and scope(exit)...
- Walter Bright (14/20) May 12 2006 Exceptions work well as long as there is only one operation that needs
- Mike Capp (18/27) May 13 2006 Off the top of my head...
- Walter Bright (12/36) May 13 2006 This doesn't work because when the scope is done, no matter how it ends,...
- Walter Bright (5/7) May 13 2006 Eh, I misinterpreted Mike's code. Sorry.
- Mike Capp (5/10) May 14 2006 Oops. I stand corrected.
- Sean Kelly (8/28) May 13 2006 It's probably a matter of implementation, but std::uncaught_exception
- pragma (6/22) May 09 2006 I'm considering using it for some code generation technqiues (parsers mo...
- Ben Hinkle (2/10) May 09 2006 Ok. That sounds like an interesting application. If it comes on line
- pragma (9/22) May 09 2006 Sure. Although the use of scope() here is really just theoretical at th...
- Regan Heath (25/43) May 09 2006 Maybe... self documenting functions, listing all return values at the to...
- Ben Hinkle (5/28) May 09 2006 I believe writing "scope(success) foo;" followed by the end of the curre...
- Regan Heath (14/29) May 09 2006 You're right. For some reason I got it in my head that scope(success)
- Chris Nicholson-Sauls (9/50) May 10 2006 Evidence from testing is that a.foo() is executed at point A. Which I t...
- James Dunne (11/32) May 10 2006 if statements do not create a scope without { }, therefore it should be
- Sean Kelly (3/6) May 10 2006 They don't?
- Ben Hinkle (7/13) May 10 2006 They do. The code
- James Dunne (15/36) May 11 2006 Then the implementation according to D's language specs is incorrect.
- Stewart Gordon (15/21) May 11 2006 I think you're meant to use a bit of common sense here. What sense does...
- Ben Hinkle (8/21) May 11 2006 You're probably right. I had tried dmc and cl and they both complained a...
- Sean Kelly (7/29) May 11 2006 What about this:
- James Dunne (15/57) May 11 2006 Straight from the docs:
- Daniel Keep (18/23) May 12 2006 You just reminded me of a feature of a language called Nemerle (which is
- Chris Miller (11/23) May 10 2006 This gives me an idea, how about if there was scope(none) that is just
- Sean Kelly (7/19) May 10 2006 It's a nasty hack, but:
- Derek Parnell (6/22) May 10 2006 And I guess this is just as nasty ...
- Sean Kelly (5/29) May 10 2006 Preferable so long as the state of a is maintained until scope exit.
- Regan Heath (10/36) May 10 2006 Yeah. It's a pity though. What about:
- Ben Hinkle (4/24) May 10 2006 In Cx I was going to make that illegal - much like in C++ it's illegal t...
- Stewart Gordon (20/27) May 11 2006 I'm not sure about this. Of course, it would need to be illegal to
- Daniel Keep (28/48) May 10 2006 I've been writing an OO binding to the cairo 2D drawing API, and
- Walter Bright (4/12) May 12 2006 Right. It eliminates the all-too-common bug of adding an extra return
- Carlos (5/25) May 11 2006 Hey Ben glad to see you posting again :). tinycx looks cool am trying
- Walter Bright (32/48) May 12 2006 The scope(success) will execute even if the scope is exited via a
I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); } -Ben
May 09 2006
Ben Hinkle wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); } -Benint fn(int i) { scope(success) printf("Good\n"); scope(failure) printf("Bad\n"); /* big huge logic block with a bazillion returns and throws +/ }
May 09 2006
Ben Hinkle wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it.How about a DB transaction you only want to commit if there are no errors generating data. You might want something like this: scope(success) tran.commit(); scope(failure) tran.rollback(); Sean
May 09 2006
I used to manage it with exceptions, and more or less happy with it:deleteNode(node_id) { node = getNode(node_id); if (!node || !db.hasSQLFeature(SQL_TRANSACTIONS)) { return false; } db.beginTransaction(); try { ... lots of stuf that may throw, or maybe throw something right here... ... } catch (Exception e) { db.rollbackTransaction(); return false; } db.commitTransaction(); return true; }In this particular case I don't want rollback on returning false, just if a db operation failed. And exceptions handle that rather well. My point is, if case is a bit more complicated then a 'hello world' example, there most likely will be different error conditions, and they meant be handled differently. Exceptions are convenient way to do it. IMHO 'on scope exit' approach is not much different from 'one return at end of function' with condition flag(s). And it is kind of obscure code for me - it can be anywhere in function, maybe even may times, etc... It's hard to maintain (just like goto's), and as so, it's no use for me at this point. Sean Kelly wrote:Ben Hinkle wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it.How about a DB transaction you only want to commit if there are no errors generating data. You might want something like this: scope(success) tran.commit(); scope(failure) tran.rollback(); Sean
May 10 2006
Serg Kovrov wrote:IMHO 'on scope exit' approach is not much different from 'one return at end of function' with condition flag(s).True. But if the function is complex and has multiple return points, scope(success) is easier to maintain.And it is kind of obscure code for me - it can be anywhere in function, maybe even may times, etc... It's hard to maintain (just like goto's), and as so, it's no use for me at this point.It's a matter of opinion, I suppose. I find scope declarations more visible and more meaningful than the alternatives. And I like that I can place them next to the declarations of data they're meant to affect, thus making the code more meaningful. Sean
May 10 2006
Are you using them in practice? Is there a link I can follow to see the code? TIAAnd it is kind of obscure code for me - it can be anywhere in function, maybe even may times, etc... It's hard to maintain (just like goto's), and as so, it's no use for me at this point.It's a matter of opinion, I suppose. I find scope declarations more visible and more meaningful than the alternatives. And I like that I can place them next to the declarations of data they're meant to affect, thus making the code more meaningful. Sean
May 10 2006
Ben Hinkle wrote:scope(success)? Not yet. I've only used scope(failure) and scope(exit) so far: http://svn.dsource.org/projects/ares/trunk/src/ares/std/array.d http://svn.dsource.org/projects/ares/trunk/src/ares/std/thread.d I do think the use of scope(success) is fairly limited--the DB example is one of the I can think of--but it's a nice option to have. SeanAre you using them in practice? Is there a link I can follow to see the code?And it is kind of obscure code for me - it can be anywhere in function, maybe even may times, etc... It's hard to maintain (just like goto's), and as so, it's no use for me at this point.It's a matter of opinion, I suppose. I find scope declarations more visible and more meaningful than the alternatives. And I like that I can place them next to the declarations of data they're meant to affect, thus making the code more meaningful.
May 10 2006
Serg Kovrov wrote:In this particular case I don't want rollback on returning false, just if a db operation failed. And exceptions handle that rather well. My point is, if case is a bit more complicated then a 'hello world' example, there most likely will be different error conditions, and they meant be handled differently. Exceptions are convenient way to do it.Exceptions work well as long as there is only one operation that needs to be rolled back. As soon as you have two or more operations that happen sequentially, and either both must succeed or neither, that the traditional exception mechanism starts coming unglued. For example, if I have operations A(), B(), and C(), and A.rollback(), B.rollback() and C.rollback: A(); scope(failure) A.rollback(); B(); scope(failure) B.rollback(); C(); scope(failure) C.rollback(); Just for fun, try to do that with either C++ exceptions or Java try-finally.
May 12 2006
In article <e42jr6$2u07$1 digitaldaemon.com>, Walter Bright says...For example, if I have operations A(), B(), and C(), and A.rollback(), B.rollback() and C.rollback: A(); scope(failure) A.rollback(); B(); scope(failure) B.rollback(); C(); scope(failure) C.rollback(); Just for fun, try to do that with either C++ exceptions or Java try-finally.Off the top of my head... struct A // ditto for B and C { A() { doA(); } ~A() { if (std::uncaught_exception()) { rollbackA(); } } }; A a; B b; C c; I'm sure there are drawbacks; there always are. It's horses for courses. If the operations are common ones, the C++ approach wins out IMHO because you don't have to remember the scope statement (which is still a "wrong by default" design). If the operation is an ad-hoc one and you have to write the wrapper class yourself, the D approach is much cleaner since it keeps everything together and clarifies the intent. (Just look how popular std::for_each isn't.) cheers Mike
May 13 2006
Mike Capp wrote:In article <e42jr6$2u07$1 digitaldaemon.com>, Walter Bright says...This doesn't work because when the scope is done, no matter how it ends, A, B and C are *all* rolled back. The idea is that if the scope exits normally, A, B and C are *not* rolled back. The starting point for C++ would be: A* a = new A(); B* b = new B(); C* c = new C(); I need all three to succeed or none. Think of something like a database transactions, where 3 different places in the database have to be updated as one operation. You can't leave it as 1 done, or 2 done. It has to be all 3, or none of them.For example, if I have operations A(), B(), and C(), and A.rollback(), B.rollback() and C.rollback: A(); scope(failure) A.rollback(); B(); scope(failure) B.rollback(); C(); scope(failure) C.rollback(); Just for fun, try to do that with either C++ exceptions or Java try-finally.Off the top of my head... struct A // ditto for B and C { A() { doA(); } ~A() { if (std::uncaught_exception()) { rollbackA(); } } }; A a; B b; C c;
May 13 2006
Walter Bright wrote:This doesn't work because when the scope is done, no matter how it ends, A, B and C are *all* rolled back.Eh, I misinterpreted Mike's code. Sorry. But the uncaught_exception doesn't do the job. It only gets invoked if some exception is uncaught anywhere on the call stack, not if it is just uncaught before the destructors are called.
May 13 2006
In article <e45cvg$cib$2 digitaldaemon.com>, Walter Bright says...Walter Bright wrote: Eh, I misinterpreted Mike's code. Sorry.Quite all right. I misinterpret my code all the time.But the uncaught_exception doesn't do the job. It only gets invoked if some exception is uncaught anywhere on the call stack, not if it is just uncaught before the destructors are called.Oops. I stand corrected. cheers Mike
May 14 2006
Mike Capp wrote:In article <e42jr6$2u07$1 digitaldaemon.com>, Walter Bright says...It's probably a matter of implementation, but std::uncaught_exception isn't terribly useful in C++. The most obvious reason being that it acts globally rather than specific to the calling thread. I'm also not sure I like that the dtor would change behavior based on whether an exception is in flight. This results in unexpected behavior, which is never a good thing. SeanFor example, if I have operations A(), B(), and C(), and A.rollback(), B.rollback() and C.rollback: A(); scope(failure) A.rollback(); B(); scope(failure) B.rollback(); C(); scope(failure) C.rollback(); Just for fun, try to do that with either C++ exceptions or Java try-finally.Off the top of my head... struct A // ditto for B and C { A() { doA(); } ~A() { if (std::uncaught_exception()) { rollbackA(); } } };
May 13 2006
In article <e3qpsj$igc$1 digitaldaemon.com>, Ben Hinkle says...I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); } -BenI'm considering using it for some code generation technqiues (parsers mostly). Being able to declare what happens at the tail-end of a scope *first*, rather than last, means that you have to maintain less state (across nested scopes) in your code generator. - EricAnderton at yahoo
May 09 2006
I'm considering using it for some code generation technqiues (parsers mostly). Being able to declare what happens at the tail-end of a scope *first*, rather than last, means that you have to maintain less state (across nested scopes) in your code generator. - EricAnderton at yahooOk. That sounds like an interesting application. If it comes on line sometime soon let me know.
May 09 2006
In article <e3qvhn$q3v$1 digitaldaemon.com>, Ben Hinkle says...Sure. Although the use of scope() here is really just theoretical at this point... I have something that digests EBNF (w/some annotations) to build a self-hosting parser frontend, but it makes heavy use of exceptions and anon delegates. I'm pretty sure that I can make some of the pass/fail semantics of the various parse expressions more straightforward (almost as much as goto) by way of scope(), but I haven't tried it yet. // I'll let y'all know what's up when I get there, regardless. :) - EricAnderton at yahooI'm considering using it for some code generation technqiues (parsers mostly). Being able to declare what happens at the tail-end of a scope *first*, rather than last, means that you have to maintain less state (across nested scopes) in your code generator. - EricAnderton at yahooOk. That sounds like an interesting application. If it comes on line sometime soon let me know.
May 09 2006
On Tue, 9 May 2006 15:17:38 -0400, Ben Hinkle <bhinkle mathworks.com> wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); }Maybe... self documenting functions, listing all return values at the top? int foobar( ..etc.. ) { scope(success) return 1; scope(failure) return 0; } As someone else mentioned, commiting changes to a database, perhaps several, some of which are optional depending on program flow eg. int foobar( ..etc..) { if (a) { ..make changes to a.. scope(success) db.commit(a); } if (b) { ..make changes to b.. scope(success) db.commit(b); } ..make changes to c.. db.commit(c); //no scope.. required here return 1; } Regan
May 09 2006
Maybe... self documenting functions, listing all return values at the top? int foobar( ..etc.. ) { scope(success) return 1; scope(failure) return 0; }Does scope(failure) continue unwinding the stack? I wonder what the behavior is of returning from a scope(failure).As someone else mentioned, commiting changes to a database, perhaps several, some of which are optional depending on program flow eg. int foobar( ..etc..) { if (a) { ..make changes to a.. scope(success) db.commit(a); } if (b) { ..make changes to b.. scope(success) db.commit(b); } ..make changes to c.. db.commit(c); //no scope.. required here return 1; }I believe writing "scope(success) foo;" followed by the end of the current scope is equivalent to just writing "foo;". Maybe I'm misunderstanding the example.Regan
May 09 2006
On Tue, 9 May 2006 22:36:03 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Good question. No idea. :(Maybe... self documenting functions, listing all return values at the top? int foobar( ..etc.. ) { scope(success) return 1; scope(failure) return 0; }Does scope(failure) continue unwinding the stack? I wonder what the behavior is of returning from a scope(failure).I believe writing "scope(success) foo;" followed by the end of the current scope is equivalent to just writing "foo;". Maybe I'm misunderstanding the example.You're right. For some reason I got it in my head that scope(success) happened when the function itself returned, as opposed to the current scope closing. So, what about in this case: int foobar( ..etc ..) { if (a) scope(success) a.foo(); //A: immediately after if } //B: at function return when does a.foo() get executed? at A or B? I get the impression it's A. Regan
May 09 2006
Regan Heath wrote:On Tue, 9 May 2006 22:36:03 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Evidence from testing is that a.foo() is executed at point A. Which I think is a shame, really. It limits the usefulness of the scope() statement, which I feel is otherwise full of potential. Maybe its a little silly to say aloud, but certain statements just shouldn't "be a scope" for the sake of the scope() statement. Maybe different scopes should have "weights" or something... I don't know how it should be done, just that it should, or else a way created to say which scope you are anchoring on, but what on earth would the syntax be? -- Chris Nicholson-SaulsGood question. No idea. :(Maybe... self documenting functions, listing all return values at the top? int foobar( ..etc.. ) { scope(success) return 1; scope(failure) return 0; }Does scope(failure) continue unwinding the stack? I wonder what the behavior is of returning from a scope(failure).I believe writing "scope(success) foo;" followed by the end of the current scope is equivalent to just writing "foo;". Maybe I'm misunderstanding the example.You're right. For some reason I got it in my head that scope(success) happened when the function itself returned, as opposed to the current scope closing. So, what about in this case: int foobar( ..etc ..) { if (a) scope(success) a.foo(); //A: immediately after if } //B: at function return when does a.foo() get executed? at A or B? I get the impression it's A. Regan
May 10 2006
Regan Heath wrote:On Tue, 9 May 2006 22:36:03 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:if statements do not create a scope without { }, therefore it should be at B. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneI believe writing "scope(success) foo;" followed by the end of the current scope is equivalent to just writing "foo;". Maybe I'm misunderstanding the example.You're right. For some reason I got it in my head that scope(success) happened when the function itself returned, as opposed to the current scope closing. So, what about in this case: int foobar( ..etc ..) { if (a) scope(success) a.foo(); //A: immediately after if } //B: at function return when does a.foo() get executed? at A or B? I get the impression it's A. Regan
May 10 2006
James Dunne wrote:if statements do not create a scope without { }, therefore it should be at B.They don't? Sean
May 10 2006
"Sean Kelly" <sean f4.ca> wrote in message news:e3tjf6$1v3n$1 digitaldaemon.com...James Dunne wrote:They do. The code if (1) int a = 10; a = 20; is illegal.if statements do not create a scope without { }, therefore it should be at B.They don't? Sean
May 10 2006
Ben Hinkle wrote:"Sean Kelly" <sean f4.ca> wrote in message news:e3tjf6$1v3n$1 digitaldaemon.com...Then the implementation according to D's language specs is incorrect. Nothing is mentioned about new scopes created by if-statements or while-statements. New scopes are only created from block { } statements when inside a function body. Scope is mentioned (in passing) for the for-statement; the initializer is noted as a special case. Did I miss a blanket statement somewhere else in the docs about this? -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneJames Dunne wrote:They do. The code if (1) int a = 10; a = 20; is illegal.if statements do not create a scope without { }, therefore it should be at B.They don't? Sean
May 11 2006
James Dunne wrote: <snip>Then the implementation according to D's language specs is incorrect. Nothing is mentioned about new scopes created by if-statements or while-statements. New scopes are only created from block { } statements when inside a function body. Scope is mentioned (in passing) for the for-statement; the initializer is noted as a special case. Did I miss a blanket statement somewhere else in the docs about this?I think you're meant to use a bit of common sense here. What sense does it make for a declaration to be conditional at runtime? To be honest, I think a naked declaration as the body of a runtime control statement should be illegal. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 11 2006
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:e3vkhn$1kq5$1 digitaldaemon.com...James Dunne wrote: <snip>You're probably right. I had tried dmc and cl and they both complained about the use of 'a' without a declaration but in fact I was expecting an error that a declaration can't be the body of an 'if' statement. Since both compiler didn't say boo about the declaration I figured that declarations are considered statements. The C99 spec doesn't consider a declaration a statement so I suspect the compilers are giving poor errors.Then the implementation according to D's language specs is incorrect. Nothing is mentioned about new scopes created by if-statements or while-statements. New scopes are only created from block { } statements when inside a function body. Scope is mentioned (in passing) for the for-statement; the initializer is noted as a special case. Did I miss a blanket statement somewhere else in the docs about this?I think you're meant to use a bit of common sense here. What sense does it make for a declaration to be conditional at runtime? To be honest, I think a naked declaration as the body of a runtime control statement should be illegal. Stewart.
May 11 2006
Ben Hinkle wrote:"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:e3vkhn$1kq5$1 digitaldaemon.com...What about this: if( auto i = doSomething() ) printError( i ); I don't think anyone would expect 'i' to survive after the printError expression. SeanJames Dunne wrote: <snip>You're probably right. I had tried dmc and cl and they both complained about the use of 'a' without a declaration but in fact I was expecting an error that a declaration can't be the body of an 'if' statement. Since both compiler didn't say boo about the declaration I figured that declarations are considered statements. The C99 spec doesn't consider a declaration a statement so I suspect the compilers are giving poor errors.Then the implementation according to D's language specs is incorrect. Nothing is mentioned about new scopes created by if-statements or while-statements. New scopes are only created from block { } statements when inside a function body. Scope is mentioned (in passing) for the for-statement; the initializer is noted as a special case. Did I miss a blanket statement somewhere else in the docs about this?I think you're meant to use a bit of common sense here. What sense does it make for a declaration to be conditional at runtime? To be honest, I think a naked declaration as the body of a runtime control statement should be illegal.
May 11 2006
Sean Kelly wrote:Ben Hinkle wrote:Straight from the docs: "If an auto Identifier is provided, it is declared and initialized to the value and type of the Expression. Its scope extends from when it is initialized to the end of the ThenStatement." It's buried in there that an implicit scope is created for these cases, but nothing whatsoever is said about scope for a straight "if (expression) not-block-statement". As you noted earlier, this is a corner case where one would expect a declaration-statement to be illegal as an if-statement's body. Declaration-statements really aren't statements, they're just parsed that way to alleviate complexity. -- Regards, James Dunne"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:e3vkhn$1kq5$1 digitaldaemon.com...What about this: if( auto i = doSomething() ) printError( i ); I don't think anyone would expect 'i' to survive after the printError expression. SeanJames Dunne wrote: <snip>You're probably right. I had tried dmc and cl and they both complained about the use of 'a' without a declaration but in fact I was expecting an error that a declaration can't be the body of an 'if' statement. Since both compiler didn't say boo about the declaration I figured that declarations are considered statements. The C99 spec doesn't consider a declaration a statement so I suspect the compilers are giving poor errors.Then the implementation according to D's language specs is incorrect. Nothing is mentioned about new scopes created by if-statements or while-statements. New scopes are only created from block { } statements when inside a function body. Scope is mentioned (in passing) for the for-statement; the initializer is noted as a special case. Did I miss a blanket statement somewhere else in the docs about this?I think you're meant to use a bit of common sense here. What sense does it make for a declaration to be conditional at runtime? To be honest, I think a naked declaration as the body of a runtime control statement should be illegal.
May 11 2006
Stewart Gordon wrote:<snip> To be honest, I think a naked declaration as the body of a runtime control statement should be illegal.You just reminded me of a feature of a language called Nemerle (which is if ... else ... where ... unless ... The thing here is that if you use "if", you must also have an "else" clause. "where" and "unless" are equivalent to "if(cond) ..." and "if(!cond) ..." in D. The rationale behind this is that it solves the problem of ambiguous chains of if/else. I actually always liked this, but am yet to see it in any other language. Speaking of neat stuff Nemerle does: "var" for type inference and immutable variables ;) -- Daniel -- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 12 2006
On Wed, 10 May 2006 00:39:30 -0400, Regan Heath <regan netwin.co.nz> wrote:You're right. For some reason I got it in my head that scope(success) happened when the function itself returned, as opposed to the current scope closing. So, what about in this case: int foobar( ..etc ..) { if (a) scope(success) a.foo(); //A: immediately after if } //B: at function return when does a.foo() get executed? at A or B? I get the impression it's A. ReganThis gives me an idea, how about if there was scope(none) that is just like a regular block, but doesn't create a new scope. This would be for when you only need to group statements but have no interest in a new scope. void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz(); - Chris
May 10 2006
Chris Miller wrote:This gives me an idea, how about if there was scope(none) that is just like a regular block, but doesn't create a new scope. This would be for when you only need to group statements but have no interest in a new scope. void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz();It's a nasty hack, but: if(!a) goto blah; scope(success) a.foo(); blah: ... Sean
May 10 2006
On Thu, 11 May 2006 08:13:37 +1000, Sean Kelly <sean f4.ca> wrote:Chris Miller wrote:And I guess this is just as nasty ... scope(success) if (a) a.foo(); -- Derek Parnell Melbourne, AustraliaThis gives me an idea, how about if there was scope(none) that is just like a regular block, but doesn't create a new scope. This would be for when you only need to group statements but have no interest in a new scope. void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz();It's a nasty hack, but: if(!a) goto blah; scope(success) a.foo(); blah: ...
May 10 2006
Derek Parnell wrote:On Thu, 11 May 2006 08:13:37 +1000, Sean Kelly <sean f4.ca> wrote:Preferable so long as the state of a is maintained until scope exit. But all of this smacks as an attempt to use the scope feature in a manner that wasn't intended. SeanChris Miller wrote:And I guess this is just as nasty ... scope(success) if (a) a.foo();This gives me an idea, how about if there was scope(none) that is just like a regular block, but doesn't create a new scope. This would be for when you only need to group statements but have no interest in a new scope. void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz();It's a nasty hack, but: if(!a) goto blah; scope(success) a.foo(); blah: ...
May 10 2006
On Wed, 10 May 2006 15:52:36 -0700, Sean Kelly <sean f4.ca> wrote:Derek Parnell wrote:Yeah. It's a pity though. What about: int foobar( .. ) { if (a) { scope(success) scope(success) a.foo(); } } I wonder. ReganOn Thu, 11 May 2006 08:13:37 +1000, Sean Kelly <sean f4.ca> wrote:Preferable so long as the state of a is maintained until scope exit. But all of this smacks as an attempt to use the scope feature in a manner that wasn't intended.Chris Miller wrote:And I guess this is just as nasty ... scope(success) if (a) a.foo();This gives me an idea, how about if there was scope(none) that is just like a regular block, but doesn't create a new scope. This would be for when you only need to group statements but have no interest in a new scope. void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz();It's a nasty hack, but: if(!a) goto blah; scope(success) a.foo(); blah: ...
May 10 2006
"Sean Kelly" <sean f4.ca> wrote in message news:e3toih$26v4$1 digitaldaemon.com...Chris Miller wrote:In Cx I was going to make that illegal - much like in C++ it's illegal to goto past an initializer or into a try block.This gives me an idea, how about if there was scope(none) that is just like a regular block, but doesn't create a new scope. This would be for when you only need to group statements but have no interest in a new scope. void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz();It's a nasty hack, but: if(!a) goto blah; scope(success) a.foo(); blah: ...Sean
May 10 2006
Chris Miller wrote: <snip>void foo() { if(a) scope(none) { stuff(); scope(success) bar(); } baz(); } bar() would execute after baz();I'm not sure about this. Of course, it would need to be illegal to declare anything within a scope(none) block. Implementing scopeless conditionals would add a runtime dependence to the ScopeStatement mechanism. The program would have to either note the value of the conditional at the time, or use some kind of function stack to keep track of which ScopeStatements will be executed. Moreover, what if it's a loop rather than an if? Should the cleanup code be executed once for each iteration of the loop, all at once when exiting the scope containing the loop? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 11 2006
I've been writing an OO binding to the cairo 2D drawing API, and scope(success) has been a huge help. Basically, cairo's api functions rarely if ever return an error code. Instead, they set a flag on the object's pointer itself[1]_. Since I need to check this flag after every call I make on any particular object, each wrapper class has a protected "checkStatus" member. Then, I just need to write this: void someMember() { scope(success) checkStatus(); // ... do cairo stuff ... } When the "do cairo stuff" is just a simple function call, I don't really gain anything. But it comes in handy when I've got to return values from cairo functions, or when I have to use any kind of complex logic. Plus, I find reading "scope(success) checkStatus()" to be very clear; that, and it's immediately obvious just looking at the code if I've forgotten it (almost every function in the binding follows that pattern so exceptions to that are easily spotted). -- Daniel .. [1]: When I say "object" what I mean is that objects in cairo are just pointers to undefined structs. So a "cairo_pattern_t*" is an "object" :P P.S. Cx looks very cool; must have a poke around that... Ben Hinkle wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); } -Ben-- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 10 2006
Daniel Keep wrote:When the "do cairo stuff" is just a simple function call, I don't really gain anything. But it comes in handy when I've got to return values from cairo functions, or when I have to use any kind of complex logic. Plus, I find reading "scope(success) checkStatus()" to be very clear; that, and it's immediately obvious just looking at the code if I've forgotten it (almost every function in the binding follows that pattern so exceptions to that are easily spotted).Right. It eliminates the all-too-common bug of adding an extra return statement but forgetting to add the check/cleanup code that goes along with it.
May 12 2006
Hey Ben glad to see you posting again :). tinycx looks cool am trying it out. I've never used scope(success) , so no comment really ;). Charlie Ben Hinkle wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); } -Ben
May 11 2006
Ben Hinkle wrote:I hope this doesn't come of as a flame, but I'm wondering if anyone is using scope(success) and why. I can't find any reason for it. Some background: I've slowed my D work to focus on some C experimental features I'm calling Cx: http://www.tinycx.org and currently I'm implementing the error handling using reserved labels "error:" and "finally:". The error label is roughly like scope(failure) and the finally label is roughly like scope(exit). There's no try-catch-finally. I don't plan on adding anything like scope(success) because I couldn't think of why anyone would want to use it. Why not just put the code at the end of the scope like normal code-flow? I suppose one could code the entire scope in reverse just for kicks: void main() { scope(success) printf("world\n"); scope(success) printf("hello "); }The scope(success) will execute even if the scope is exited via a return, break, or continue statement, but not if it is exited via a thrown exception. Thus, it is fundamentally different from just putting the code at the closing }. The code: { foo(); scope(success) bar(); def(); } is equivalent to: { foo(); int x; try { x = 0; def(); } catch (Object o) { x = 1; throw o; } finally { if (x == 0) bar(); } } which is a tedious, error-prone, and unobvious thing to write.
May 12 2006