diff options
-rw-r--r-- | src/clj/clojure/core.clj | 42 | ||||
-rw-r--r-- | src/clj/clojure/core_print.clj | 2 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index da282d35..4c76d9b5 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -4023,6 +4023,14 @@ Defaults to true") +(defn future? + "Returns true if x is a future" + [x] (instance? java.util.concurrent.Future x)) + +(defn future-done? + "Returns true if future f is done" + [#^java.util.concurrent.Future f] (.isDone f)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; helper files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (alter-meta! (find-ns 'clojure.core) assoc :doc "Fundamental library of the Clojure language") (load "core_proxy") @@ -4052,6 +4060,15 @@ not yet finished, calls to deref/@ will block." [& body] `(future-call (fn [] ~@body))) + +(defn future-cancel + "Cancels the future, if possible." + [#^java.util.concurrent.Future f] (.cancel f true)) + +(defn future-cancelled? + "Returns true if future f is cancelled" + [#^java.util.concurrent.Future f] (.isCancelled f)) + (defn pmap "Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't @@ -4131,3 +4148,28 @@ (str "-" q)) (when (:interim *clojure-version*) "-SNAPSHOT"))) + +(defn promise + "Experimental. + 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." + [] + (let [d (java.util.concurrent.CountDownLatch. 1) + v (atom nil)] + (proxy [clojure.lang.AFn clojure.lang.IDeref] [] + (deref [] (.await d) @v) + (invoke [x] + (locking d + (if (pos? (.getCount d)) + (do (.countDown d) + (reset! v x) + this) + (throw (IllegalStateException. "Multiple deliver calls to a promise")))))))) + +(defn deliver + "Experimental. + Delivers the supplied value to the promise, releasing any pending + derefs. A subsequent call to deliver on a promise will throw an exception." + [promise val] (promise val)) diff --git a/src/clj/clojure/core_print.clj b/src/clj/clojure/core_print.clj index 228b8cb3..d2b1612e 100644 --- a/src/clj/clojure/core_print.clj +++ b/src/clj/clojure/core_print.clj @@ -312,6 +312,6 @@ (print-sequential (format "#<%s@%x: " (.getSimpleName (class o)) (System/identityHashCode o)) - pr-on, "", ">", (list @o), w)) + pr-on, "", ">", (list (if (and (future? o) (not (future-done? o))) :pending @o)), w)) (def #^{:private true} print-initialized true) |