[plt-scheme] finally
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))