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

Re: Finally clauses



> Scheme already has a 'finally' in dynamic-wind.

Yup :-) I realised my mistake at about 3am on Sunday...

However I still think (finally) does something *slightly* different to
what is done by (dynamic-wind): where (dynamic-wind) executes its
third thunk on *any* throw past it, I'd expect (finally) to be
triggered by only either normal return, or exception-throw. That is,
the finally-clause gets installed *as an exception-handler*, not a
general unwinder. Perhaps (apologies for the untested, lowlevel
macro):

(define-macro (finally final-exp body . rest)
  (let ((exn (gensym))
	(result (gensym)))
    `(with-exception-handler
      (lambda (,exn)
	,final-exp
	(raise ,exn)) ; note[1]
      (lambda ()
	(let ((,result (begin
			 ,body
			 ,@rest)))
	  ,final-exp
	  ,result)))))

[1] I'm assuming here (I hope I read the SRFI correctly?) that (raise)
within an exception-handler chains to the next enclosing handler.

>   (define-syntax finally
>     (syntax-rules ()
>       ((finally final-exp body . rest)
>        (dynamic-wind (lambda () #f)
>                      (lambda () body . rest)
>                      (lambda () final-exp)))))

If someone is using call/cc to implement coroutines, or microthreads,
or what-have-you, this means that this
coroutine/thread/dynamic-context will give up its lock on each context
switch. What I was after was relinquishment of the lock when code
either returned normally, or threw an exception...

> The bottom line is that 'finally' is already there but it doesn't
> help as much as you would like.

Well, mostly because it's dynamic-wind, and dynamic-wind doesn't make
any distinctions between various kinds of throw.

Tony