View mode: basic / threaded / horizontal-split · Log in · Help
February 28, 2006
try..catch..pass..finally Was: DMD 0.148 - scope guard
>I'd say add another option to try..catch..finally paradigm.
>
>-S.

Seconded.  For more fun, next we can debate whether the syntax should be:

1.  try..pass..catch..finally    
2.  try..catch..pass...finally
3.  try..catch..finally..pass


Tom
February 28, 2006
Re: DMD 0.148 - scope guard
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message 
news:dtvkhr$2cf4$1@digitaldaemon.com...
>
> "Walter Bright" <newshound@digitalmars.com> wrote in message 
> news:dtr8kl$4lm$1@digitaldaemon.com...
>>
>> "Derek Parnell" <derek@psych.ward> wrote in message 
>> news:op.s5j942tp6b8z09@ginger.vic.bigpond.net.au...
>>> Wow! I know of one other language that (almost) implements this.
>>
>> Which one?
>>
>
> If I understand this correctly Ruby has something similar
> http://www.rubycentral.com/book/tut_exceptions.html
>
> But this is the same try-catch-finally I guess
> as these on_scope_*** too, btw.

Ruby's rescue thing looks like try-catch. on_scope is much more than 
try-catch, or I wouldn't have implemented it <g>.
February 28, 2006
Re: Negative
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message 
news:dtvl91$2dds$1@digitaldaemon.com...
>
> This is real life example:
>
> Logger log = getLogger();
> try {
>      File outf = getOutputFile(); // state managed outside
>      File inf = getInputFile(); // state managed outside
>      File tmpf = createTempFile();
>      // lots of code
> } catch (Object e)  {
>      log.logFailure("...");
>      throw e;
> } finally {
>     delete tmpf;
> }
> log.close();

I don't see how it could be real life, since tmpf is not in scope in the 
finally statement, so it won't compile. Furthermore, even if tmpf was in 
scope, if getOutputFile() throws, then tmpf wouldn't have even been created 
when the finally statement attempts to delete it. The log.close() also does 
not reliably happen, as the throw e; statement would cause it to be skipped.

These kinds of issues are what on_scope_xxx are for. Let's rewrite it:

Logger log = getLogger();
   on_scope_exit log.close();
   on_scope_failure log.logFailure("...");
File outf = getOutputFile();
File inf = getInputFile();
File tmpf = createTempFile();
   on_scope_exit delete tmpf;
...lots of code...

We don't have any more resource leaks.
February 28, 2006
Re: try..catch..pass..finally Was: DMD 0.148 - scope guard
On Tue, 28 Feb 2006 06:34:00 +0000 (UTC), Tom Johnson  
<Tom_member@pathlink.com> wrote:
>> I'd say add another option to try..catch..finally paradigm.
>>
>> -S.
>
> Seconded.  For more fun, next we can debate whether the syntax should be:
>
> 1.  try..pass..catch..finally
> 2.  try..catch..pass...finally
> 3.  try..catch..finally..pass

No, on_scope gives us more than try/catch/finally. Let me try this another  
way.

"catch" from try/catch/finally allows:
 - you to execute a static/pre-defined set of code in the event that there  
is a failure in the current scope.

"finally" from try/catch/finally allows:
 - you to execute a static/pre-defined set of code at the exit of the  
current scope in all cases.

Compare that to:

on_scope_failure allows:
 - you to add one or more sets of code, at the points at which they become  
required, to the list of things to execute in the event of a failure.

on_scope_exit allows:
 - you to add one or more sets of code, at the points at which they become  
required, to the list of things to execute at the exit of the scope in all  
cases.

To achieve the same thing that on_scope gives with try/finally requires  
you to store state somewhere to indicate which parts of the finally block  
to execute, or, it requires that you define several finally blocks and  
nest them. Both of those options are no where near as neat as on_scope.

I'm honestly baffled that people can't see the difference.

Regan
February 28, 2006
Re: Negative
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message 
news:du0hhf$a0u$1@digitaldaemon.com...
> Why you think that your example is aesthetically
> better (technically they are the same) than this?
>
> Transaction abc()
> {
>    Foo f;   Bar b;  Def d;
>    try
>   {
>       f = dofoo();
>       b = dobar();
>       d = dodef();
>       return Transaction(f, b, d);
>   }
>   finally {
>      delete f; delete b; delete d;
>   }
> }

Technically, they are not the same. The above version *always* deletes f, b 
and d, but it's not supposed to if the function succeeds. Only if dofoo(), 
dobar(), or dodef() throws are f, b and d supposed to be deleted.

This is the whole problem with try-finally. It works great with trivial 
problems, and all the tutorials and example code unsurprisingly only show 
trivial problems. Try scaling it up for things like multi-step transactions, 
and it gets very complicated very fast, and it gets very hard to get right.

Here's the on_scope version:

Transaction abc()
{
   Foo f = dofoo();
       on_scope_failure delete f;
   Bar b = dobar();
       on_scope_failure delete b;
   Def d = dodef();
       on_scope_failure delete d;
   return Transaction(f, b, d);
}

Scaling it up is as easy as linearly adding more on_scope statements, and 
easy to get it right.
February 28, 2006
Re: DMD 0.148 - scope guard
On Mon, 27 Feb 2006 12:40:56 -0500, Chris Miller wrote:

I find this one better too.

