That being said, I'm not clear if any of these differences are important to most people's use cases. I suspect that Lamina channels can behave like a core.async channel without much trouble, so it wouldn't bother me much if core.async became the primary interface for these sorts of things. If someone cares a lot about throughput or other distinguishing factors, they can just look under the covers.
I am, however, a little curious how well the goroutine mechanism works in terms of being able to sample the state of the various tasks. Without some equivalent for "jstack", they become something of a black box.
You can maybe create propagation operators that make these relationships explicit, but that would require either eschewing the bare take/put methods, or making sure the take/put behavior is in sync with whatever metadata you use to describe it.
I don't see this as much of a downside though, considering the issues one can have with selective receives.
* http://blog.paralleluniverse.co/post/49445260575/quasar-puls...
http://gist.github.com/swannodette/5886048
With timeout channels, the throttler is a beautiful 7 lines of clear code - compare to the Underscore.js imperative mess: http://underscorejs.org/docs/underscore.html#section-64
I've been doing sophisticated JS UIs for 8 years now and had largely given up on ever being able to really manage async complexity - neither JavaScript Promises nor ES6 generators provide this level of process coordination and clarity.
Very exciting times.
EDIT: Oh and don't forget you can pattern match on the result of a select (alt!) with core.match to get Erlang style matching http://github.com/clojure/core.match :) All this from libraries