Skip to content

Instantly share code, notes, and snippets.

@oranenj
Created February 2, 2009 13:13
Show Gist options
  • Save oranenj/56907 to your computer and use it in GitHub Desktop.
Save oranenj/56907 to your computer and use it in GitHub Desktop.
(defn ! [ag x & args]
(send ag (@ag :receive) x args))
(defn !! [ag x & args]
(send-off ag (@ag :receive) x args))
(defn ? [ag x & args]
(let [rf (ref nil)]
(send ag (@ag :receive) x (cons rf args))
(await ag)
@rf))
(defmacro actor [nam & body]
(let [_hm (gensym) _msg (gensym) _body (gensym) _ag (gensym) _st (gensym)
namrcvr (symbol (str nam "_receiver"))
hm (apply hash-map (interleave (map #(keyword (name (first %))) body)
(map #(cons 'fn (rest %)) body)))]
`(do
(def ~nam nil)
(let [~_hm ~hm]
(defn ~namrcvr [~_st ~_msg ~_body]
(apply (~_hm ~_msg) ~_st ~_body))
(let [~_ag (agent {:receive ~namrcvr})]
; (! ~_ag :init)
(def ~nam ~_ag))))))
(actor account
(init [st] (assoc st :balance 0))
(empty [st] (assoc st :balance 0))
(add [st n] (assoc st :balance (+ (:balance st) n)))
(check [st rf] (dosync (commute rf #(do % (:balance st)))) st))
(! account :init)
(! account :add 10)
(! account :add 10)
(println "your account:" (? account :check))
(actor counter
(init [st] (assoc st :n 0))
(inc [st]
(let [new (inc (:n st))]
(when (zero? (rem new 20))
(println "counter:" new))
(assoc st :n new)))
(status [st rf] (dosync (commute rf #(do % (:n st)))) st))
(! counter :init)
(! counter :inc)
(! counter :inc)
(println "counter:" (? counter :status))
(actor counter-tester
(init [st] st)
(once [st] (! counter :inc) st)
(please-stop [st] {:receive list})
(forever [st]
(! counter :inc)
(Thread/sleep 90)
(! counter-tester :forever)
st)
(go [st] (dorun (take 100 (repeatedly #(! counter :inc)))) st))
(! counter-tester :go)
(! counter-tester :go)
(println "counter:" (? counter :status))
(!! counter-tester :forever)
(do (println "Waiting...")
(Thread/sleep 4000)
(println "Stopping...")
(! counter-tester :please-stop))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment