是不是与Clojure原则相反的core.async?

aeu*_*uea 42 clojure core.async

我见过很多Clojure程序员热衷于新的core.async库,虽然看起来非常有趣,但我很难看到它是如何符合Clojure原则的,所以我有这些问题:

  1. 它在任何地方都使用可变状态,因为函数名称通过带有感叹号来表示,例如alt!,put!,>!和其他.如果您从频道中输入或获取值,则会在该位置修改该频道.是否与Clojure哲学相反,它更倾向于使用不可变数据结构,纯函数等等?或者是core.async仅在无法避免可变事物的情况下使用?
  2. 因为"go"是一个宏(从而修改代码结构)并确保"<!" 直接在go-block中使用,不能使用"<!" 在另一个函数里面,像这样:

    (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
    
    Run Code Online (Sandbox Code Playgroud)

    在我看来,这可以防止简单性和可组合性.为什么不是问题?

  3. 也许作为前两个问题的结果,core.async的许多代码使用较低级别的构造,例如loop/recur而不是map/filter/reduce.这不是倒退吗?

我在哪里错过了这一点?

提前致谢.

dno*_*len 37

第一个问题 - 是核心操作是副作用.但是通道没有通常与可变引用相关的问题,因为它们不代表"地方" - 通道是不透明的,你无法检查它们,实际上你甚至无法查询通道是否关闭或超出阅读范围零.

第二个问题 - 做任何不仅仅是浅层产量将意味着整个项目的转型.这是一个权衡,我认为是合理的.组成的水平是通道而不是块,它们组成很好.

最后的关注点,你可以很容易地做Rx风格的地图/过滤/减少操作的渠道和人已经这样做了.


cgr*_*and 16

go宏(它的位置)的限制也是一个特性:它强制执行有状态操作的源代码局部性.


Art*_*ldt 11

  1. 反过来说,Core.async只能用于不可变性是常态的系统中.所以Clojure的原则启用了core.async而不是反向.

  2. 这是一个限制,也发生在clojure的其他地方,不符合%符号的匿名函数的限制似乎至少表现出相同的想法.并非找到另一个限制的情况当然会更好.

  3. 我没有看到这是我的自我,尽管如果你试图采用简单的代码并且在以一种方式表达时清洁然后以某种方式表达它......那么这将是一个倒退. .


cla*_*laj 5

Rich Hickey在其中一个blip.tv讲座中表示,Clojure的功能是"85%".我喜欢将core.async视为其他15%的一部分.Core.async非常适合用户之间的互动,这些事情本来可以通过承诺,延迟和其他事情来完成,可能会以更混乱的方式进行.