[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Finally clauses

This page is part of the web mail archives of SRFI 34 from before July 7th, 2015. The new archives for SRFI 34 contain all messages, not just those from before July 7th, 2015.



> I don't understand why this makes any difference.  No matter
> how you get out, by a normal return, an exception throw, or
> some other throw, you can still throw back in.  An exception
> throw is no more 'final' than any other throw.

That's true. But "finally" isn't dealing with cleaning up on
stack-unwinding - it's dealing with cleaning up on exception-raising
(which doesn't involve any stack-unwinding at all, unless an
individual exception-handler procedure decides to do a throw to a
different dynamic environment).

Normal return, exception handlers, and finally clauses are all part of
normal, linear program execution. Other kinds of continuation-
manipulation are outside the model - not situations I would normally
have to worry about in day-to-day programming with exceptions. Anyone
throwing to a different dynamic environment, be it from within an
exception handler or from normal code, should already be familiar with
the consequences of doing so - finally clauses don't try to solve that
problem.

Say a hypothetical "finally" were implemented as an exception handler
that didn't care about the data passed in to it, which simply cleaned
up and passed the buck to its enclosing handler. This is quite
different from putting the cleanup code in the third arm of
dynamic-wind.

I can show the difference: putting the cleanup-code in an exception
handler is roughly equivalent to this sketch (where fluid-let is
implemented with dynamic-wind):

(let ((old-handler *current-handler*))
  (let ((result (fluid-let
		    ((*current-handler* (lambda (exn)
					  ...cleanup-code...
					  (old-handler exn))))
		  ...finally-body...)))
    ...cleanup-code...
    result))

Note that as the stack is wound and unwound, no actual cleanup-code is
executed - that's only done when an exception is thrown, or the code
returns normally. Compare it to this:

(dynamic-wind
    (lambda () 'dummy)
    (lambda () ...finally-body...)
    (lambda () ...cleanup-code...))

where every time the stack is unwound, the cleanup code is *run*.

The exception system as proposed doesn't require any continuation-
changing on raise - the current exception handler is a "procedure",
with no prescribed behaviour. The stack won't necessarily be unwound
when an exception is raised, so dynamic-wind isn't what I want. The
yucky macro I posted yesterday is pretty close to what I'm after,
though, I think.

Tony
-- 
(Your adaptable natural language driven multi media email interface
should now play the user definable sound effect you have elected to
hear whenever someone makes a gross understatement.)
	- Don Hopkins, http://www.art.net/~hopkins/Don/unix-haters/x-windows/i39l.html