Created
September 24, 2012 12:04
-
-
Save edw/3775636 to your computer and use it in GitHub Desktop.
Threading macro, a variant of ->, with pre, post, and run conditions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; 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