Guest User

Untitled

a guest
May 24th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.13 KB | None | 0 0
  1. ;;; Future pipelining macro.
  2. ;;; Behaves like a let, but wraps everything in futures - running your bindings concurrently
  3. ;;; Computation takes only as long as the longest-running bind
  4.  
  5. (ns user
  6. (:use clojure.walk clojure.test))
  7.  
  8. (defn cols
  9. "Projection of n columns from coll"
  10. [n coll]
  11. (apply map vector (partition n coll)))
  12.  
  13. (defmacro let-futures
  14. "Bindings wrapped in futures. Derefs in bindings and body made implicit."
  15. [bindings & body]
  16. (let [[locals procs] (cols 2 bindings)
  17. lmap (zipmap locals (map #(list `deref %) locals))]
  18. `(let ~(vec (interleave locals (map #(cons `future (list %))
  19. (postwalk-replace lmap procs))))
  20. ~@(postwalk-replace lmap body))))
  21.  
  22. (deftest test-cols
  23. (is (= [[:a :b :c] [:A :B :C]] (cols 2 [:a :A :b :B :c :C])))
  24. (is (= [[:a :b :c] [:A :B :C] [10 20 30]] (cols 3 [:a :A 10 :b :B 20 :c :C 30]))))
  25.  
  26. (deftest test-let-futures
  27. (letfn [(sleepy-fn [ms] (Thread/sleep ms) 1)]
  28. ;; running time should be ~500ms
  29. (is (= 3 (time
  30. (let-futures [f1 (sleepy-fn 500)
  31. f2 (+ (sleepy-fn 500) f1)
  32. f3 (+ (sleepy-fn 500) f2)]
  33. f3))))
  34. (is (= 10 (let-futures [x 10]
  35. x)))))
Add Comment
Please, Sign In to add comment