View mode: basic / threaded / horizontal-split · Log in · Help
February 28, 2006
Re: DMD 0.148 - scope guard
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.

Here's some more experimental ideas:

  scope.onExit fooexpr;
  scope.onSuccess barexpr;
  scope.onFailure bazexpr;

Now a more clean/pure version, but that doesn't allow block statements:

  scope.onExit(fooexpr);
  scope.onSuccess(barexpr);
  scope.onFailure(bazexpr);

Don't really 100% like them, but I'll present them anyway, maybe it will 
inspire someone for a better idea. (The problem with this one is that is 
makes scope seem like a workable proper object, while it's not)

-- 
Bruno Medeiros - CS/E student
"Certain aspects of D are a pathway to many abilities some consider to 
be... unnatural."
February 28, 2006
Re: DMD 0.148 - scope guard
In article <du0slm$lj0$2@digitaldaemon.com>, Walter Bright says...
>
>Ruby's rescue thing looks like try-catch. on_scope is much more than 
>try-catch, or I wouldn't have implemented it <g>. 

on_scope is quite cute, and certainly cleaner than the C++ implementation of
ScopeGuard. Compared to ctor/dtor RAII, though, it still has the same problem as
try-catch{-finally} - a naive use of a resource is wrong by default, and the
programmer has to do something extra to make it right.

When I first saw Andrei's paper it struck me that what made things painful in
C++ was the lack of usable closures. Since D is pretty good in this regard,
could the same effect have been achieved with a less sugary but more regular
approach reusing RAII-auto syntax, e.g.

# import std.scopeguard;
# auto Guard onOk = new OnScopeSuccessGuard(&mySuccessFunc);
# auto Guard onFail = new OnScopeFailureGuard(function { /* ad hoc code */ });

with something like C++'s std::uncaught_exception in the Guard subclass
destructor implementations to discriminate exit conditions?

cheers
Mike
February 28, 2006
Re: Negative
Andrew Fedoniouk escribió:
> Hi, Carlos
> 
> "Carlos Santander" <csantander619@gmail.com> wrote in message 
> news:dtvtgt$2mvh$1@digitaldaemon.com...
>> 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?
> 
> "get" in getOutputFile implies that file exists somewhere and opened by 
> someone else
> so code here cannot delete it.
> 

If I understand correctly, then that someone else who opened the file would have 
to close it (or delete it, as you put it). How does the opener know when to 
close it?

> In contrary "create" in createTempFile says that it creates new instance
> so we are owning it - must delete.
> 
> If getOutputFile creates new instance then
> finally {
>      delete tmpf;
>      delete outf;
>      delete inf;
> }
> will be enough.
> 

See Walter's reply.

> In any case it shall be something one: either
> try-catch-finally or on_scope_xxx() - two similar
> and probably conflicting mechanisms is a bad design.
> 

Not necessarily. RAII and finally could be seen as "similar mechanisms", but I 
don't think having both is a bad design. How about for and foreach? do and 
while? function and delegate?

> ( This is why I like Java - with some minor exceptions
>  its grammar just perfect for the the domain it serves.
>  Ascetic but clean and simple. )
> 
> Andrew Fedoniouk.
> http://terrainformatica.com
> 
> 

-- 
Carlos Santander Bernal
February 28, 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
> 

This is excellent!

is it the first really new thing in D?
thinking hard (for 30 seconds) seems to be the first one.

excellent in any case.

Ant
February 28, 2006
Re: try..catch..pass..finally Was: DMD 0.148 - scope guard
Regan,

Your last post finally made me get it.

on_scope_* is a different kind of construct.  It's kind of like (imperfect
analogy coming) descending down a dynamic ladder.  If you have to go up again
on_scope_failure tells you which how to undo each "code rung" so you can go back
up.  The on_scope_success adds a last rung from the floor and on_scope_exit adds
codes at both ends of the ladder.  The analogy wears a bit thin because you can
do on_scope_exit failure and success multiple times.  

I have rtfa and all the previous messages and it still wasn't apparent that all
this was possible.

Thanks,

Tom


In article <ops5n86slk23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>
>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: DMD 0.148 - scope guard
Chris Miller wrote:
<snip>
> 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.

The scope(exit) notation gets me thinking, considering that all three of 
them are on exit from the scope.  Not that I can think of anything 
better....

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.
February 28, 2006
Re: try..catch..pass..finally Was: DMD 0.148 - scope guard
Regan Heath wrote:
<snip>
> 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.

When I started to read it, it did indeed look like syntactic sugar for 
try/finally.  But then I realised that, as you say, it saves some of the 
need to nest try/finally blocks.

on_scope_failure has another advantage still: if you have multiple catch 
blocks, it saves having to replicate the recovery code in each.

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.
February 28, 2006
Re: DMD 0.148 - scope guard
Lucas Goss wrote:

>>> Chris Miller wrote:
>>>>
>>>> scope(exit)  foo();
>>>> scope(success)  bar();
>>>> scope(failure)  baz();
>>>
> 
> While I don't really like the _'s in on_scope_exit, etc, I don't like
> this proposed syntax any more, in fact I think I don't like it as much.
> With this proposed syntax it seems like an expression such as an
> if/while/for/etc, however, in all of those the condition is user
> defined. So this proposed syntax would appear inconsistent.
> 
> <rant>
> And if there's one thing I dislike in languages and libraries, it's
> inconsistencies, right up with it is non descriptive or inconsistent
> functions. Don't even get me started on those, I'm looking at you Phobos
> :)
> 
> writefln ... what? write file name? write first line? write f language?
> isxdigit ... is x a digit? of course not! why do I need this function?
> pardir   ... parrot directory? not everyone has the parrot vm.
> altsep   ... Alt key seperator? does this get the Alt key?
> ifind    ... integer find? iFind? iWork? is this for Mac only?
> 
> First, I don't see why all of the above aren't readable. And second, why
> don't they follow the D guidelines of camelCase? (I prefer the
> PascalCase myself, but I could live with camelCase if it was
> consistent). For example:
> 
> writeLine(string), writeLine(string, format)
> isHexDigit
> parentDirectory
> windowsAlternateSeperator
> FindFirst
> 
> The only reason I can see is "it will make it easier for C/C++
> programmers." or, it's shorter. The first has little merit, as
> templates, operator overloading, streams, reals etc. are all different
> (for good reason of course), and C/C++ programmers will have to learn D
> no matter what. As for shorter, you may gain a few seconds (after a
> couple hundred lines), but I'd much rather be able to tell what I was
> doing at a glance...
> 
> (notice: Yes I know, the functions come from C... it's good we hold on
> to our history just like C++ did :) )
> </rant>
> 
> I'd much rather prefer something like:
> scopeexit
> scopesuccess
> scopefailure
> 
> Or some derivative:
> scopeabort, scopefault, scopedone, scopefinish, scope?
> 
> ps. I like the looks of this new feature and find it very elegant. I
> prefer this to try/catch/finally.

Sorry, but I find the proposed statements very consistent with D's existing
version, debug, etc statements.
February 28, 2006
Re: Negative
Walter Bright wrote:
> "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.

It's worth mentioning that an allocation failure will cause an exception 
to be thrown, in addition to divide by zero and other errors on Windows. 
 So code doesn't need to explicitly throw to generate exceptions.

The PocketPC really doesn't have exceptions?  And they still call it 
C++? :-)

>> 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.

Is it really a bug to call delete on a null reference?  This is 
well-defined behavior in C++.


Sean
February 28, 2006
Re: DMD 0.148 - scope guard
"Mike Capp" <mike.capp@gmail.com> wrote in message 
news:du1ire$1h1s$1@digitaldaemon.com...
> When I first saw Andrei's paper it struck me that what made things painful 
> in
> C++ was the lack of usable closures. Since D is pretty good in this 
> regard,
> could the same effect have been achieved with a less sugary but more 
> regular
> approach reusing RAII-auto syntax, e.g.
>
> # import std.scopeguard;
> # auto Guard onOk = new OnScopeSuccessGuard(&mySuccessFunc);
> # auto Guard onFail = new OnScopeFailureGuard(function { /* ad hoc code 
> */ });
>
> with something like C++'s std::uncaught_exception in the Guard subclass
> destructor implementations to discriminate exit conditions?

I don't know a way to make that work as cleanly.
7 8 9 10 11 12 13 14 15
Top | Discussion index | About this forum | D home