I understand using call-with-exception-handler/with-handlers/etc. to
catch exceptions in a block of code, but I'm at a loss to what the best
way to do a "finally" or cleanup action after a block of code. My
intuition is to use dynamic-wind, but I figure there may be a better way
that I just cannot locate in the manual.
Is there a way to do this that I just cannot find?
Cheers,
Sam
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users
Jay
--
Jay McCarthy <j...@cs.byu.edu>
Assistant Professor / Brigham Young University
http://teammccarthy.org/jay
"The glory of God is Intelligence" - D&C 93
The documentation could warn about what this restricts.
I feel bad every time I use "dynamic-wind" to approximate
"unwind-protect", pretending that I don't have first-order
continuations. But often I'm cleaning up one-shot external resources
anyway. "unwind-protect" would be more explicit about the assumptions
than "dynamic-wind" would, and incidentally would be tidier in the code.
Jay McCarthy wrote at 10/08/2010 07:40 PM:
> I use dynamic-wind for this. If there is something better, I don't know what it is. dynamic-wind is a little bit funny though because if you capture continuations then the in/out handlers can run multiple times which might defy your expectations. You could set up a continuation barrier on the inside to ensure that doesn't happen though.
>
>
--
http://www.neilvandyke.org/
Robby
This is pretty much what I was afraid of with using dynamic-wind.
>
> Hi All,
>
> I understand using call-with-exception-handler/with-handlers/etc. to
> catch exceptions in a block of code, but I'm at a loss to what the best
> way to do a "finally" or cleanup action after a block of code. My
> intuition is to use dynamic-wind, but I figure there may be a better way
> that I just cannot locate in the manual.
>
> Is there a way to do this that I just cannot find?
>
> Cheers,
> Sam
>
Sam
Here's an implementation of the finally idiom.
Each line obtains the current continuation, stores it in 'out', then executes
buggy code implemented as (myerror n)
The handler-expression then invokes the continuation to continue evaluating the
remaining lines.
R./
Zack
define (myerror n)
(raise (exn:fail (format "threw error ~A\n" n) (current-continuation-marks))))
(let ((out #f))
(with-handlers ([exn:fail? (lambda (exn) (printf "~A\n" (exn-message exn))
(out))])
(let/cc k (set! out k) (myerror 1))
(let/cc k (set! out k) (myerror 2))
(let/cc k (set! out k) (myerror 3))
(let/cc k (set! out k) (myerror 4))
(let/cc k (set! out k) (myerror 5))))
output:
threw error 1
threw error 2
threw error 3
threw error 4
threw error 5
>
> On Fri, Oct 8, 2010 at 4:40 PM, Jay McCarthy <jay.mccarthy@...> wrote:
> > I use dynamic-wind for this. If there is something better, I don't
> > know what it is. dynamic-wind is a little bit funny though because if
> > you capture continuations then the in/out handlers can run multiple
> > times which might defy your expectations. You could set up a
> > continuation barrier on the inside to ensure that doesn't happen
> > though.
>
> This is pretty much what I was afraid of with using dynamic-wind.
>
> Cheers,
> Sam
>
Sam,
Followup to my earlier post.
Here's an unhygenic macro to execute the finally idiom
> (finally (myerror 1) (myerror 2) (myerror 3)(myerror 4))
output
threw error 1
threw error 2
threw error 3
threw error 4
=========================================================================
(require mzlib/defmacro)
(define-macro (finally . (fn . fns))
(let ((out (gensym))
(k (gensym)))
`(let* ((,out #f))
(with-handlers ([exn:fail? (lambda (exn) (printf "~A\n" (exn-message exn))
(,out))])
(let/cc ,k (set! ,out ,k) ,fn)
,@(map (lambda (f) `(let/cc ,k (set! ,out ,k) ,f)) fns)))))
You can certainly use "dynamic-wind" to approximate what Java people
think of as "finally", and that's what I usually do on a day-to-day
basis. But when we have the luxury of getting even smarter over
lunchtime, we can do things like read Dorai Sitaram's survey:
http://repository.readscheme.org/ftp/papers/sw2003/Unwind.pdf
--
http://www.neilvandyke.org/