Skip to content

Instantly share code, notes, and snippets.

@fogus
Forked from cgrand/transmogrify.clj
Last active August 29, 2015 14:19
Show Gist options
  • Select an option

  • Save fogus/39269dc930c23b9437d8 to your computer and use it in GitHub Desktop.

Select an option

Save fogus/39269dc930c23b9437d8 to your computer and use it in GitHub Desktop.
(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