Finally clauses Tony Garnock-Jones (09 Aug 2002 14:05 UTC)
Re: Finally clauses Dave Mason (09 Aug 2002 14:58 UTC)
Re: Finally clauses Richard Kelsey (09 Aug 2002 23:28 UTC)
Re: Finally clauses Tony Garnock-Jones (12 Aug 2002 11:24 UTC)
Re: Finally clauses Richard Kelsey (13 Aug 2002 00:48 UTC)
Re: Finally clauses Tony Garnock-Jones (13 Aug 2002 17:35 UTC)
Re: Finally clauses Richard Kelsey (15 Aug 2002 01:47 UTC)
Re: Finally clauses Tony Garnock-Jones (15 Aug 2002 11:11 UTC)
Re: Finally clauses bear (15 Aug 2002 15:19 UTC)
Re: Finally clauses sperber@xxxxxx (29 Aug 2002 08:08 UTC)
Re: Finally clauses bear (01 Sep 2002 20:55 UTC)
Re: Finally clauses Richard Kelsey (01 Sep 2002 22:22 UTC)
Re: Finally clauses bear (04 Sep 2002 03:07 UTC)
Re: Finally clauses Richard Kelsey (04 Sep 2002 06:55 UTC)

Re: Finally clauses Tony Garnock-Jones 13 Aug 2002 17:40 UTC

> 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