このスニペットは、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
アニメを再帰的に '* agent * 'に送るときに、なぜ'#' 'リーダマクロが必要ですか? – noahlz
これは、使用されるたびに 'animation'を評価します。このように 'アニメーション'は即座に変更することができます –