I have seen many Clojure programmers enthusiastic about the new core.async library and, though it seems very interesting, I am having a hard time seeing how it conforms to Clojure principles, so I have these questions:
- It uses mutable state everywhere, as the function names suggest by having an exclamation mark, like alt!, put!, >!, and others. If you put or take a value from a channel, that channel is modified inplace. Isn't it contrary to Clojure philosophy of preferring immutable data-structures, pure functions and so on? Or is core.async made to be used only where mutable things could not be avoided at all?
Since "go" is a macro (thus modifying code structure) and ensures "<!" is used directly in a go-block, it is not possible to use "<!" inside another function, like this:
(defn take-and-print [c] (println (<! c))) (def ch (chan 1)) (>!! ch 123) (go (take-and-print ch)) Assert failed: <! used not in (go ...) block
It seems to me that this prevents simplicity and composability. Why is it not a problem?
Maybe as a consequence of the previous two issues, a lot of code with core.async uses lower-level constructs such as loop/recur instead of map/filter/reduce. Isn't it a step backwards?
Where am I missing the point?
Thanks in advance.