Skip to content

Instantly share code, notes, and snippets.

@eschulte
Created January 24, 2011 08:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eschulte/792968 to your computer and use it in GitHub Desktop.
Save eschulte/792968 to your computer and use it in GitHub Desktop.
simple propagator-backed spreadsheet -- see http://gitweb.adaptive.cs.unm.edu/propagator.git
(ns propagator.spreadsheet ; see http://gitweb.adaptive.cs.unm.edu/propagator.git
(use propagator))
(def xrange 10) (def yrange 10)
(def spreadsheet
(map (fn [_] (map (fn [_]
(let [c (gensym)] (eval `(defcell ~c nil)) c))
(range xrange)))
(range yrange)))
(defn spreadsheet-print []
(doseq [row spreadsheet]
(->> (map (comp deref eval) row)
(map #(if (nil? %) "[ ]" (format "[%5.2f]" (float %))))
(interpose " ")
(apply str)
(println))) (println))
(defn parse [exp]
(let [refs (transient [])]
(letfn [(parse [exp]
(cond
(vector? exp)
(let [[x y] exp
c (-> spreadsheet (nth x) (nth y))]
(conj! refs c) c)
(seq? exp)
(let [lst (map parse exp)] (dorun lst) lst)
true exp))]
[(parse exp) (set (persistent! refs))])))
(defn spreadsheet-set [[x y] v]
(if (seq? v)
(let [[e rs] (parse v)
out-cell (-> spreadsheet (nth y) (nth x))]
(eval `(defpropagator fm ~(vec rs) [~out-cell] ~e)))
(set-cell (eval (-> spreadsheet (nth y) (nth x))) v)))
(comment ; example usage
(spreadsheet-set [2 2] '(+ [1 1] [0 0])) ; a formula -- propagator
(spreadsheet-set [0 0] 2) ; an integer -- cell
(spreadsheet-set [1 1] 45) ; an integer -- cell
(spreadsheet-print))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment