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

Re: Finally clauses



   Date: Fri, 9 Aug 2002 15:10:56 +0100
   From: Tony Garnock-Jones <tonyg@xxxxxxxxxxxxxxx>

   Hi. One feature I find valuable in Java that I miss in C++ (and
   Scheme, for that matter) is the idea of a "finally" clause. Would
   srfi-34 be a sensible place to put one of these - either alongside the
   try clause, on its own, or bound up together with it, as perhaps
   try/finally?

Scheme already has a 'finally' in dynamic-wind.  In Java the
'finally' mechanism is combined with exception handling because
raising an exception is the only way to do a throw.  Scheme has
long had throws, via call-with-current-continuation, and in 
R5RS it got dynamic-wind as its version of 'finally'.  What it
doesn't have is exceptions.  With SRFI-34 exceptions and throws
are still separate.  You can raise an exception without doing a
throw, and do a throw without raising an exception.

	   (begin
	     (mutex-lock! m)
	     (finally (mutex-unlock! m)
	       (do-operation-requiring-lock)))

This 'finally' can be defined as:

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

Note that your example doesn't work well because someone can
use continuations to throw out of the lock-requiring operation
and then back in again.  You could fix this by doing

   (dynamic-wind (lambda () (mutex-lock! m))
                 (lambda () (do-operation-requiring-lock))
                 (lambda () (mutex-unlock! m)))

but your lock-requiring operation still only gets very weak
protection.  The lock only protects the sections that do not do
throws, and you don't need 'finally' for those parts.

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