On Thu Mar 17 21:49 2011, Fiel Cabral wrote: > Hello Clojure users, > This is a dumb question but I'd like to write something equivalent to this > in Clojure: > > public String loop_with_exception(int retries) > { > for (int n = retries; n > 0; n--) { > try { > return some_io_operation(); > } catch (IOException e) { > continue; > } > } > return null; > } > > So I tried writing it like this: > > > (ns sandbox.core > (:import [java.io.IOException])) > > (defn some-io-operation > "Some read I/O operation that could throw an IOException." > [] > (println "WOULD do a read operation")) > > (defn loop-with-exception [retries] > (loop [n retries] > (try > (when (pos? n) > (some-io-operation)) > (catch IOException e > (recur (dec n)))))) > > What's the recommended way to handle exceptions and retry inside a > loop/recur?
Well, I'm not sure what's the best recommendation, but playing around with it a bit, it seems like moving the exception-handling into the IO method works best. Doing this, you can have different return values depending on whether the operation succeeded. Here's what I came up with: (defn some-io-operation "Some read I/O operation that may fail. Returns nil on failure, ::success on success." [] (try (when (zero? (rand-int 3)) (throw (IOException.))) ; return non-nil and non-false on success ::success (catch IOException e ; return nil on failure nil))) (defn loop-with-exception [retries] (first (remove nil? (repeatedly retries some-io-operation)))) I am not absolutely certain the loop-with-exception function is the best implementation, but I believe it works correctly. Sincerely, Daniel Solano Gómez
pgpzctxncuNQV.pgp
Description: PGP signature