Skip to content

Instantly share code, notes, and snippets.

@hiredman
Last active January 11, 2021 20:35
Show Gist options
  • Save hiredman/075b45eaeb01e4b526ce6f8854685487 to your computer and use it in GitHub Desktop.
Save hiredman/075b45eaeb01e4b526ce6f8854685487 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 (dissoc deps n)]))))))))
(assert (= (topo {:a {:b :b :c :c} :b {:c :c} :c {} :d {:b :b :a :a}})
[:c :b :a :d]))
(defn run [transform deps env fun & args]
(reduce
(fn [env k]
(assoc env k (apply fun
(into (get env k)
(for [[k v] (get deps k)]
[v (get env k)]))
args)))
env
(transform (topo deps))))
(defn run-up [deps env fun & args]
(apply run identity deps env fun args))
(defn run-down [deps env fun & args]
(apply run reverse deps env fun args))
;; (defn printer [name]
;; {:start (fn [this]
;; (println "starting" name)
;; this)
;; :stop (fn [this]
;; (println "stopping" name)
;; this)})
;; (def env {:A (printer :a)
;; :B (printer :b)
;; :C (printer :c)
;; :D (printer :d)})
;; (def deps {:A {}
;; :B {}
;; :C {:A :x
;; :B :y}
;; :D {:B :b}})
;; (run-down
;; deps
;; (run-up deps env (fn [m]
;; ((:start m) m)))
;; (fn [m]
;; ((:stop m) m)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment