restarts

157 views
Skip to first unread message

Christopher Howard

unread,
Jun 19, 2014, 12:25:04 PM6/19/14
to clojure
Does Clojure have restarts or continuable-errors like in CL? Or
something similiar? If not, is that something that could be
implemented some how?

Michael Griffiths

unread,
Jun 19, 2014, 12:33:24 PM6/19/14
to clo...@googlegroups.com
You may be interested in ribol:


I've not had a chance to play with it myself.

Thomas Heller

unread,
Jun 19, 2014, 5:05:07 PM6/19/14
to clo...@googlegroups.com
Excuse my ignorance of not knowing anything about CL and restarts but I needed something like retry a while back.

I started with something like this

(defn do-something-that-might-fail []
  (let [v (rand)]
    (prn  [:v v])
    (when (> v 0.1)
      (throw (ex-info "boom" {})))
    v))

(loop [attempts 1]
  (let [[ok? result] (try
                       [true (do-something-that-might-fail)]
                       (catch Exception e
                         [false e]))]
    (cond
     ok?
     result

     (= attempts 3)
     (throw (ex-info "failed after 3 tries" {} result))

     :else
     (do (prn :retry)
         (recur (inc attempts)))))) 


You don't want to catch all Exceptions, only the ones that you actually are recoverable (eg. SocketTimeoutException). My example isn't pretty, but a macro should clean it up nicely. I eventually went with a slightly different solution but the essence remains the same: wrap it in a loop.

Maybe this helps.

Stefan Kamphausen

unread,
Jun 20, 2014, 3:04:22 AM6/20/14
to clo...@googlegroups.com
On Thursday, June 19, 2014 11:05:07 PM UTC+2, Thomas Heller wrote:
Excuse my ignorance of not knowing anything about CL and restarts but I needed something like retry a while back.
 
Restarts in CL are a different beast.  Take a look at e.g. http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html

Best,
stefan

Thomas Heller

unread,
Jun 20, 2014, 5:20:00 AM6/20/14
to clo...@googlegroups.com
Don't want to get into a debate about whether something is a good idea or not, but that "beast" seems to go against clojures "data-all-the-things". In their example, you'd move a side effect into an otherwise "pure" function of taking text and turning it into data.

Maybe a little different solution, that uses data instead of throw

(defrecord LogEntry [valid? data error])

(defn parse-log-entry [text]
  (if (looks-good? text)
    (->LogEntry true (actually-parse text) nil)
    (->LogEntry false nil (turn-into-error-message text))))

(defn explode-on-invalid-entries! [log]
  (let [errors (->> log
                    (remove :valid?)
                    (map :error)
                    (doall))]
    (when (seq errors)
      (throw (ex-info "parse failed with invalid entries" {:errors errors})))
    log))

(defn parse-log [log]
  (->> (line-seq log)
       (map parse-log-entry)
       ;; remove invalid entries
       (filter :valid?)
       (map :data)
       ;; or (replace invalid values with default)
       (map (fn [{:keys [valid? data] :as it}]
              (if valid? data default-data)))
       ;; or bail
       (explode-on-invalid-entries!)
       ))

Just let parse-log-entry return whether the entry was ok or not. So we can handle it outside. Might just return nil on invalid entries, but that loses information. Avoid Exceptions whereever possible.

But again, I know nothing about CL so it might be a good idea to use restarts. IMHO its not a good idea in clojure, especially coupled with lazy-seqs.

But we are getting off-topic ...

Regards,
/thomas


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/lfWhAagj1-Q/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages