我看到许多 Clojure 程序员对新的 core.async 库充满热情,尽管它看起来很有趣,但我很难看出它如何符合 Clojure 原则,所以我有以下问题:
- 它在任何地方都使用可变状态,正如函数名称通过感叹号所暗示的那样,例如 alt!、put!、>! 等。如果您从通道中放入或取出值,则该通道将被就地修改。这不是违背了 Clojure 偏好不可变数据结构、纯函数等的哲学吗?或者 core.async 是否只在根本无法避免可变事物的情况下使用?
-
由于“go”是一个宏(从而修改代码结构)并确保“
(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
在我看来,这阻碍了简单性和可组合性。为什么这不是问题?
也许由于前两个问题,许多带有 core.async 的代码使用了较低级别的构造,例如循环/递归而不是映射/过滤/减少。这不是倒退一步吗?
我哪里遗漏了重点?
提前致谢。
第一个担忧 - 是的,核心操作是副作用。然而,通道不存在通常与可变引用相关的问题,因为它们不代表“位置” - 通道是不透明的,您无法检查它们,事实上您甚至无法查询通道是否已关闭或无法读取零。
第二个问题——除了浅产量之外的任何事情都意味着整个计划的转变。这是一种权衡,我认为是合理的。组合的水平是通道而不是块,它们组合得很好。
最后一个问题是,您可以轻松地通过通道进行 Rx 风格的映射/过滤/归约操作,并且人们已经这样做了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)