Skip to content

Instantly share code, notes, and snippets.

@jjl

jjl/blah.clj Secret

Last active May 10, 2016 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jjl/d92dc6f7675cd23d0f1c870e72443f8f to your computer and use it in GitHub Desktop.
Save jjl/d92dc6f7675cd23d0f1c870e72443f8f to your computer and use it in GitHub Desktop.
(defmacro state->
"[macro] Threads state through functions
args: [init & clauses]
init is the initial state value
clauses look like -> clauses, either functions or lists.
like ->, we insert the state into the second position
returns: [final-state returns]
returns is a vector of the return values in order of threading"
[init & clauses]
(if (seq clauses)
(let [sym `state#
form (fn [f]
(cond (list? f) `(~(first f) ~sym ~@(rest f))
(fny? f) (list f sym)
:else (throw (ex-info (str "Don't know what to do with " f) {:got f}))))
ns (repeatedly (count clauses) #(gensym "r"))
binds (map (fn [r] [sym r]) ns)
forms (map form clauses)
lets (interleave binds forms)]
(prn :sym sym :init init :lets lets :ns ns)
`(let [~sym init ~@lets]
[~sym [~@ns]]))
init))
(macroexpand-1 '(state-> 123 :a (:b 456) (:c 7 8 9) :d))
;; =>
(clojure.core/let [state__15418__auto__ postgrey.squirrel.util/init
[state__15418__auto__ r15432] (:a state__15418__auto__)
[state__15418__auto__ r15433] (:b state__15418__auto__ 456)
[state__15418__auto__ r15434] (:c state__15418__auto__ 7 8 9)
[state__15418__auto__ r15435] (:d state__15418__auto__)]
[state__15418__auto__ [r15432 r15433 r15434 r15435]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment