Created
June 5, 2015 03:38
-
-
Save shofetim/065260ed22c1dc55f009 to your computer and use it in GitHub Desktop.
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
;; Story: | |
;; I have an EDN data structure from an external API | |
;; I extract several patterns of records from it. | |
;; I would like to treat the patterns as data, pass them around, modify them etc. | |
(def sample-data {:tracks {:items [1 2 3 4 5]}}) | |
(def pattern [:tracks :items count]) | |
;; Thread first -> should be what I need, but I need to "apply" it... | |
(apply -> (cons sample-data pattern)) ;; Can't take value of a macro: #'clojure.core/-> | |
;; So make a new macro that reuses -> | |
(defmacro get->> [data pattern] | |
`(-> ~data ~@pattern)) | |
(macroexpand-1 '(get->> sample-data pattern)) | |
;; Don't know how to create ISeq from: clojure.lang.Symbol |
This works, though:
(defn get->> [data pattern]
(reduce (fn [a f] (f a)) data pattern))
so don't even need a macro! I imagine there could be similar versions for thread-last vs thread-first.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See this: http://stackoverflow.com/questions/5277451/clojure-macro-puzzle-expanding-sequence-in-macro-args
Basically, macro-expansion doesn't have access to the run-time environment, so can't expand
pattern
which is defined in thedef
.works, but:
(get->> sample-data pattern)
won't.
All the macro can see when it's expanding is a symbol
'pattern
because macro args aren't expanded, so the contents of it just isn't there. In effect, we (I'm tolstoy on IRC) were trying to~@symbol
that wasn't anything but a symbol.