处理无限(懒惰)序列

时间:2016-12-13 04:10:49

标签: clojure

我继承了一些轮询更新的代码,将这些更新附加到延迟序列并进行处理。从clojure 1.7.0-alpha5升级到任何更高版本后,由于惰性序列的chunking,代码显示已损坏。我已经写了一个例子来说明问题:

(defn infinite-updates
  []
  (letfn [(step [n]
            (lazy-seq
             ;; Poll for an update
             (Thread/sleep 3000)
             (cons n (step (rand-int 5)))))]
     (lazy-seq
      (step (rand-int 5)))))

;; Run with:
(doseq [t  (sequence (map inc) (infinite-updates))] (println t))

该项目是在clojure 1.7.0-alpha5上运行的:每3秒t打印一次。

一旦我升级过该版本,就会对结果进行分块,因此大约1.5分钟后我会打印出t个。{/ p>

我尝试过使用以下内容:

(defn unchunk [s]
  (when (seq s)
  (lazy-seq
    (cons (first s)
        (unchunk (next s))))))

unchunk没有运气的数据。

我如何处理这些更新,或者是否有一种更惯用的方式来编写infinite-updates,以便我处理所有更新,而不依赖于lazy-seq?

2 个答案:

答案 0 :(得分:3)

您的问题是针对clojure.core.async量身定制的。此代码显示了大纲:

(ns tst.clj.core
  (:use clj.core
        clojure.test)
  (:require
     [clojure.core.async :as async]
  ))

; create a buffer of arbitrary size 99 (any size, even zero, would work)
(let [buffer (async/chan 99) ]
  (async/go       ; start sending loop in another thread
    (while true
      (Thread/sleep 3000)
      (let [val (rand-int 5) ]
        (println "putting:" val)
        (async/>!! buffer val))))
  (while true       ; start receiving loop in this thread
    (println "received:"
      (async/<!! buffer))))

带输出:

*clojure-version* => {:major 1, :minor 8, :incremental 0, :qualifier nil}
java.version =>  1.8.0_111
putting: 4
received: 4
putting: 1
received: 1
putting: 0
received: 0
putting: 0
received: 0
putting: 0
received: 0
putting: 1
received: 1
putting: 1
received: 1
putting: 0
received: 0
putting: 0
received: 0
putting: 0
received: 0
putting: 3
received: 3
putting: 0
received: 0
putting: 1
received: 1
putting: 4
received: 4
putting: 3
received: 3
putting: 2
received: 2
putting: 4
received: 4
每3秒钟一次。另请参阅:

http://www.braveclojure.com/core-async/

http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html

http://clojure.github.io/core.async/

https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj

https://www.infoq.com/presentations/clojure-core-async

https://youtu.be/enwIIGzhahw

答案 1 :(得分:2)

使用&#34;常规&#34;而不是使用传感器。 map(手动构造的列表不分块):

(doseq [t (map inc (infinite-updates))] (println t))