Skip to content

Instantly share code, notes, and snippets.

@pervognsen
Created March 22, 2010 06:09
Show Gist options
  • Save pervognsen/339834 to your computer and use it in GitHub Desktop.
Save pervognsen/339834 to your computer and use it in GitHub Desktop.
;; core.clj
(deftype Promise [d v]
clojure.lang.IDeref
(deref
[]
(.await d)
@v)
clojure.lang.IFn
(invoke
[x]
(locking d
(when (zero? (.getCount d))
(throw (IllegalStateException. "Multiple deliver calls to a promise")))
(reset! v x)
(.countDown d)
x)))
(defn promise?
[p]
(isa? (type p) ::Promise))
(defn promise-delivered?
[p]
(zero? (.getCount (:d p))))
(defmethod print-method ::Promise
[writer p]
((get-method print-method clojure.lang.IDeref) writer p))
(defn promise
"Alpha - subject to change.
Returns a promise object that can be read with deref/@, and set,
once only, with deliver. Calls to deref/@ prior to delivery will
block. All subsequent derefs will return the same delivered value
without blocking."
[]
(Promise (java.util.concurrent.CountDownLatch. 1) (atom nil)))
;; core_print.clj
(declare promise? promise-delivered?)
(defmethod print-method clojure.lang.IDeref [o #^Writer w]
(print-sequential (format "#<%s@%x%s: "
(.getSimpleName (class o))
(System/identityHashCode o)
(if (and (instance? clojure.lang.Agent o)
(agent-error o))
" FAILED"
""))
pr-on, "", ">", (list (if (or (and (future? o) (not (future-done? o)))
(and (promise? o) (not (promise-delivered? o))))
:pending
@o)), w))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment