[racket] finally via macro
Sam Phillips <samdphillips at ...> writes:
>
> On Fri, Oct 8, 2010 at 4:40 PM, Jay McCarthy <jay.mccarthy at ...> 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)))))