digitalmars.D - improving scope(finally/success)
- Tomer Filiba (34/34) Dec 03 2015 it'd be really helpful if scope() statements got hold of the
- Idan Arye (16/50) Dec 03 2015 int foo(bool cond) { // scope 1
- Marc =?UTF-8?B?U2Now7x0eg==?= (10/46) Dec 03 2015 Tomer's suggested lowering can't work, because tmp's scope
- Chris Wright (10/10) Dec 03 2015 You can already do it with a slight change, and it's not so painful, at
- Steven Schveighoffer (11/21) Dec 03 2015 auto ref logCall(alias f, Args...)(auto ref Args args) {
- Artur Skawina via Digitalmars-d (8/18) Dec 04 2015 Which will happily accept:
it'd be really helpful if scope() statements got hold of the return value or exception, e.g., scope(success, retval) { writeln("the retval is", retval) } scope(failure, ex) { if(typeid(ex) == typeid(MyException)) { callTheCops(); } } it would make logging very easy, and since these statements are basically code-rewrites i don't suppose it would be hard to implement. from a syntax point of view: scope(succes[, VARNAME]) // where VARNAME would be the return value (a const tmp variable?) scope(failure[, VARNAME]) // where VARNAME would be hold the exception (a Throwable) i mean, code such as int f() { scope(exit) writeln("bye"); return 5; } is rewritten as something like int f() { try { auto tmp = 5; } finally { writeln("bye"); } return tmp; } so `tmp` is already there for the finally clause (modulo scoping issues)
Dec 03 2015
On Thursday, 3 December 2015 at 11:41:29 UTC, Tomer Filiba wrote:it'd be really helpful if scope() statements got hold of the return value or exception, e.g., scope(success, retval) { writeln("the retval is", retval) } scope(failure, ex) { if(typeid(ex) == typeid(MyException)) { callTheCops(); } } it would make logging very easy, and since these statements are basically code-rewrites i don't suppose it would be hard to implement. from a syntax point of view: scope(succes[, VARNAME]) // where VARNAME would be the return value (a const tmp variable?) scope(failure[, VARNAME]) // where VARNAME would be hold the exception (a Throwable) i mean, code such as int f() { scope(exit) writeln("bye"); return 5; } is rewritten as something like int f() { try { auto tmp = 5; } finally { writeln("bye"); } return tmp; } so `tmp` is already there for the finally clause (modulo scoping issues)int foo(bool cond) { // scope 1 { // scope 2 scope(success, retval) { writeln("the retval is", retval) } if (cond) { // scope 3 return 1; } } return 2; } `foo(true)` should obviously print "the retval is 1", but what should `foo(false)` print? It's `scope(success)` block should run when it exists scope 2, but the return value is only determined at the end of scope 1.
Dec 03 2015
On Thursday, 3 December 2015 at 13:07:53 UTC, Idan Arye wrote:On Thursday, 3 December 2015 at 11:41:29 UTC, Tomer Filiba wrote:Tomer's suggested lowering can't work, because tmp's scope doesn't extend outside of the try. It would need to be hoisted up to the beginning of the function. This would then imply that `foo(false)` would print "0" (int.init). However, I don't think this kind of lowering is a good idea, because it would create a temporary lvalue, which implies that it needs to go through the full construct/assign/destroy cycle instead of a simple move, which is a potentially observable difference to the current behaviour.int f() { scope(exit) writeln("bye"); return 5; } is rewritten as something like int f() { try { auto tmp = 5; } finally { writeln("bye"); } return tmp; } so `tmp` is already there for the finally clause (modulo scoping issues)int foo(bool cond) { // scope 1 { // scope 2 scope(success, retval) { writeln("the retval is", retval) } if (cond) { // scope 3 return 1; } } return 2; } `foo(true)` should obviously print "the retval is 1", but what should `foo(false)` print? It's `scope(success)` block should run when it exists scope 2, but the return value is only determined at the end of scope 1.
Dec 03 2015
You can already do it with a slight change, and it's not so painful, at least in simple functions: int foo(bool b) { auto result = 2; scope(exit) writeln(result); if (b) { result = 1; } return result; }
Dec 03 2015
On 12/3/15 10:24 AM, Chris Wright wrote:You can already do it with a slight change, and it's not so painful, at least in simple functions: int foo(bool b) { auto result = 2; scope(exit) writeln(result); if (b) { result = 1; } return result; }auto ref logCall(alias f, Args...)(auto ref Args args) { auto ref printResult(T)(auto ref T t) { writeln(t); return t; } return printResult(f(args)) } logCall!foo(true); -Steve
Dec 03 2015
On 12/03/15 16:33, Steven Schveighoffer via Digitalmars-d wrote:auto ref logCall(alias f, Args...)(auto ref Args args) { auto ref printResult(T)(auto ref T t) { writeln(t); return t; } return printResult(f(args)) } logCall!foo(true);Which will happily accept: bool foo(ref bool a) { return a=false; } And, yes, it can be dealt with via a bit of introspection, but nobody will bother in practice (consider that 'f' may be overloaded). So it doesn't really work for non-trivial or generic code. artur
Dec 04 2015