如何理解clojure core.async

时间:2016-01-18 13:44:14

标签: clojure core.async

我已经阅读了以下文档和示例,但仍然没有得到它的真正含义。我理解alts !!,但不是alt !!。有人举一个容易理解的例子吗?

https://clojure.github.io/core.async/#clojure.core.async/alt !!

我还准备了以下链接

In Clojure (core.async) what's the difference between alts and alt?

更新:示例位于doc:

(alt!
  [c t] ([val ch] (foo ch val))
  x ([v] v)
  [[out val]] :wrote
  :default 42)

第二行

[c t] ([val ch] (foo ch val))

[c t]的通道操作意味着通道c和值t:将值t放在通道c上。 ([val ch](foo ch val))的result-expr表示操作的出价[val ch],但由于它是一个列表,[val ch]应该作为函数计算,并且(foo ch val)将是作为参数传递给[val ch]的函数。但是对于具有(foo ch val)参数的[val ch]的函数意味着什么?

1 个答案:

答案 0 :(得分:5)

  

[c t]([val ch](foo ch val))

在某些情况下,列表并不意味着“评估为函数”。例如:

(ns com.foo.bar
  (:require …))

在上面的代码中,没有调用名为:require的函数。

用于除函数应用程序之外的其他内容的列表的另一个示例是letfn

(letfn [(foo [x] (+ (bar 1) x))
        (bar [x] (+ 2 x))]
  (+ (foo 5) (bar 7)))

如上所示,letfn有两个列表,一个以符号foo开头,另一个以符号bar开头,这两个列表都不是传统函数呼叫。相反,letfn 定义两个新函数,一个名称为foo,另一个名称为bar。表达式的其余部分被视为使用这些函数的“主体”。

  

但是[val ch]的函数对于(foo ch val)的参数是什么意思?

letfn类似,alt 定义名为val的值和名为ch的频道,然后是表达式的其余部分( (foo ch val))被视为使用这两个名称的“主体”。

alt!/alt!!

的说明

我觉得最容易将alt!alt!!视为有点像cond,除了测试选择要执行的主体的条件,它会等待频道选择身体执行。每个子句由两部分组成,就像cond一样 - 第一部分(“channel op”)用于指定alt!应该等待的频道,以及第二部分(“结果expr”)指定如果该频道首先传递值,会发生什么。

由于您可能希望在发生这种情况时访问通道通道本身提供的值,结果expr 使您有机会同时绑定值和通道到符号,以及用这些绑定执行的代码体。因此,以下条款......

[c t]
([val ch]
  (foo ch val))

...是指:

  

alt!调用应阻止的其中一个频道操作是尝试从<{1}}或c两个频道中选择。如果其中任何一个在此t调用中的任何其他频道操作之前发送了一个值,则执行alt!(foo ch val)绑定到从频道获取的值首先投放了一个值,并val绑定到投放ch的频道(valc)。

以及以下条款......

t

...是指:

  

[[out input-val]] ([val ch] (bar ch val)) 调用应阻止的其中一个频道操作是 alt!置于名为input-val的频道上。如果在此次out调用中的任何其他频道操作之前成功,请执行alt! (bar ch val)绑定valinput-val绑定到ch(成功接收该值的通道)。

总而言之,这两个条款将写成:

out