Skip to content

Instantly share code, notes, and snippets.

@kendagriff
Last active September 9, 2015 14:31
Show Gist options
  • Save kendagriff/b39d28e2179cf56d8234 to your computer and use it in GitHub Desktop.
Save kendagriff/b39d28e2179cf56d8234 to your computer and use it in GitHub Desktop.
while->
(defmacro while->
"As long as the predicate holds true, threads
the expr through each form (via `->`). Once pred returns
false, the current value of all forms is returned."
[pred expr & forms]
(let [g (gensym)
pstep (fn [step] `(if (~pred ~g) (-> ~g ~step) ~g))]
`(let [~g ~expr
~@(interleave (repeat g) (map pstep forms))]
~g)))
(defn valid? [v]
(not (contains? v :errors)))
(while-> valid?
{:hello "world"}
(assoc :errors "my errors")
(assoc :and "goodbye"))
;; => {:hello "world", :errors "my errors"}
(while-> valid?
{:hello "world"}
(assoc :and "goodbye"))
;; => {:hello "world" :and "goodbye"}
@eraserhd
Copy link

eraserhd commented Sep 2, 2015

Interesting. This seems like a generalization of some->, but that fact doesn't seem useful.

You'll want to gensym and let-bind pred because it could be a computed value.

@kendagriff
Copy link
Author

Ah, good point. I'll make that change...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment