I don\'t know how to implement this piece of Python code in Clojure
for i in range(3):
try:
......
except e:
if i == 2:
raise
Here's one approach:
(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)))
Example from the REPL:
user> (retry 2 (do (println :foo) (throw (RuntimeException. "foo"))))
:foo
:foo
:foo
; Evaluation aborted.
(Passing 2
to retry
asks expr
to be retried twice it if fails the first time round, for a total of three attempts. Three :foo
s are printed, because the println
occurs before the throw
in the do
form passed to retry
. The final ; Evaluation aborted.
means an exception was thrown.)
Also, about the for
loop from your snippet:
If you try looping over a longer range (replace (range 3)
with (range 10)
, say), the output will end after i
reaches 3
. Also, if you put in a println
before the form which throws the exception, it will of course print out whatever you pass to it; if the println
occurs after the exception-throwing form, there will be no printout. In any case, at most three calls to println
will be executed (assuming an exception is thrown on every iteration).