more debugging...
[propagator.git] / propagator.org
blobac437fe8e5e3c51826e35797db2589331819be8c
1 #+TITLE: Concurrent Propagator System
2 #+OPTIONS: num:nil ^:nil
3 #+LaTeX_CLASS: normal
5 * code
6   :PROPERTIES:
7   :tangle:   src/propagator.clj
8   :END:
10 #+begin_src clojure
11   (ns
12       #^{:author "Eric Schulte",
13          :license "GPLV3",
14          :doc "Simple concurrent propagator system."}
15     propagator
16     (:use clojure.contrib.repl-utils
17           clojure.contrib.duck-streams))
18   
19   (defmacro cell "Define a new cell."
20     [name state]
21     `(def ~name (agent ~state)))
22   
23   (def que (ref '()))
24   
25   (defmacro propagator "Define a new propagator."
26     [name in-cells out-cells & body]
27     `(do
28        (defn ~(with-meta name
29                 (assoc (meta name)
30                   :in-cells in-cells :out-cells out-cells))
31          ~in-cells ~@body)
32        (doseq [cell# ~in-cells] (add-neighbor cell# ~name))
33        ~name))
34   
35   (defmacro run-propagator
36     "Run a propagator, first collect the most recent values from all
37   cells associated with the propagator, then evaluate."
38     [propagator]
39     `(let [output-val# (apply ~propagator (map deref (:in-cells ^#'~propagator)))
40            output-cells# (:out-cells ^#'~propagator)]
41        (append-spit "/home/eschulte/Desktop/spitoon"
42                     (format "results in %S\n" output-val#))
43        (append-spit "/home/eschulte/Desktop/spitoon"
44                     (format "sending to %S\n" output-cells#))
45        (dosync [cell# output-cells#]
46                (append-spit "/home/eschulte/Desktop/spitoon"
47                             (format "sending %S to %S\n" output-val# output-cells#))
48                (send cell# (fn [_#] output-val#)))))
49   
50   (defmacro add-neighbor "Add a neighbor to the given cell."
51     [cell neighbor]
52     `(add-watcher
53       ~cell :send
54       (agent nil :validator
55              (fn [_#] (dosync (run-propagator ~neighbor)) true))
56       (fn [_# _#])))
57 #+end_src
59 * notes
60 ** look at mutable data stores
61 - http://clojure.org/agents
62 - http://clojure.org/atoms
63 - http://clojure.org/refs
65 most definitely will use agents, functions to set their values are
66 applied to them with send (or send-off if potentially I/O bound), they
67 support validators, and they can be set to run actions (i.e. alert
68 propagators) as part of their update cycle.
70 ** design to permit distribution across multiple machines
71 it should be possible to wrap these mutable items including
72 - network connections from other machines
73 - hardware (timers, I/O devices, etc...)
75 in cells, so that the propagator system remains "pure"
77 ** ask for advice
78 This probably mentioned a request for advice from the mailing list or
79 from the #clojure group.