Skip to content

Instantly share code, notes, and snippets.

@ane
Last active November 15, 2017 19:41
Show Gist options
  • Save ane/a12d6413b0688046561e43692958eac1 to your computer and use it in GitHub Desktop.
Save ane/a12d6413b0688046561e43692958eac1 to your computer and use it in GitHub Desktop.
experimenting with a Scala Future/Task like library for Clojure
; experiments on a clojure future API
; http/get and/post are expected to return futures
; create a future
(run (Thread/sleep 100)
123)
; => java.util.concurrent.CompletableFuture[123]
; supports deref, implements java.util.concurrent.Future
(def foo (run "blaa"))
@foo ; => "blaa"
; promote a value, don't launch a future
@(now 123) ; => 123
; then is map
@(then (run 123) (inc))
; => 124
; compose is flatMap
@(compose (run 1234) (fn [x] (run (Thread/sleep 1000) (inc x))))
; => 1235
; for yield - with interop
(def xyz (promise))
(for [a (run "hello")
b (future "i am bob")
c xyz]
(print (str a b c)))
; time passes
(deliver xyz "blarh")
; prints "helloi am bobblarh"
; sequence a list of tasks into a task list
(sequence (run 1) (future 2) (now 9))
; => [1 2 9]
; traverse with a task producing function
(traverse (fn [x] (run (Thread/sleep (* x 500)))) [1 2 3 4])
; contrived example, real use
; then is map
(def get-location
(task/then (http/get "http://host.com/stuff")
cheshire/parse-string))
(defn get-restaurants
[location]
(task/then (http/get "http://target.api/restaurants-near-you" {:lat (:latitude location) :lng (:longitude location)})
cheshire/parse-string))
; compose is flatMap
(defn reserve-restaurant
[restaurant-id]
(task/compose (http/post "http://restaurant.reservation/reserve"
(cheshire/format-string {:id restaurant-id}))
(fn [reservation] ; returns a new future!
(http/post "http://my.calendar/free"
(cheshire/format-string {:time (:start reservation)})))))
(defn best-restaurant
[restaurants]
(first restaurants)) ; arbitrary logic here
; for is for yield
(def reserve-nearest-restaurant
(task/for [location (get-location)
restaurants (get-restaurants location)
reservation (reserve-restaurant (:id (best-restaurant restaurants)))]
(printf "reserved restaurant %s%n" (:name reservation))))
; block until it's reserved
@reserve-nearest-restaurant
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment