Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I recur from a Clojure catch block in a more functional manner?

For an IRC bot I'm writing, I want to keep trying to open a socket, even if there's an UnkownHostException. My first thought was something like this.

(defn open-socket [{:keys [host port] :as connection}]
  (try (java.net.Socket. host port)
    (catch java.net.UnknownHostException _ (recur connection))))

But it doesn't work because you can't recur from a catch block. So instead I settled on something like this:

  (let [socket (promise)
        _ (while (not (realized? socket))
            (try (deliver socket (java.net.Socket. host port))
              (catch java.net.UnknownHostException _)))
        socket @socket]
    ...

And this works, but it's awfully imperative. Is there a more functional way I could be doing this that I can't see?

like image 582
mybuddymichael Avatar asked Jun 23 '13 05:06

mybuddymichael


1 Answers

Just add an or:

(defn open-socket [{:keys [host port] :as connection}]
  (or (try (java.net.Socket. host port)
           (catch java.net.UnknownHostException _ nil))
      (recur connection)))
like image 94
Ankur Avatar answered Nov 20 '22 18:11

Ankur