From: Kelly Murray
Subject: Unwind-protect and exception handling
Date: 
Message-ID: <36F13E9F.3574B947@IntelliMarket.Com>
Having spent a lot of time "bullet-proofing" code recently,
it seems to me unwind-protect could use some help,
or perhaps could be rolled into exception handling?

Generally, my useage always seems to require knowing whether
the protected form completed or not, which requires a variable:

(let aborted = t
  do
  (unwind-protect
     (progn
       (do-something)
       (set aborted = nil)
       )
   (if aborted
     then ...
     else ...)
   )         
   
Sure, one could write a macro to encapsulate the above pattern
(which I might argue should be the documented interface)
but the concern is the call to (do-something) can in fact return
but the variable not be set to nil, because there is some time
between the two forms. Thus, it seems that the processing
of the unwind-protect itself is where it will know if the
protected form was completed or not, and thus the low-level
implementation is where the variable should be set, not in user code.
In particular, interrupt handling can naturally occur on
function call/return, so using the above structure, on the return
from (do-something) is a natural break for an interrupt.

This leads me to wonder if in fact using some type of exception
handling is in fact more appropriate than unwind-protect,
and if so, then perhaps unwind-protect is obsolete,
and could just be implemented as a macro that uses exception 
handling.  

(with-handlers
 (timeout ...)  ;; only executed if the body times out or errors,
 (error ...) 
 do
 (do-something)
 )


-Kelly Murray

From: Barry Margolin
Subject: Re: Unwind-protect and exception handling
Date: 
Message-ID: <6BbI2.326$p4.116294@burlma1-snr2>
In article <·················@IntelliMarket.Com>,
Kelly Murray  <···@IntelliMarket.Com> wrote:
>Having spent a lot of time "bullet-proofing" code recently,
>it seems to me unwind-protect could use some help,
>or perhaps could be rolled into exception handling?
>
>Generally, my useage always seems to require knowing whether
>the protected form completed or not, which requires a variable:

Symbolic Common Lisp has a macro for this.  I think it was something like:

(unwind-protect-case
  <form>
  (:if-success <forms>)
  (:if-fails <forms>)
  (:always <forms>))

The :if-success forms are executed if <form> runs to completion, :if-fails
if it doesn't, and :always are always executed.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Bruno Haible
Subject: Re: Unwind-protect and exception handling
Date: 
Message-ID: <7crnro$a5v$1@news.u-bordeaux.fr>
Kelly Murray <···@IntelliMarket.Com> writes:

> This leads me to wonder if in fact using some type of exception
> handling is in fact more appropriate than unwind-protect,
> and if so, then perhaps unwind-protect is obsolete,
> and could just be implemented as a macro that uses exception 
> handling.

Which kind of exceptions are you trying to protect against?
Asynchronous exceptions (like some Unix signals), or synchronous
exceptions (a.k.a. "conditions") ?

If you want your program to terminate some computation and
unwind the stack when it receives a _asynchronous_ exception,
you cannot do that by having the exception handler itself unwind
the stack. This simply will never be bullet-proof. Some
objects can always be left in an inconsistent state. (This
is also the reason why Java2 deprecates the function `Thread.stop').

Reacting safely on an asynchronous exception typically involves
a variable, which can be atomically set by the exception handler
when the exception occurred, and which is polled by the computation.
This way, an asynchronous exception is essentially transformed
into a synchronous one.

For _synchronous_ exceptions, on the other hand, `unwind-protect'
is perfectly appropriate.

> (let ((aborted t))
>   (unwind-protect
>       (progn
>         (do-something)
>         (setq aborted nil)
>       )
>     (if aborted
>       (...)
>       (...)
>     )
> ) )

This is a fairly common idiom, and yes, a macro that encapsulates
it would be fine. And this is bullet-proof against synchronous
conditions, because between the return from `(do-something)' and
the following assignment, no exception can happen.

                  Bruno                          http://clisp.cons.org/~haible/