tags:

views:

238

answers:

1

I am trying to execute a func several times before giving up upon exceptions. But it is not valid in Clojure to recur from catch block. How can this be achieved ?

(loop [tries 10]
  (try
    (might-throw-exception)
    (catch Exception e
      (when (pos? tries) (recur (dec tries))))))

java.lang.UnsupportedOperationException: Cannot recur from catch/finally

The best I could find is the following clumsy solution (wrapping in func and calling it)

(defn do-it []
  (try
    (might-throw-exception)
    (catch Exception e nil)))

(loop [times 10]
  (when (and (nil? (do-it)) (pos? times))
    (recur (dec times))))
+8  A: 
kotarak
This is a fine solution. I would add it to clojure.contrib or something.
bugspy.net
It's actually the same solution as the one the poster suggested. But macros make it easier to do in the general case. Macros are the killer feature of any lisp variant.
Jeremy Wall
It's not exactly the same solution. The poster's suggestion does not catch the return value of the block, and if it did the block wouldn't be able to return nil. Also the exceptions are swallowed. But you are right: it's basically the same idea. Macros just hide the boilerplate.
kotarak