:
(defmacro retry
"Evaluates expr up to cnt + 1 times, retrying if an exception
is thrown. If an exception is thrown on the final attempt, it
is allowed to bubble up."
[cnt expr]
(letfn [(go [cnt]
(if (zero? cnt)
expr
`(try ~expr
(catch Exception e
(retry ~(dec cnt) ~expr)))))]
(go cnt)))
REPL:
user> (retry 2 (do (println :foo) (throw (RuntimeException. "foo"))))
:foo
:foo
:foo
; Evaluation aborted.
( 2 retry expr , , . :foo , println throw do, retry. ; Evaluation aborted. , .)
, for :
( (range 3) (range 10), ), , i 3. , println , , , , , ; println , . println ( , ).