Meikel  Brandmeyer avatar Meikel Brandmeyer committed 70b6a87

Extract generate from let-gen

Comments (0)

Files changed (1)

src/main/clojure/clojurecheck/core.clj

   *retries*
   2000)
 
+(defn generate
+  "Takes a spinning generator and runs it until it returns a value
+  or the retry count is exceeded. A spinning generator indicates
+  a value by returning a vector consisting of the keyword :value
+  and the actual value. It indicates the request for a retry by
+  returning a vector containing the keyword :retry."
+  {:added "2.1"}
+  [generator size]
+  (loop [n *retries*]
+    (if-not (zero? n)
+      (let [[result value] (generator size)]
+        (if (= result :retry)
+          (recur (dec n))
+          value))
+      (throw (Exception. (str "Retries exhausted (" *retries* " attempts)"))))))
+
 (defmacro let-gen
   "Takes a vector of let-like bindings. let-gen returns itself
   a generator. When called it evaluates the generators on the
         emit-l (fn [bindings body]
                  `(let ~bindings
                     ~body))]
-    `(fn [~size]
-       (loop [n# *retries*]
-         (if-not (zero? n#)
-           (let [[result# value#]
-                 ~(reduce
-                    (fn [body [v t :as bs]]
-                      (case t
-                        :when (emit-p v body)
-                        :let  (emit-l v body)
-                        (emit-g [t v] body)))
-                    `[:value (do ~@body)]
-                    (partition 2 (rseq bindings)))]
-             (if (= result# :retry)
-               (recur (dec n#))
-               value#))
-           (throw
-             (Exception.
-               (str "Retries exhausted (" *retries* " attempts)"))))))))
+    `(let [generator# (fn [~size]
+                        ~(reduce
+                           (fn [body [v t :as bs]]
+                             (case t
+                               :when (emit-p v body)
+                               :let  (emit-l v body)
+                               (emit-g [t v] body)))
+                           `[:value (do ~@body)]
+                           (partition 2 (rseq bindings))))]
+       (fn [size#]
+         (generate generator# size#)))))
 
 (defn list
   "Generates a list based on the given generator. The length of
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.