这段代码目前在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
每次使用时都会评估“动画”。这样'动画'可以随时更改 –