Skip to content

Instantly share code, notes, and snippets.

@edw
Created September 24, 2012 12:04
Show Gist options
  • Select an option

  • Save edw/3775636 to your computer and use it in GitHub Desktop.

Select an option

Save edw/3775636 to your computer and use it in GitHub Desktop.
Threading macro, a variant of ->, with pre, post, and run conditions
;; MACRO -*>
;;
;; While writing Ring handlers and other sorts of code that take advantage of
;; the threading idiom, it is often useful to peer inside the values of a thread
;; of evaluation. A :run condition is introduced here, which is evaluated
;; (presumably for side effects) before each form. Due to the nature of the
;; threading idiom, you must specify an EXPR-SYM, which is the symbol which is
;; used in the run and pre condition forms to specify the incoming value of the
;; first parameter. Additional parameters are not accessible.
(defmacro -*> [[expr-sym conditions] expr & forms]
(let [run-forms (conditions :run [])
conditions (dissoc conditions :run)]
(reduce (fn [expr form]
(let [form
(cond (list? form)
`(~(first form) ~expr-sym ~@(rest form))
:else
`(~form ~expr-sym))]
`((fn [~expr-sym]
~conditions
~@run-forms
~form)
~expr)))
expr
forms)))
;; Example
(-*> [x {:run [(prn x)] :pre [(string? x)]}]
"foo"
(str "-bar")
upper-case
(str " mumble"))
;> "foo"
;> "foo-bar"
;> "FOO-BAR"
;= "FOO-BAR mumble"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment