core.async能否在序列方面实现其功能?

时间:2014-10-30 12:23:36

标签: clojure sequence core.async transducer

Rich Hickey's Strange Loop transducers presentation告诉我们,Clojure 1.6中有两个map实现,一个用于clojure.core中的序列,另一个用于core.async中的频道。

enter image description here

现在我们知道在1.7中我们有换能器,当给定a时,foldrreduce)函数从高阶函数返回,如mapfilter功能但不是集合。

我正在努力表达和失败,这就是为什么core.async函数不能返回序列,或者Seq - 就像。我有一种感觉,'接口'(协议)是不同的,但我看不出如何。

当然,如果您从频道中取出第一个项目,那么您可以将其表示为从序列中取出第一个项目吗?

我的问题是: core.async能否按顺序实现其功能?

1 个答案:

答案 0 :(得分:9)

是的,从某种意义上说,他们本来可以。如果你忽略了去块(暂时让我们这样做),那么下面的内容确实没有错:

(defn chan-seq [ch]
  (when-some [v (<!! c)]
    (cons v (lazy-seq (chan-seq ch)))))

但请注意<!!电话。这称为“阻塞”:在此函数内部是一些promise和lock,它们将导致当前正在执行的线程停止,直到通道上有值。因此,如果您不介意让Java线程无所事事,那么这样可以正常工作。

go block背后的想法是使逻辑过程更便宜;为了实现这一点,go块将块的主体重写为一系列附加到通道的回调,这样在go块内部对<!的调用就会变成这样的{{1}其中(take! c k)是对go块其余部分的回调。

现在,如果我们有真正的延续,或者JVM支持轻量级线程,那么是的,我们可以组合go-blocks和阻塞。但目前这涉及深度字节码重写(如Pulsar / Quasar项目)或某些非标准JVM功能。这两个选项都在core.async的创建中被排除,有利于实现更简单(并且希望更容易推理)本地块转换。