如何理解 clojure 中的 alt core.async
how to understand alt in clojure core.async
我已经阅读了以下文档和示例,但仍然不明白它的真正含义。我理解 alts!!,但不是 alt!!。有人举个容易理解的例子吗?
https://clojure.github.io/core.async/#clojure.core.async/alt!!
我还准备了以下link
In Clojure (core.async) what's the difference between alts and alt?
更新:文档中的示例是:
(alt!
[c t] ([val ch] (foo ch val))
x ([v] v)
[[out val]] :wrote
:default 42)
为
的第二行
[c t] ([val ch] (foo ch val))
channel-op of [c t]表示通道c和值t:将值t放在通道c上。
([val ch] (foo ch val)) 的结果表达式表示为操作出价 [val ch],但由于它是一个列表,[val ch] 应该作为一个函数求值,而 (foo ch val) 将是作为传递给 [val ch] 函数的参数。但是参数为 (foo ch val) 的 [val ch] 函数意味着什么?
[c t] ([val ch] (foo ch val))
在某些情况下,列表并不意味着 "evaluate as a function"。例如:
(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
。表达式的其余部分被视为要在其中使用这些函数的 "body"。
but what does it mean for function of [val ch] with parameter of (foo ch val) ?
类似于letfn
,alt
定义一个名为val
的值和一个名为ch
的通道,然后表达式的其余部分 ((foo ch val)
) 被视为 "body",在其中使用这两个名称。
alt!/alt!!
的解释:
我发现最容易想到 alt!
和 alt!!
有点像 cond
,除了不是测试条件来选择 body 来执行,它等待通道选择 body 来执行。每个子句由两部分组成,就像 cond
– 第一部分("channel op")用于指定 alt!
应该等待的通道上,第二部分("result expr")指定如果该通道首先传递值应该发生什么。
由于您可能希望在发生这种情况时访问通道 或 通道本身传递的值,因此 result expr 为您提供将值和通道绑定到符号的机会,以及使用这些绑定执行的 body 代码。因此,以下子句......
[c t]
([val ch]
(foo ch val))
…表示:
One of the channel operations that this call to alt!
should block on is an attempt to take from either of two channels, c
or t
. If either of those send a value before any other channel op in this call to alt!
, then execute (foo ch val)
with val
bound to the value taken from the channel that first delivered a value, and with ch
bound to the channel that delivered val
(which will be either c
or t
).
和下面的子句……
[[out input-val]]
([val ch]
(bar ch val))
…表示:
One of the channel operations that this call to alt!
should block on is an attempt to put input-val
onto a channel called out
. If that succeeds before any other channel op in this call to alt!
, then execute (bar ch val)
with val
bound to input-val
and ch
bound to out
(the channel that successfully received the value).
这两个子句加起来可以写成:
(alt!
[c t] ; "Takes" can be a single channel instead of vectors.
([val ch]
(foo ch val))
[[out input-val]] ; "Puts" must be nested vectors.
([val ch]
(bar ch val)))
我已经阅读了以下文档和示例,但仍然不明白它的真正含义。我理解 alts!!,但不是 alt!!。有人举个容易理解的例子吗?
https://clojure.github.io/core.async/#clojure.core.async/alt!!
我还准备了以下link
In Clojure (core.async) what's the difference between alts and alt?
更新:文档中的示例是:
(alt!
[c t] ([val ch] (foo ch val))
x ([v] v)
[[out val]] :wrote
:default 42)
为
的第二行[c t] ([val ch] (foo ch val))
channel-op of [c t]表示通道c和值t:将值t放在通道c上。 ([val ch] (foo ch val)) 的结果表达式表示为操作出价 [val ch],但由于它是一个列表,[val ch] 应该作为一个函数求值,而 (foo ch val) 将是作为传递给 [val ch] 函数的参数。但是参数为 (foo ch val) 的 [val ch] 函数意味着什么?
[c t] ([val ch] (foo ch val))
在某些情况下,列表并不意味着 "evaluate as a function"。例如:
(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
。表达式的其余部分被视为要在其中使用这些函数的 "body"。
but what does it mean for function of [val ch] with parameter of (foo ch val) ?
类似于letfn
,alt
定义一个名为val
的值和一个名为ch
的通道,然后表达式的其余部分 ((foo ch val)
) 被视为 "body",在其中使用这两个名称。
alt!/alt!!
的解释:
我发现最容易想到 alt!
和 alt!!
有点像 cond
,除了不是测试条件来选择 body 来执行,它等待通道选择 body 来执行。每个子句由两部分组成,就像 cond
– 第一部分("channel op")用于指定 alt!
应该等待的通道上,第二部分("result expr")指定如果该通道首先传递值应该发生什么。
由于您可能希望在发生这种情况时访问通道 或 通道本身传递的值,因此 result expr 为您提供将值和通道绑定到符号的机会,以及使用这些绑定执行的 body 代码。因此,以下子句......
[c t]
([val ch]
(foo ch val))
…表示:
One of the channel operations that this call to
alt!
should block on is an attempt to take from either of two channels,c
ort
. If either of those send a value before any other channel op in this call toalt!
, then execute(foo ch val)
withval
bound to the value taken from the channel that first delivered a value, and withch
bound to the channel that deliveredval
(which will be eitherc
ort
).
和下面的子句……
[[out input-val]]
([val ch]
(bar ch val))
…表示:
One of the channel operations that this call to
alt!
should block on is an attempt to putinput-val
onto a channel calledout
. If that succeeds before any other channel op in this call toalt!
, then execute(bar ch val)
withval
bound toinput-val
andch
bound toout
(the channel that successfully received the value).
这两个子句加起来可以写成:
(alt!
[c t] ; "Takes" can be a single channel instead of vectors.
([val ch]
(foo ch val))
[[out input-val]] ; "Puts" must be nested vectors.
([val ch]
(bar ch val)))