[plt-scheme] finally

From: Dave Herman (dherman at ccs.neu.edu)
Date: Tue Dec 20 00:05:05 EST 2005

Just for fun, here's a little Java-like "try-catch-finally" facility. 
Warning: utterly untested.

;; Example:

   (try (begin (printf "hi")
               (printf " there")
               (printf ", world")
               (newline)
               (error 'blah))
     (catch ([exn? (lambda (exn) 3)]))
     (finally (printf "<finally>~n")))

;; --

(module try mzscheme

   (define-for-syntax (literal sym)
     (lambda (stx-obj)
       (eq? (syntax-object->datum stx-obj) sym)))

   (define-for-syntax finally? (literal 'finally))

   (define-for-syntax catch? (literal 'catch))

   (define-for-syntax (catch-clause? stx)
     (syntax-case stx ()
       [(catch . _)
        (catch? #'catch)
        #t]
       [_ #f]))

   (define-for-syntax (finally-clause? stx)
     (syntax-case stx ()
       [(finally . _)
        (finally? #'finally)
        #t]
       [_ #f]))

   (define-syntax catch
     (syntax-rules ()
       [(_ (c ([pred handler] ...)) e)
        (with-handlers ([pred handler] ...) e)]))

   (define-syntax finally
     (syntax-rules ()
       [(_ (f f-e0 f-e1 ...) e)
        (dynamic-wind void
                      (lambda () e)
                      (lambda () f-e0 f-e1 ...))]))

   (define-syntax (try stx)
     (syntax-case stx ()
       [(_ e c f)
        (and (catch-clause? #'c) (finally-clause? #'f))
        #'(finally f (catch c e))]
       [(_ e c)
        (catch-clause? #'c)
        #'(catch c e)]
       [(_ e f)
        (finally-clause? #'f)
        #'(finally f e)]))

   (provide try))


Posted on the users mailing list.