Public Vars

Back

future-call (clj)

(source)

function

(future-call f)
Takes a function of no args and yields a future object that will invoke the function 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?.

Examples

clojure/core.typed
(ns ^:skip-wiki clojure.core.typed.ann.clojure
  "Type annotations for the base Clojure distribution."
  (:require [#?(:clj clojure.core.typed
                :cljs cljs.core.typed)
             :refer [defalias] :as t]))

(defalias
  ^{:doc "A Clojure future (see clojure.core/{future-call,future})."
    :forms '[(Future t)]}
  t/Future 
  (t/TFn [[x :variance :covariant]]
         (t/I (t/Deref x)
              (clojure.lang.IBlockingDeref x)
              clojure.lang.IPending
              java.util.concurrent.Future)))
hraberg/deuce
(ns deuce.emacs.callproc
  (:use [deuce.emacs-lisp :only (defun defvar) :as el])
  (:require [clojure.core :as c]
            [clojure.string :as s]
            [clojure.java.io :as io]
            [clojure.java.shell :as sh]
            [deuce.emacs.buffer :as buffer]
            [deuce.emacs.data :as data]
            [deuce.emacs.editfns :as editfns])
  (:import [java.io File])
  (:refer-clojure :exclude []))

  If BUFFER is 0, `call-process' returns immediately with value nil.
  Otherwise it waits for PROGRAM to terminate
  and returns a numeric exit status or a signal description string.
  If you quit, the process is killed with SIGINT, or SIGKILL if you quit again."
  (let [opts (if infile [:in (io/file infile)] [])
        no-wait? (= 0 buffer)
        buffer (or no-wait?
                   (and (data/consp buffer) (= :file (data/car buffer)) (data/cdr buffer))
                   (and (true? buffer) (buffer/current-buffer))
                   (el/check-type 'bufferp (or (when (data/consp buffer) (data/car buffer))
                                               buffer (buffer/current-buffer))))
        stderr (when (data/consp buffer) (data/cdr buffer))
        runner (if no-wait? #(do (future-call %) nil) #(%))]
    (runner #(let [{:keys [exit out err]}
                   (apply sh/sh (concat (cons program args) opts))]
               (when (data/bufferp buffer)
                 (binding [buffer/*current-buffer* buffer]
                   (editfns/insert out)
                   (when (true? stderr)
                     (editfns/insert err))))
               (when (string? buffer)
                 (spit (io/file buffer) out))
               (when (string? stderr)
                 (spit (io/file stderr) err))
               exit))))
typedclojure/typedclojure
(ns ^:no-doc typed.ann.clojure
  "Type annotations for the base Clojure distribution."
  #?(:cljs (:require-macros [typed.ann-macros.clojure :as macros]))
  (:require [clojure.core :as cc]
            [typed.clojure :as t]
            #?(:clj [typed.ann-macros.clojure :as macros])
            #?(:clj typed.ann.clojure.jvm) ;; jvm annotations
            #?(:clj clojure.core.typed))
  #?(:clj
     (:import (clojure.lang PersistentHashSet PersistentList
                            APersistentMap #_IPersistentCollection
                            #_ITransientSet
                            IRef)
              (java.util Comparator Collection))))

#?(:clj
(t/defalias
  ^{:doc "A Clojure future (see clojure.core/{future-call,future})."
    :forms '[(Future x)]}
  t/Future 
  (t/TFn [[x :variance :covariant]]
         (t/I (t/Deref x)
              (clojure.lang.IBlockingDeref x)
              clojure.lang.IPending
              java.util.concurrent.Future))))

#?@(:cljs [] :default [
cc/future-call (t/All [x] [[:-> x] :-> (t/Future x)])
])
ReactiveX/RxClojure
(ns rx.lang.clojure.graph-test
  (:require [rx.lang.clojure.graph :as graph]
            [rx.lang.clojure.core :as rx]
            [rx.lang.clojure.future :as rx-future]
            [rx.lang.clojure.blocking :as rx-blocking]
            [clojure.test :refer [deftest testing is]]))

  (testing "it still works"
    (is (= {:a 99 :b 100 :z "hi"}
           (rx-blocking/single
             (-> (let [z (rx/return "hi")] ; an observable from "somewhere else"
                   (graph/let-o
                     [?a (rx-future/future* future-call #(do (Thread/sleep 50) 99))
                      ?b (rx-future/future* future-call #(do (Thread/sleep 500) 100))
                      ?c (rx/map #(hash-map :a %1 :b %2 :z %3) ?a ?b ?z)
                      ?z z]
                     (rx/reduce merge {} ?c)))))))))

(deftest test-complicated-graph
  ; These funcs model network requests for various stuff. They all return observable.
  (let [request-vhs (fn []
                      (rx-future/future-generator*
                        future-call
                        (fn [o]
                          (Thread/sleep 50)
                          (doseq [i (range 3)]
                            (rx/on-next o {:id i})))))
        request-user (fn [id]
                       (rx-future/future*
                         future-call
                         #(do (Thread/sleep (rand-int 250))
                            {:id id
                             :name (str "friend" id) })))
        request-ab (fn [u]
                     (rx-future/future*
                       future-call
                       #(do (Thread/sleep (rand-int 250))
                          {:user-id (:id u)
                           :cell    (* 2 (:id u))})))

        ; Now we can stitch all these requests together into an rx graph to
        ; produce a response.
        o (graph/let-o [?user-info (rx-future/future*
                                     future-call
                                     #(do (Thread/sleep 20)
                                        {:name "Bob"
                                         :id 12345
                                         :friend-ids [1 2 3] }))
ReactiveX/RxClojure
(ns rx.lang.clojure.core-test
  (:require [rx.lang.clojure.core :as rx]
            [rx.lang.clojure.blocking :as b]
            [rx.lang.clojure.future :as f]
            [clojure.test :refer [deftest is testing are]]))

(let [expected-result [[1 3 5] [2 4 6]]
      sleepy-o        #(f/future-generator*
                         future-call
                         (fn [o]
                           (doseq [x %]
                             (Thread/sleep 10)
                             (rx/on-next o x))))
      make-inputs (fn [] (mapv sleepy-o expected-result))
      make-output (fn [r] [(keep #{1 3 5} r)
                           (keep #{2 4 6} r)])]
  (deftest test-merge*
    (is (= expected-result
           (->> (make-inputs)
                (rx/seq->o)
                (rx/merge*)
                (b/into [])
                (make-output)))))
  (deftest test-merge
    (is (= expected-result
           (->> (make-inputs)
                (apply rx/merge)
                (b/into [])
                (make-output)))))
  (deftest test-merge-delay-error*
    (is (= expected-result
           (->> (make-inputs)
                (rx/seq->o)
                (rx/merge-delay-error*)
                (b/into [])
                (make-output)))))
  (deftest test-merge-delay-error
    (is (= expected-result
           (->> (make-inputs)
                (apply rx/merge-delay-error)
                (b/into [])
                (make-output))))))