Last active
August 29, 2015 14:18
-
-
Save cgrand/4b59a09345df203fba4c to your computer and use it in GitHub Desktop.
transmogrify->> rewrites last-threaded forms to use transducers.
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
(defmulti transmogrify | |
"Rewrites the last form of a thread-last to use transducer (if possible)." | |
(fn [f xform src & args] f)) | |
(defmacro transmogrify->> | |
"Like ->> but uses transducers" | |
([x] x) | |
([src & xs] | |
(let [end (last xs) | |
xforms (butlast xs) | |
xform `(comp ~@xforms) | |
[f & args] (if (seq? end) end (list end)) | |
f (or (and (symbol? f) (not (contains? &env f)) | |
(when-some [{fname :name fns :ns} (meta (resolve f))] | |
(symbol (name (ns-name fns)) (name fname)))) | |
f)] | |
(apply transmogrify f xform src args)))) | |
(defmethod transmogrify :default | |
; fingers crossed | |
[f xform src & args] | |
`(sequence (comp ~xform (~f ~@args)) ~src)) | |
(defn first-as-init [f] | |
(let [vf (volatile! nil)] | |
(vreset! vf | |
(fn | |
([_] (f)) | |
([_ x] | |
(vreset! vf (completing f)) | |
x))) | |
(fn | |
([acc] (@vf acc)) | |
([acc x] (@vf acc x))))) | |
(defmethod transmogrify `reduce | |
([_ xform src f] | |
`(transduce ~xform (first-as-init ~f) nil ~src)) | |
([_ xform src f init] | |
`(transduce ~xform ~f ~init ~src))) | |
(defmethod transmogrify `into | |
[_ xform src dest] | |
`(into ~dest ~xform ~src)) | |
(defmethod transmogrify `sequence | |
[_ xform src] | |
`(sequence ~xform ~src)) | |
(defmethod transmogrify `seq | |
[_ xform src] | |
`(seq (sequence ~xform ~src))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment