Skip to content

Instantly share code, notes, and snippets.

@hiredman
Created October 6, 2017 23:38
Show Gist options
  • Save hiredman/71b71e4e07e7666fe1b9def9a476c765 to your computer and use it in GitHub Desktop.
Save hiredman/71b71e4e07e7666fe1b9def9a476c765 to your computer and use it in GitHub Desktop.
(defn topo [graph]
(when-not (empty? graph)
(lazy-seq
(let [n (first (for [[node s] graph
:when (not (seq s))]
node))]
(assert n "if this fails there is a cycle")
(cons n (topo (into {} (for [[node deps] graph
:when (not= n node)]
[node (disj deps n)]))))))))
(defmacro f [args & body]
`(vary-meta (fn [{:keys ~args}] ~@body)
assoc :deps (quote ~(set args))))
(defn lrun [g]
(let [graph (zipmap (keys g)
(for [v (vals g)]
(set (map (comp keyword name) (:deps (meta v))))))
order (doall (topo graph))]
(reduce (fn [m k]
(let [f (get g k)
args (get graph k)]
(letfn [(build-maps [m [x & xs]]
(if (seq xs)
(for [i (get m x)
ii (build-maps (assoc m x i) xs)]
ii)
(for [i (get m x)]
(assoc m x i))))]
(if (seq args)
(assoc m k (map (if (fn? f) f (constantly f)) (build-maps m (seq args))))
(assoc m k ((if (fn? f) f (constantly f)) m))))))
{}
order)))
(lrun {:a (f [] (range 10))
:b (f [a a] (- a a))
:c (f [a] (inc a))
:d (f [b c]
(+ b c))})
;; {:d (1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10), :b (0 0 0 0 0 0 0 0 0 0), :c (1 2 3 4 5 6 7 8 9 10), :a (0 1 2 3 4 5 6 7 8 9)}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment