Skip to content

Instantly share code, notes, and snippets.

@kurogelee
Created April 4, 2014 13:19
Show Gist options
  • Save kurogelee/9974558 to your computer and use it in GitHub Desktop.
Save kurogelee/9974558 to your computer and use it in GitHub Desktop.
Clojureでオプションで場所指定可能なスレッディングマクロを作る ref: http://qiita.com/kurogelee/items/e23a205d6bc9cc26d0f2
(->> (range 10) (map -) (#(nth % 3)))
user=> (o>> 10 (range) reverse (map -) (nth <> 3) (identity {:a [1 <>]}))
{:a [1 -6]}
user=> (o> 10 (range) reverse (nth 3) (map - (range <>)))
(0 -1 -2 -3 -4 -5)
(defn cons-nth [index x coll]
(concat (take index coll) [x] (drop index coll)))
(defn cons-last [x coll]
(concat coll [x]))
(defn- find-symbol [form sym]
(cond (or (sequential? form) (set? form)) (some #(find-symbol % sym) form)
(map? form) (or (find-symbol (keys form) sym)
(find-symbol (vals form) sym))
:else (= form sym)))
(defmacro o> [x & forms]
(loop [x x forms forms]
(if-not forms x
(let [form (first forms)
threaded (if (seq? form)
(-> (if (find-symbol form '<>)
(list 'let ['<> x] form)
(cons-nth 1 x form))
(with-meta (meta form)))
(list form x))]
(recur threaded (next forms))))))
(defmacro o>> [x & forms]
(loop [x x forms forms]
(if-not forms x
(let [form (first forms)
threaded (if (seq? form)
(-> (if (find-symbol form '<>)
(list 'let ['<> x] form)
(cons-last x form))
(with-meta (meta form)))
(list form x))]
(recur threaded (next forms))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment