When working with channels, is future recommended or is thread? Are there times when future makes more sense?
Rich Hickey's blog post on core.async recommends using thread rather than future:
While you can use these operations on threads created with e.g. future, there is also a macro, thread , analogous to go, that will launch a first-class thread and similarly return a channel, and should be preferred over future for channel work.
~ http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html
However, a core.async example makes extensive use of future when working with channels:
(defn fake-search [kind]
(fn [c query]
(future
(<!! (timeout (rand-int 100)))
(>!! c [kind query]))))
~ https://github.com/clojure/core.async/blob/master/examples/ex-async.clj
Summary
In general,
threadwith its channel return will likely be more convenient for the parts of your application where channels are prominent. On the other hand, any subsystems in your application that interface with some channels at their boundaries but don't use core.async internally should feel free to launch threads in whichever way makes the most sense for them.Differences between
threadandfutureAs pointed out in the fragment of the core.async blog post you quote,
threadreturns a channel, just likego:The channel is backed by a buffer of size 1 and will be closed after the value returned by the body of the
threadform is put on it. (Except if the returned value happens to benil, in which case the channel will be closed without anything being put on it -- core.async channels do not acceptnil.)This makes
threadfit in nicely with the rest of core.async. In particular, it means thatgo+ the single-bang ops andthread+ the double-bang ops really are used in the same way in terms of code structure, you can use the returned channel inalt!/alts!(and the double-bang equivalents) and so forth.In contrast, the return of
futurecan bederef'd (@) to obtain the value returned by thefutureform's body (possiblynil). This makesfuturefit in very well with regular Clojure code not using channels.There's another difference in the thread pool being used --
threaduses a core.async-specific thread pool, whilefutureuses one of the Agent-backing pools.Of course all the double-bang ops, as well as
put!andtake!, work just fine regardless of the way in which the thread they are called from was started.