這段代碼目前在Clojure 1.4中。一個函數將任務提交給調用它的代理是否是慣用的?是。
下面是一個使用類似的方法來遞歸地計算一個階乘的例子:
(defn fac [n limit total]
(if (< n limit)
(let [next-n (inc n)]
(send-off *agent* fac limit (* total next-n))
next-n)
total))
(def a (agent 1))
(await (send-off a fac 5 1))
; => nil
@a
;=> 120
更新
上面是一個人爲的例子,實際上不太好,因爲有一個各種遞歸調用send-off
和後來的await
之間的競爭條件。可能還有一些send-off
調用尚未添加到代理的任務隊列中。
我重新寫上面如下:
(defn factorial-using-agent-recursive [x]
(let [a (agent 1)]
(letfn [(calc [n limit total]
(if (< n limit)
(let [next-n (inc n)]
(send-off *agent* calc limit (* total next-n))
next-n)
total))]
(await (send-off a calc x 1)))
@a))
,並觀察到以下行爲:
user=> (for [x (range 10)] (factorial-using-agent-recursive 5))
(2 4 3 120 2 120 120 120 120 2)
user=> (for [x (range 10)] (factorial-using-agent-recursive 5))
(2 2 2 3 2 2 3 2 120 2)
user=> (for [x (range 10)] (factorial-using-agent-recursive 5))
(120 120 120 120 120 120 120 120 120 120)
這個故事的寓意是:不使用代理同步計算。將它們用於異步獨立任務 - 比如更新顯示給用戶的動畫:)
您可以發佈什麼特定的代碼,以便發佈問題,以便我們可以爲您提供幫助?否則,我認爲這個問題屬於程序員。 – octopusgrabbus
爲什麼遞歸發送'animation'到'* agent *'時需要'#''reader宏? – noahlz
每次使用時都會評估「動畫」。這樣'動畫'可以隨時更改 –