Skip to content

Instantly share code, notes, and snippets.

@fredyr
Last active February 3, 2017 00:52
Show Gist options
  • Save fredyr/6345191 to your computer and use it in GitHub Desktop.
Save fredyr/6345191 to your computer and use it in GitHub Desktop.
Haskell's MVars in Clojure
;; MCons Hack - https://gist.github.com/fredyr/6341286
;; Haskell MVars - http://chimera.labs.oreilly.com/books/1230000000929/ch07.html
;; http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html
defn empty-mvar []
(let [take-sem (java.util.concurrent.Semaphore. 1)
put-sem (java.util.concurrent.Semaphore. 1)]
(.acquire take-sem)
(mcons nil (mcons take-sem put-sem))))
(defn put-mvar [mvar val]
(let [take-sem (mcar (mcdr mvar))
put-sem (mcdr (mcdr mvar))]
(.acquire put-sem)
(set-mcar! mvar val)
(.release take-sem)))
(defn take-mvar [mvar]
(let [take-sem (mcar (mcdr mvar))
put-sem (mcdr (mcdr mvar))]
(.acquire take-sem)
(let [val (mcar mvar)]
(set-mcar! mvar nil)
(.release put-sem)
val)))
(defn new-mvar [val]
(let [mvar (empty-mvar)]
(put-mvar mvar val)
mvar))
;; Examples
(def m (empty-mvar))
(put-mvar m [:a :b])
(take-mvar m)
(let [[a b] (take-mvar m)] a)
(take-mvar (new-mvar {:cool "man"}))
(let [mvar (empty-mvar)]
(.start (Thread. #(do
(put-mvar mvar "x")
(put-mvar mvar "y"))))
(str
(take-mvar mvar)
(take-mvar mvar)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment