Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Unwind-protect and exception handling

2 views
Skip to first unread message

Kelly Murray

unread,
Mar 18, 1999, 3:00:00 AM3/18/99
to
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

Barry Margolin

unread,
Mar 18, 1999, 3:00:00 AM3/18/99
to
In article <36F13E9F...@IntelliMarket.Com>,

Kelly Murray <k...@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, bar...@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.

Bruno Haible

unread,
Mar 18, 1999, 3:00:00 AM3/18/99
to
Kelly Murray <k...@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/


0 new messages