Skip to content

Instantly share code, notes, and snippets.

@ztellman
Last active January 3, 2016 15:29
Show Gist options
  • Save ztellman/8482838 to your computer and use it in GitHub Desktop.
Save ztellman/8482838 to your computer and use it in GitHub Desktop.
(defn chain
"Composes functions, left to right, over the value `x`, returning a promise containing
the result. When composing, either `x` or the returned values may be values which can
be converted to a promise, causing the composition to be paused.
The returned promise will only be realized once all functions have been applied and their
return values realized.
(chain 1 inc #(future (inc %) => 3
@(chain (future 1) inc inc) => 3
"
([x]
(chain x identity identity identity))
([x f]
(chain x f identity identity))
([x f g]
(chain x f g identity))
([x f g h]
(try
(let [x' (unwrap x)]
(if (promise? x')
(let [p (promise)]
(on-realized x'
#(let [x (chain % f g h)]
(if (promise? x)
(connect x p)
(success! p x)))
#(error! p %))
p)
(let [x'' (f x')]
(if (promisable? x'')
(chain x'' g h identity)
(let [x''' (g x'')]
(if (promisable? x''')
(chain x''' h identity identity)
(let [x'''' (h x''')]
(if (promisable? x'''')
(->promise x'''')
(success-promise x'''')))))))))
(catch Throwable e
(error-promise e))))
([x f g h & fs]
(let [x' (chain x f g h)
p (promise)]
(on-realized x'
#(connect (apply chain % fs) p)
#(error! p %))
p)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment