dynamic-wind
dynamic-wind is how parameterize, with-exception-handler, and port-closing helpers stay correct in the presence of call/cc. Re-entering a continuation runs BEFORE again.
;; (dynamic-wind before thunk after): BEFORE runs whenever control enters THUNK's dynamic extent,
;; AFTER runs whenever control leaves it, including via continuations and exceptions.
(dynamic-wind
(lambda () (display "[enter]"))
(lambda () (display "body") 'result)
(lambda () (display "[exit]"))) ; prints [enter]body[exit], returns result
;; Leaving via a continuation still runs AFTER
(call/cc
(lambda (k)
(dynamic-wind
(lambda () (display "acquire "))
(lambda () (k 'escaped) (display "never printed"))
(lambda () (display "release "))))) ; prints "acquire release ", returns escaped
;; Resource management helper
(define (call-with-resource open close proc)
(let ((r #f))
(dynamic-wind
(lambda () (set! r (open)))
(lambda () (proc r))
(lambda () (close r) (set! r #f)))))