;;;; A handler-bind clause that signals the condition it is handling. ;;;; ;;;; While a clause runs, the handlers in force are the ones that were in force ;;;; when its handler-bind was established (CLHS 9.1.4.1). So the inner clause's ;;;; own bad index reaches the *outer* clause, once, and not the inner one ;;;; again — which used to recurse until the stack ran out. ;;;; ;;;; The second half is the other order: after the inner clause has run and ;;;; declined, the handler it belongs to is in force again for the next signal. (defonce hits i64) (def grid [4 i32] [1 2 3 4]) (defn bad [i i32] i32 (at grid i)) (defn nested [] i64 (restart-case (handler-bind [(BoundsError [c] (set hits (+ hits 100)) (invoke-restart 'outer))] (restart-case (handler-bind [(BoundsError [c] (set hits (+ hits 1)) (bad 9) (invoke-restart 'inner))] (bad 7)) (inner [] 0))) (outer [] 0)) hits) (defn again [] i64 (set hits 0) (restart-case (handler-bind [(BoundsError [c] (set hits (+ hits 1)) (invoke-restart 'out))] (handler-bind [(BoundsError [c] (set hits (+ hits 10)))] (bad 5) 0)) (out [] 0)) (restart-case (handler-bind [(BoundsError [c] (set hits (+ hits 1000)) (invoke-restart 'out))] (bad 6)) (out [] 0)) hits) (defn main [] i32 (println (nested)) (println (again)) 0)