Skip to content

Instantly share code, notes, and snippets.

@zerokarmaleft
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zerokarmaleft/5fd329479e476911e207 to your computer and use it in GitHub Desktop.
Save zerokarmaleft/5fd329479e476911e207 to your computer and use it in GitHub Desktop.
"X1. A drinks dispenser has two buttons labelled ORANGE and
LEMON. The actions of pressing the two buttons are /set-orange/ and
/set-lemon/. The actions of dispensing a drink are /orange/ and
/lemon/. The choice of drink that will be dispensed is made by
pressing the corresponding button. Before any button is pressed, no
drink will be dispensed."
(declare orange lemon)
(def c (chan))
(defn orange []
(println "Dispenser is set to orange")
(go
;; An orange drink is taken from the dispenser or
;; the dispenser's setting is changed
(let [[v p] (alts! [[c :orange] c])]
(condp = v
:set-lemon #(lemon)
:set-orange #(orange)
#(orange)))))
(defn lemon []
(println "Dispenser is set to lemon")
(go
;; A lemon drink is taken from the dispenser or
;; the dispenser's setting is changed
(let [[v p] (alts! [[c :lemon] c])]
(condp = v
:set-orange #(orange)
:set-lemon #(lemon)
#(lemon)))))
(defn drink-dispenser []
(println "Starting drink dispenser")
(go
(let [x (<! c)]
(condp = x
:set-orange (trampoline orange)
:set-lemon (trampoline lemon)))))
(drink-dispenser)
;; => Starting drink dispenser
(go (>! c :set-orange))
;; => Dispenser is set to orange
(go (println "Retrieving:" (<! c)))
;; this expression parks waiting for a `>!`
;; but `orange` is parked at `alts!` waiting to see if `(>! c :orange)` succeeds
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment