我最近开始使用core.async
库,我有点困惑为什么它使用这样的函数名称:
>!
>!!
chan
我总是要考虑感叹号的数量,例如当我不确定哪个是停车版本时,哪个是阻止版本。这让我想起了“不要让我思考”一书和“Clojure Programming”这本书写成:
Clojure的语法减少了读取或编写代码所需的认知负荷......每次程序员必须暂停并考虑这一点(或在手册中查找)......出现心理页面错误。
对此有何解释?
答案 0 :(得分:3)
我推测在使用core.async时,您将多次编写go
parking-put
blocking-take
create-channel
,因此认为适合使用速记。 >
和<
由于方向性而非常明显。也许!
表示将值传递到通道的副作用,!!
表示进入通道并创建线程的副作用。在任何情况下,意思应该理解为一个bang意味着状态机,两个刘海意味着线程。
符号和简写允许更简洁的代码,如果采用core.async,那些运算符的使用往往会迅速渗透到代码中...所以在这种情况下似乎是一个很好的权衡,尽管搜索有明显的缺点能力和自我证据。
Zach Tellman在他的演讲中对命名进行了深思熟虑的评论:https://www.youtube.com/watch?v=JaKLSH4csqE和书籍https://leanpub.com/elementsofclojure
答案 1 :(得分:3)
一个微小的助记符:分别将>
<
视为一个漏洞,它就像你chan
nel的端点。 !
(或!!
)是您要加入(>!
)或从(<!
)该频道投放的邮件。
不幸的是,我不能解释为什么!
代表停车而!!
代表拦截,但我认为你很快就习惯了。此外,它还可以让您编写简洁的代码,而不会分散实际的业务逻辑。
编辑:观看Timothy Baldridge's talk on core.async from Clojure/conj 2013后,我想添加此引文(跳至6:15):
[...]第一个感叹号表示它不是事务安全的[...],第二个表示这是一个阻塞操作。
答案 2 :(得分:1)
我分担你的痛苦。我总是不得不停下来思考,以便将像<!
这样的名称翻译成只能在go循环中使用的停车版本#34;。我已经开始研究一些更人性化的名字(仍在进行中!):
(ns tupelo.async
"tupelo - Making Clojure even sweeter"
(:require [clojure.core :as clj]
[clojure.core.async :as clj.async] )
(:gen-class))
; #todo add tests
; #todo add docs to README
(defmacro put-go! [& args]
`(clj.async/>! ~@args))
(defmacro take-go! [& args]
`(clj.async/<! ~@args))
(defn put-now! [& args]
(apply clj.async/>!! args))
(defn take-now! [& args]
(apply clj.async/<!! args))
(defn put-later! [& args]
(apply clj.async/put! args))
(defn take-later! [& args]
(apply clj.async/take! args))
https://github.com/cloojure/tupelo/blob/master/src/tupelo/async.cljc