Skip to content

Instantly share code, notes, and snippets.

@visibletrap
Created June 1, 2017 01:51
Show Gist options
  • Save visibletrap/1aebaa4a04c6b1136ff2c3df609f3f77 to your computer and use it in GitHub Desktop.
Save visibletrap/1aebaa4a04c6b1136ff2c3df609f3f77 to your computer and use it in GitHub Desktop.
(defmacro condp->
"Takes an expression and a set of predicate/form pairs. Threads expr (via ->)
through each form for which the corresponding predicate is true of expr.
Note that, unlike cond branching, condp-> threading does not short circuit
after the first true test expression."
[expr & clauses]
(assert (even? (count clauses)))
(let [g (gensym)
pstep (fn [[pred step]] `(if (~pred ~g) (-> ~g ~step) ~g))]
`(let [~g ~expr
~@(interleave (repeat g) (map pstep (partition 2 clauses)))]
~g)))
(defmacro condp->>
"Takes an expression and a set of predicate/form pairs. Threads expr (via ->>)
through each form for which the corresponding predicate is true of expr.
Note that, unlike cond branching, condp->> threading does not short circuit
after the first true test expression."
[expr & clauses]
(assert (even? (count clauses)))
(let [g (gensym)
pstep (fn [[pred step]] `(if (~pred ~g) (->> ~g ~step) ~g))]
`(let [~g ~expr
~@(interleave (repeat g) (map pstep (partition 2 clauses)))]
~g)))
(defn flip
"Like partial except you supply everything but the first argument.
Also like Haskell's flip for single arity call."
([f] (fn [b a] (f a b)))
([f b] (fn [a] (f a b)))
([f b c] (fn [a] (f a b c)))
([f b c d & more]
(fn [a] (apply f a b c d more))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment