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

Attachment: pgpzctxncuNQV.pgp
Description: PGP signature

Reply via email to