Skip to content

Instantly share code, notes, and snippets.

@visibletrap
Last active June 2, 2017 10:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save visibletrap/723ab9ed469264762b9b1d561a63ddc2 to your computer and use it in GitHub Desktop.
Save visibletrap/723ab9ed469264762b9b1d561a63ddc2 to your computer and use it in GitHub Desktop.
Thanks to @seancorfield: "We wrote our own `condp->` and `condp->>` macros that thread through the predicate as well as the expression." -- https://clojurians-log.clojureverse.org/clojure/2017-06-01.html#inst-2017-06-01T04:38:05.966147Z
(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