[racket] finally via macro

From: Zack Galler (lzgaller at optonline.net)
Date: Wed Aug 10 18:28:25 EDT 2011

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

Followup to my earlier post.

 Here's an unhygenic macro to execute the finally idiom

> (finally (myerror 1) (myerror 2) (myerror 3)(myerror 4))


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))
      (let/cc ,k (set! ,out ,k) ,fn)
      ,@(map (lambda (f) `(let/cc ,k (set! ,out ,k) ,f)) fns)))))

Posted on the users mailing list.