ClojureDocs

Nav

Namespaces

future

clojure.core

Available since 1.1 (source)
  • (future & body)
Takes a body of expressions and yields a future object that will
invoke the body in another thread, and will cache the result and
return it on all subsequent calls to deref/@. If the computation has
not yet finished, calls to deref/@ will block, unless the variant of
deref with timeout is used. See also - realized?.
6 Examples
;; A future's calculation is started here and it runs in another thread
user=> (def f (future (Thread/sleep 10000) (println "done") 100))
#'user/f
;;if you wait 10 seconds before dereferencing it you'll see "done"

;; When you dereference it you will block until the result is available.
user=> @f
done
100

;; Dereferencing again will return the already calculated value.
=> @f
100
;; save the example in a script (e.g. test-future.clj) then run it in the console
;;
;; > clojure test-future.clj

(println "[Main] calculate the answer to life the universe and everything")

;; Used Thread/sleep to simulate long running process
(def what-is-the-answer-to-life
    (future 
        (println "[Future] started computation")
        (Thread/sleep 3000) ;; running for 3 seconds
        (println "[Future] completed computation")
        42))
        
(println "[Main] created future")

(Thread/sleep 1000)
(println "[Main] do other things while waiting for the answer")
(println "[Main] get the answer")
(println "[Main] the result" @what-is-the-answer-to-life)
(shutdown-agents)


;; You may get something like this
;;
;; [Main] calculate the answer to life, the universe and everything
;; [Future] started computation
;; [Main] created future
;; [Main] do other things while waiting for the answer
;; [Main] get the answer
;; [Future] completed computation
;; [Main] the result 42


;; Note: If you leave out the call to (shutdown-agents), the program
;; will on most (all?) OS/JVM combinations "hang" for 1 minute before
;; the process exits.  It is waiting for a thread created by the
;; future call to be shut down.  shutdown-agents will shut them down
;; immediately, or (System/exit <exit-status>) will exit immediately
;; without waiting for them to shut down.

;; This wait occurs even if you use futures indirectly through some other Clojure
;; functions that use them internally, such as pmap or clojure.java.shell/sh

;; http://dev.clojure.org/jira/browse/CLJ-124 is a ticket opened against Clojure,
;; as this 1-minute wait is not considered desirable behavior.
;; Futures will not raise their exceptions...
=> (def my-future (future (/ 1 0))

;; ...until dereferenced!
=> @my-future
ArithmeticException Divide by zero  clojure.lang.Numbers.divide
;; Given two URLs, create two futures to slurp their HTML, and return 
;; the page that returns first.
;; This works because promises can only be delivered once.
(let [p (promise)]
  (let [angieslist "https://angieslist.com" 
        homeadvisor "https://homeadvisor.com"]
   (doseq [url [angieslist homeadvisor]]
     (future (let [response (slurp url)]
               (deliver p response)))))
  @p)
;; You may want to do some cleanup whenever you cancel your `future`
;; InterruptedException is the catch!

;; lets say we want to feed our doge, but only a limited time...
(defn connect! [conn] (println (reset! conn "[doge] very yum")))
(defn response [conn] (println (reset! conn "[doge] so full")))
(defn clean    [conn] (println (reset! conn "[doge] so hungry")))

(let [feed-time  (rand-int 2000)
      connection (atom "[doge] such ready")
      doge-ops   (future
                   (try
                     (println @connection)
                     (connect! connection)
                     (Thread/sleep 1000)
                     (response connection)
                     (catch InterruptedException ie
                       (clean connection))
                     (finally (println "[doge] wow"))))]
  (printf "[Main] granting many feeding time: %dms\n" feed-time)
  (if (= :too-late (deref doge-ops feed-time :too-late))
    (do (println "[Main] stop!")
        (future-cancel doge-ops))
    @doge-ops))

;; if he's lucky:
[Main] granting many feeding time: 1582ms
[doge] such ready
[doge] very yum
[doge] so full
[doge] wow
=> nil

;; if he's unlucky:
[Main] granting many feeding time: 569ms
[doge] such ready
[doge] very yum
[Main] stop!
=> true
[doge] so hungry
[doge] wow
;; Notice that future takes a body of expressions. That means it is possible
;; to add a callback for an async computation in the future definition itself.
;; There are two cases:
;; 1. If the callback does not need to take the result of the computation 
;; as input, just do this:
(future (computation) (callback))
;; 2. If the callback needs to take the result, do this:
(future (callback (computation)))
See Also

Cancels the future, if possible.

Added by abrooks

Initiates a shutdown of the thread pools that back the agent system. Running actions will complete...

Added by jafingerhut

Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to...

Added by klauern

Returns true if a value has been produced for a promise, delay, future or lazy sequence.

Added by klauern

Takes a body of expressions and yields a Delay object that will invoke the body only the first tim...

Added by pauldoo

Returns true if x is a future

Added by gstamp

Takes a function of no args and yields a future object that will invoke the function in another th...

Added by ninjudd

Returns true if future f is done

Added by Chort409

Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in...

Added by MicahElliott
0 Notes
No notes for future