Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;; Future pipelining macro.
- ;;; Behaves like a let, but wraps everything in futures - running your bindings concurrently
- ;;; Computation takes only as long as the longest-running bind
- (ns user
- (:use clojure.walk clojure.test))
- (defn cols
- "Projection of n columns from coll"
- [n coll]
- (apply map vector (partition n coll)))
- (defmacro let-futures
- "Bindings wrapped in futures. Derefs in bindings and body made implicit."
- [bindings & body]
- (let [[locals procs] (cols 2 bindings)
- lmap (zipmap locals (map #(list `deref %) locals))]
- `(let ~(vec (interleave locals (map #(cons `future (list %))
- (postwalk-replace lmap procs))))
- ~@(postwalk-replace lmap body))))
- (deftest test-cols
- (is (= [[:a :b :c] [:A :B :C]] (cols 2 [:a :A :b :B :c :C])))
- (is (= [[:a :b :c] [:A :B :C] [10 20 30]] (cols 3 [:a :A 10 :b :B 20 :c :C 30]))))
- (deftest test-let-futures
- (letfn [(sleepy-fn [ms] (Thread/sleep ms) 1)]
- ;; running time should be ~500ms
- (is (= 3 (time
- (let-futures [f1 (sleepy-fn 500)
- f2 (+ (sleepy-fn 500) f1)
- f3 (+ (sleepy-fn 500) f2)]
- f3))))
- (is (= 10 (let-futures [x 10]
- x)))))
Add Comment
Please, Sign In to add comment