View mode: basic / threaded / horizontal-split · Log in · Help
February 27, 2006
Re: Negative
Andrew Fedoniouk wrote:
> I am with Charles here...
> 
> I don't understand why
> on_scope_failure & co. are significantly better than
> try catch finally?

imho, they're not better in all cases, just in some :)

> What is wrong with them?

nothing

> Semantically try-catch-finally are well known and
> widely recognizable constructions.

agreed

> BTW: Am I right in my assumption that
> proposed on_scope_exit / on_scope_success / on_scope_failure
> is a direct equivalent of the following:
> 
> try
> {
>    [scope code]
>    my_on_scope_success().
> }
> catch(...)
> {
>    my_on_scope_failure().
> }
> finally {
>   my_on_scope_exit().
> }
> 
> If yes then again what it wrong with them in principle?

Well, nothing in principle, but like it was said already:
- init and cleanup can be close together (which is good in itself)
- as a consequence, it's harder to forget cleanup
- it's prettier - code that is about linear looks like it's about linear 
(see example 2)
- you can reorder them as you see fit (see example 1)
- less typing :)


Example 1:

=======================
on_scope_exit foo();
on_scope_failure bar();
on_scope_exit baz();

// code
=======================

Versus

=======================
try {
    try {
        try {
            // code
        } finally {
            baz();
        }
    } catch (Object e) {
        bar();
        throw e;
    }
} finally {
    foo();
}
=======================


Example 2:

==================================
// notice how creation and cleanup are together
Logger log = getLogger();
on_scope_exit log.close();
on_scope_failure log.logFailure("...");

File outf = getOutputFile();
on_scope_exit outf.close();

File inf = getInputFile();
on_scope_exit inf.close();

File tmpf = createTempFile();
on_scope_exit tmpf.delete();
on_scope_exit tmpf.close();

// lots of code
==================================

Versus

==================================
Logger log = getLogger();
try {
    File outf = getOutputFile();
    try {
        File inf = getInputFile();
        try {
            File tmpf = createTempFile();
            try {
                // lots of code
            } finally {
                tmpf.close();
                tmpf.delete();
            }
        } finally {
            inf.close();
        }
    } finally {
        outf.close();
    }
} catch (Object e) {
    log.logFailure("...");
    throw e;
} finally {
    log.close();
}
==================================
February 27, 2006
Re: DMD 0.148 - scope guard
"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.

Andrew.
February 27, 2006
Re: Negative
> ==================================
> Logger log = getLogger();
> try {
>     File outf = getOutputFile();
>     try {
>         File inf = getInputFile();
>         try {
>             File tmpf = createTempFile();
>             try {
>                 // lots of code
>             } finally {
>                 tmpf.close();
>                 tmpf.delete();
>             }
>         } finally {
>             inf.close();
>         }
>     } finally {
>         outf.close();
>     }
> } catch (Object e) {
>     log.logFailure("...");
>     throw e;
> } finally {
>     log.close();
> }
> ==================================
>
>

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();

----------------------------------
Andrew.
February 27, 2006
Re: DMD 0.148 - scope guard
Walter Bright 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
> 
> 

The syntax seems a little kludgey.
February 27, 2006
Re: Negative
On Mon, 27 Feb 2006 10:42:10 -0800, Andrew Fedoniouk  
<news@terrainformatica.com> wrote:
> I am with Charles here...
>
> I don't understand why
> on_scope_failure & co. are significantly better than
> try catch finally?
>
> What is wrong with them?
>
> Semantically try-catch-finally are well known and
> widely recognizable constructions.
>
> BTW: Am I right in my assumption that
> proposed on_scope_exit / on_scope_success / on_scope_failure
> is a direct equivalent of the following:
>
> try
> {
>    [scope code]
>    my_on_scope_success().
> }
> catch(...)
> {
>    my_on_scope_failure().
> }
> finally {
>   my_on_scope_exit().
> }
>
> If yes then again what it wrong with them in principle?

For a simple example it is very similar, for a more complex one it's not.  
Have you read this:
  http://www.digitalmars.com/d/exception-safe.html

Here is my attempt at "explaination by example", a more complex example  
and it's equivalent using try/catch/finally.

Transaction abc()
{
    Foo f;
    Bar b;
    Def d;

    f = dofoo();
    on_scope_failure dofoo_unwind(f);

    b = dobar();
    on_scope_failure dobar_unwind(b);

    d = dodef();

    return Transaction(f, b, d);
}

as try/catch/finally:

Transaction abc()
{
	Foo f;
	Bar b;
	Def d;

	f = dofoo();	
	try {
		b = dobar();
		try {
			d = dodef();
			return Transaction(f, b, d);
		}
		catch(Object o) {
			dobar_unwind(b);
			throw o;
		}
	}
	catch(Object o) {
		dofoo_unwind(f);
		throw o;
	}	
}

Note, the order of the unwind calls is important:
  http://www.digitalmars.com/d/statement.html#scope
  "If there are multiple OnScopeStatements in a scope, they are executed  
in the reverse lexical order in which they appear."

There are many benefits of on_scope over try/catch, they are:

1. less verbose, with less clutter it's easier to see the purpose of the  
code. on scope scales well to handle many 'transactions' which require  
cleanup, like the example above, try/catch/finally does not, it gets  
horribly nested and confusing.

2. groups the cleanup code with code that requires it, less seperation  
between the thing that is done, and the thing that cleans up after it.  
try/catch/finally has the cleanup code in a seperate 'catch' or 'finally'  
scope often a long way from the code that creates the need for that  
cleanup.

Regan
February 27, 2006
Re: DMD 0.148 - scope guard
"Ben Hinkle" <bhinkle@mathworks.com> wrote in message 
news:dtv8f5$1svn$1@digitaldaemon.com...
>
> "Walter Bright" <newshound@digitalmars.com> wrote in message 
> news:dtr2fg$2vqr$4@digitaldaemon.com...
>> 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
>
> Note GCC has pretty much the same thing with the "cleanup" attribute 
> extension on variables: 
> http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Variable-Attributes.html

cleanup only corresponds with on_scope_exit, not the other two. It also only 
runs a function with a local variable as a parameter - i.e. it is the same 
thing as RAII. It doesn't allow arbitrary code to be executed, nor manage 
things like state of a class member, etc.
February 27, 2006
Re: Negative
Andrew Fedoniouk escribió:
> 
> 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();
> 
> ----------------------------------
> Andrew.
> 
> 

This is not rhetorical, but honest: in the cases where you said "state managed
outside", how do you do that? i.e., how do you know for sure that the files will
be closed, provided that destructors are not guaranteed to be run and you can't 
return auto references?

-- 
Carlos Santander Bernal
February 27, 2006
Re: DMD 0.148 - scope guard
Chris Miller wrote:

> This format looks good to me:
> 
> scope(exit)  foo();
> scope(success)  bar();
> scope(failure)  baz();

Yeap. It's nice. Maybe s/success/pass/ s/failure/fail/ would even improve it
a little.
February 27, 2006
Re: DMD 0.148 - scope guard
Aye gets my vote too.


Chris Miller wrote:
> 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 27, 2006
Re: DMD 0.148 - scope guard
On Mon, 27 Feb 2006 17:16:38 -0500, Dawid Ciężarkiewicz  
<dawid.ciezarkiewicz@gmail.com> wrote:

> Chris Miller wrote:
>
>> This format looks good to me:
>>
>> scope(exit)  foo();
>> scope(success)  bar();
>> scope(failure)  baz();
>
> Yeap. It's nice. Maybe s/success/pass/ s/failure/fail/ would even  
> improve it
> a little.

Good one.
4 5 6 7 8 9 10 11 12
Top | Discussion index | About this forum | D home