使用Clojure开始,我发现了丰富的希基谈话,他演示了Clojure的优势的一个基本蚂蚁模拟器 。
可以将此代码仍然被认为是Clojure的一个很好的参考? 尤其是当他递归发送关闭功能,代理部分模拟游戏循环。 例:
(defn animation [x]
(when b/running
(send-off *agent* #'animation))
(. panel (repaint))
(. Thread (sleep defs/animation-sleep-ms))
nil)
编辑:
我不感兴趣#'
读者宏但更羯羊它是地道/好Clojure的递归调用一个代理或不是一个函数。
这片段是用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)
这个故事的寓意是:不使用代理同步计算。 他们使用异步独立的任务 - 如更新显示给用户的动画:)