> On Sat, 25 Feb 2006 21:06:36 -0500, Walter Bright  
> <newshound@digitalmars.com> wrote:
> 
>> Scope guards are a novel feature no other language has. They're based on
>> Andrei Alexandrescu's scope guard macros, which have led to considerable
>> interest in the idea. Check out the article
>> www.digitalmars.com/d/exception-safe.html
>>
> 
> This format looks good to me:
> 
> scope(exit)  foo();
> scope(success)  bar();
> scope(failure)  baz();
> 
> similar to extern(name), pragma(name), etc, requires one `scope` keyword,  
> name in () doesn't need to be a keyword but is still treated special, and  
> doesn't look bad.
February 28, 2006
Re: Negative
>
> Technically, they are not the same. The above version *always* deletes f, 
> b and d, but it's not supposed to if the function succeeds. Only if 
> dofoo(), dobar(), or dodef() throws are f, b and d supposed to be deleted.

Ok, mea culpa.

>
> This is the whole problem with try-finally. It works great with trivial 
> problems, and all the tutorials and example code unsurprisingly only show 
> trivial problems. Try scaling it up for things like multi-step 
> transactions, and it gets very complicated very fast, and it gets very 
> hard to get right.

Well, I spent year programming on PocketPC in eVC where are no such
things as exceptions. In principle. Not implemented in C++ compiler.
Still alive :)

>
> Here's the on_scope version:
>
> Transaction abc()
> {
>    Foo f = dofoo();
>        on_scope_failure delete f;
>    Bar b = dobar();
>        on_scope_failure delete b;
>    Def d = dodef();
>        on_scope_failure delete d;
>    return Transaction(f, b, d);
> }
>
> Scaling it up is as easy as linearly adding more on_scope statements, and 
> easy to get it right.

True.

But
Transaction abc()
{
   try {
     Foo f = dofoo();
     Bar b = dobar();
     Def d = dodef();
     return Transaction(f, b, d);
  } catch(object er) {
       delete f; delete b; delete d;
  }
}
is not worse to be honest.

I would think rather about extending mixins to allow to add
on_scope_exit as a custom template conrstructions.

Like mixins taking block {} as a parameter:

template on_scope_exit(B)  auto Auto t = new Auto(B);

... and in Galaxy far far away:

mixin on_scope_exit{ delete foo; }

So anyone can implement needed policy for himself.

I mean on_scope_exit is only one particular way of dealing
with the problem. There are and will be others.

Huh?

Andrew.
February 28, 2006
Re: DMD 0.148 - scope guard
"S. Chancellor" <dnewsgr@mephit.kicks-ass.org> wrote in message 
news:du0lmk$dbg$1@digitaldaemon.com...
> On 2006-02-25 18:06:36 -0800, "Walter Bright" <newshound@digitalmars.com> 
> said:
>
>> Scope guards are a novel feature no other language has. They're based on 
>> Andrei Alexandrescu's scope guard macros, which have led to considerable 
>> interest in the idea. Check out the article 
>> www.digitalmars.com/d/exception-safe.html
>
> The only thing I see that's amazingly useful about this is the 
> on_scope_success.  Having a block of code that is only executed when an 
> exception is NOT thrown would be nice.  However, the rest of this stuff 
> seems like rocks under the water.  Your example of the new programmer 
> coming in reads like this to me:  "The new programmer may not take the 
> time to actually read the code he's modifying, so lets stick hidden stuff 
> in there to take care of things he might have missed."  Which doesn't seem 
> very logical to me, as it may be just as important to modify those on 
> success/on failure blocks and miss them.
>
> I'd say add another option to try..catch..finally paradigm.
>
> -S.
>

try {

  something horrible here....

  //on_scope_success:

  ... and here is on success part

}

Why do you need separate 'passed' part?

Andrew.
February 28, 2006
Re: Negative
"Regan Heath" <regan@netwin.co.nz> wrote in message 
news:ops5n25std23k2f5@nrage.netwin.co.nz...
> On Mon, 27 Feb 2006 19:54:23 -0800, Andrew Fedoniouk 
> <news@terrainformatica.com> wrote:
>> Seems like I realy don't understand something here...
>>
>> Why you think that your example is aesthetically
>> better (technically they are the same) than this?
>
> Wait, your example below is not technically the same as mine because:
>
> 1. My example (actually taken from the docs on digitalmars.com) used 
> on_scope_failure, not on_scope_exit. on_scope_exit has the same effect as 
> "finally" except...
>
> 2. The important feature of all of these statements is that they allow you 
> to add items to the list of things to do _as you go_ and to then execute 
> them in reverse lexical order at the appropriate time i.e. on_scope_exit 
> or on_scope_failure etc.

BTW:
 Walter is using "reverse lexical order" incorectly in the doc I beleive.
 "lexical order" is something from different opera.


Andrew
February 28, 2006
Re: Negative
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message 
news:du106f$ptt$1@digitaldaemon.com...
> Well, I spent year programming on PocketPC in eVC where are no such
> things as exceptions. In principle. Not implemented in C++ compiler.
> Still alive :)

It's true that if code doesn't generate exceptions, then one doesn't need 
exception safety.

> But
> Transaction abc()
> {
>    try {
>      Foo f = dofoo();
>      Bar b = dobar();
>      Def d = dodef();
>      return Transaction(f, b, d);
>   } catch(object er) {
>        delete f; delete b; delete d;
>   }
> }
> is not worse to be honest.

It is worse because it won't even compile. f, b, and d are not in scope in 
the catch statement. Even if they were, there's still a serious bug - if 
dofoo() throws an exception, then the catch statement will attempt to delete 
b and d, which are not even initialized yet.
6 7 8 9 10 11 12 13 14
Top | Discussion index | About this forum | D home