2014-10-30 56 views
8

Rich Hickey's Strange Loop transducers presentation告訴我們在Clojure 1.6中有兩個實現map,一個用於clojure.core中的序列,另一個用於core.async中的通道。core.async是否可以通過序列實現它的功能?

enter image description here

現在我們知道,在1.7,我們有傳感器,爲此,foldrreduce)功能從高階函數給出的函數,但不是一個集合返回時像mapfilter

我想表達和失敗的是,爲什麼core.async函數不能返回序列,或者是類似於Seq。我有一種感覺,'界面'(協議)是不同的,但我不明白。

當然,如果您將第一個項目從頻道中取出,那麼您可以將第一個項目表示爲序列?

我的問題是:難道core.async已經在序列方面實現了它的功能嗎?

回答

7

是的,從某種意義上說,他們本來可以。如果你忽略了去塊(此刻,讓我們這樣做),那麼就真的沒有錯,像下面這樣:

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

但這裏需要注意的<!!電話。這被稱爲「take blocking」:在這個函數內部有一些promise和鎖,它們會導致當前正在執行的線程暫停,直到通道上有值。所以如果你不介意讓Java線程坐在那裏無所事事,那麼這將工作得很好。

go blocks背後的想法是讓邏輯進程更便宜;爲了實現這一點,go塊將塊的主體重寫爲連接到該頻道的一系列回調,以便在內部對go塊內的<!的調用變成類似這樣的(take! c k),其中k是回調到休息區的其餘部分。

現在,如果我們有真正的延續,或者如果JVM支持輕量級線程,那麼是的,我們可以結合go-blocks和阻塞需求。但是,目前這涉及深度字節碼重寫(如Pulsar/Quasar項目)或一些非標準的JVM特性。在創建core.async時,這兩個選項都被排除在外,而更容易實現(並且希望更簡單地推理)本地塊轉換。

相關問題