Skip to content

Instantly share code, notes, and snippets.

@cgrand
Last active August 29, 2015 14:18
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cgrand/4b59a09345df203fba4c to your computer and use it in GitHub Desktop.
Save cgrand/4b59a09345df203fba4c to your computer and use it in GitHub Desktop.
transmogrify->> rewrites last-threaded forms to use transducers.
(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