; Rough sketch: def defines a var (pretend it's a reference)
; @ is used to dereference the future and block to wait for the result.
(def f
(future
(Thread/sleep 10000) (println "done") 100))
user=> @f
done
100
;; Dereferencing again will return the already calculated value.
=> @f
100
http://clojuredocs.org/clojure_core/clojure.core/futureEdit: And more importantly, there are wrappers for the standard data structures designed around different concurrency use-cases (sync, async, coordinated, uncoordinated)
Refs are for Coordinated Synchronous access to Many Identities".
Atoms are for Uncoordinated synchronous access to a single Identity.
Agents are for Uncoordinated asynchronous access to a single Identity.
Vars are for thread local isolated identities with a shared default value.
http://stackoverflow.com/questions/9132346/clojure-differenc...
And you can use all (all!) of the Java concurrency tooling as desired, including raw threads (for which Clojure has a wrapper as well).
Part of the reason I use Clojure rather than Go is because it doesn't try to force you into a one-size-fits-all method for handling concurrency. I have no problem with CSP but it doesn't fit everything I do. Sometimes I just want to defer work or wrap it in a future. Or I want to use an intelligent coordinated data structure rather than trying to meld flesh and bone to steel in order to make a concurrency-naive data structure behave how I want in a concurrent environ.
If I can avoid those unnecessary battles, I will.
So - Clojure.