Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

Isn't core.async contrary to Clojure principles?

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:

  1. 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?
  2. 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?

  3. 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.

question from:https://stackoverflow.com/questions/18198666/isnt-core-async-contrary-to-clojure-principles

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The first concern - yes the core operations are side effects. However channels don't have the problems normally associated with mutable references as they don't represent a "place" - channels are opaque, you cannot inspect them, in fact you can't even query whether a channel is closed or not beyond reading nil.

The second concern - doing anything more than shallow yield would mean whole program transformation. This is a tradeoff and I think a reasonable one. The level of composition is channels not go blocks and they compose just fine.

The final concern, you can easily do Rx style map/filter/reduce operations over channels and people have already done so.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...