Skip to content

Commit 1a0e23d

Browse files
committed
added more future fns, fixed print of pending futures, added promise/deliver
1 parent a9cb831 commit 1a0e23d

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/clj/clojure/core.clj

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4023,6 +4023,14 @@
40234023
40244024
Defaults to true")
40254025

4026+
(defn future?
4027+
"Returns true if x is a future"
4028+
[x] (instance? java.util.concurrent.Future x))
4029+
4030+
(defn future-done?
4031+
"Returns true if future f is done"
4032+
[#^java.util.concurrent.Future f] (.isDone f))
4033+
40264034
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; helper files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40274035
(alter-meta! (find-ns 'clojure.core) assoc :doc "Fundamental library of the Clojure language")
40284036
(load "core_proxy")
@@ -4052,6 +4060,15 @@
40524060
not yet finished, calls to deref/@ will block."
40534061
[& body] `(future-call (fn [] ~@body)))
40544062

4063+
4064+
(defn future-cancel
4065+
"Cancels the future, if possible."
4066+
[#^java.util.concurrent.Future f] (.cancel f true))
4067+
4068+
(defn future-cancelled?
4069+
"Returns true if future f is cancelled"
4070+
[#^java.util.concurrent.Future f] (.isCancelled f))
4071+
40554072
(defn pmap
40564073
"Like map, except f is applied in parallel. Semi-lazy in that the
40574074
parallel computation stays ahead of the consumption, but doesn't
@@ -4131,3 +4148,28 @@
41314148
(str "-" q))
41324149
(when (:interim *clojure-version*)
41334150
"-SNAPSHOT")))
4151+
4152+
(defn promise
4153+
"Experimental.
4154+
Returns a promise object that can be read with deref/@, and set,
4155+
once only, with deliver. Calls to deref/@ prior to delivery will
4156+
block. All subsequent derefs will return the same delivered value
4157+
without blocking."
4158+
[]
4159+
(let [d (java.util.concurrent.CountDownLatch. 1)
4160+
v (atom nil)]
4161+
(proxy [clojure.lang.AFn clojure.lang.IDeref] []
4162+
(deref [] (.await d) @v)
4163+
(invoke [x]
4164+
(locking d
4165+
(if (pos? (.getCount d))
4166+
(do (.countDown d)
4167+
(reset! v x)
4168+
this)
4169+
(throw (IllegalStateException. "Multiple deliver calls to a promise"))))))))
4170+
4171+
(defn deliver
4172+
"Experimental.
4173+
Delivers the supplied value to the promise, releasing any pending
4174+
derefs. A subsequent call to deliver on a promise will throw an exception."
4175+
[promise val] (promise val))

src/clj/clojure/core_print.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,6 @@
312312
(print-sequential (format "#<%s@%x: "
313313
(.getSimpleName (class o))
314314
(System/identityHashCode o))
315-
pr-on, "", ">", (list @o), w))
315+
pr-on, "", ">", (list (if (and (future? o) (not (future-done? o))) :pending @o)), w))
316316

317317
(def #^{:private true} print-initialized true)

0 commit comments

Comments
 (0)