2012-09-03 8 views
6

Clojureから始めて、Rich Hickeyの講演で、Clojureの強みを基本的なものであるAnt-Simulatorに示しました。Clojure reference最新のプロジェクトですか?

このコードはまだClojureの良い参考資料と考えることができますか?特に、彼が再帰的にエージェントに関数を送信してゲームループをシミュレートするときの部分。 例:

(defn animation [x] 
    (when b/running 
    (send-off *agent* #'animation)) 
    (. panel (repaint)) 
    (. Thread (sleep defs/animation-sleep-ms)) 
    nil) 

編集:

私は#'リーダーマクロに興味を持っていますが、再帰的にエージェントまたはないで関数を呼び出す に慣用/良いClojureのが天気をよりないです。

+0

私たちはあなたを助けることができるように、投稿された特定のコードを投稿できますか?そうでなければ、私はこの質問がプログラマに属すると考えています。 – octopusgrabbus

+0

アニメを再帰的に '* agent * 'に送るときに、なぜ'#' 'リーダマクロが必要ですか? – noahlz

+2

これは、使用されるたびに 'animation'を評価します。このように 'アニメーション'は即座に変更することができます –

答えて

3

このスニペットは、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) 

モラルです:同期の計算のための薬剤を使いません。ユーザーに表示されるアニメーションの更新など、非同期の独立したタスクに使用してください:)

+0

ありがとう@noahz –

関連する問題