Hi Everybody,
 I just wrote a simple macro to tame the run-away loop-recur infinite
loops. Some of you may find use for it. It only handles loop-recur pairs
not fn-recur combination. It is trivial but useful .. so thought of sharing.

(defmacro limit [max-recurs loop-expr]
  (let [[_ bindings & body] loop-expr
        counter (gensym)
        transformer (fn transformer [form]
                      (if-not (seq? form) form
                              (let [[op & operands :as form] form]
                                (cond
                                 (= op 'loop) `(limit ~max-recurs ~form)
                                 (= op 'recur) `(recur ~@(conj (vec
operands) `(inc ~counter)))
                                 :default (clojure.walk/walk transformer
identity form)))))]
    `(loop ~(into bindings [counter 0])
       (if (> ~counter ~max-recurs) (throw (Exception. "loop limit
exceeded"))
           (do ~@(clojure.walk/walk transformer identity body))))))

usage :

(limit 1000 (loop [a 10]
                (if (= (mod (rand-int 100) 5) 0) (recur (inc a))
                    (if (= (mod (rand-int 100) 5) 0) (recur (dec a))
                        (if (= (mod (rand-int 100) 5) 0) (recur (inc a))
                            (loop [x a y (* a a)]
                              (if (> x 100) (+ x y)
                                  (recur (dec x) (inc y)))))))))

the above sexp will macro-expand to a form where none of the loop-recur
combination can recurse for more than 1000 iterations.

Merry Christmas and Happy New Year!!
Sunil.

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to