[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.



> 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