clojure.core.async中的函数名称源自何处,是否可以使用描述性函数?

时间:2016-08-03 18:53:14

标签: clojure core.async

我最近开始使用core.async库,我有点困惑为什么它使用这样的函数名称:

  • >!
  • >!!
  • chan

我总是要考虑感叹号的数量,例如当我不确定哪个是停车版本时,哪个是阻止版本。这让我想起了“不要让我思考”一书和“Clojure Programming”这本书写成:

  

Clojure的语法减少了读取或编写代码所需的认知负荷......每次程序员必须暂停并考虑这一点(或在手册中查找)......出现心理页面错误。

对此有何解释?

3 个答案:

答案 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的端点。 !(或!!)是您要加入(>!)或从(<!)该频道投放的邮件。

enter image description here

不幸的是,我不能解释为什么!代表停车而!!代表拦截,但我认为你很快就习惯了。此外,它还可以让您编写简洁的代码,而不会分散实际的业务逻辑。

编辑:观看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