Ten fragment jest aktualny w Clojure 1.4. Czy funkcja, aby przekazać zadanie agentowi, który go nazwał, jest idiomatyczny? Tak.
Oto przykład, który wykorzystuje podejście podobne do rekurencyjnie obliczyć silnię:
(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
Aktualizacja
Powyższe jest wymyślony przykład i rzeczywiście nie jest dobre, ponieważ istnieje stan wyścigu między różnymi wywołaniami rekurencyjnymi send-off
i późniejszym . Może być jeszcze kilka połączeń send-off
do dodania do kolejki zadań agenta.
I ponownie napisałem wyżej, co następuje:
(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))
i zaobserwować następujące zachowanie:
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)
Morał z tej historii jest taki: Nie używaj środków do synchronicznych obliczeń. Używaj ich do asynchronicznych zadań niezależnych - takich jak aktualizowanie animacji wyświetlanych użytkownikowi :)
Jaki konkretny kod został snipped możesz opublikować, aby można było podać problem, abyśmy mogli Ci pomóc? W przeciwnym razie myślę, że to pytanie należy do programistów. – octopusgrabbus
Dlaczego potrzebne jest makro czytnika '# '' podczas rekursywnego wysyłania 'animation' do' * agenta * '? – noahlz
Wylicza "animację" za każdym razem, gdy jest używana. W ten sposób 'animacja' może być zmieniana w locie –