In order to try to understand core.async, I unsuccesfully tried to implement the "Skynet 1 million microbenchmark", which is:
Creates an actor (goroutine, whatever), which spawns 10 new actors, each of them spawns 10 more actors, etc. until one million actors are created on the final level. Then, each of them returns back its ordinal number (from 0 to 999999), which are summed on the previous level and sent back upstream, until reaching the root actor. (The answer should be 499999500000).
There are implementation in many languages here:
https://github.com/atemerev/skynet
Here's my totally broken attempt:
(defn skynet [chan num size div]
(if (= 1 size)
(>! chan num)
(>! chan (reduce + (let [rc (async/chan)
n (/ size div)]
(doall (for [i [0 div]]
(skynet rc (+ num (* i n)) n div))
(for [i [0 div]] (<! rc))))))))
And I was trying to call it all from inside a go block at the REPL:
(time (go (<!! (skynet (async/chan) 0 1000000 10))))
I'm probably seriously confused about many things concerning core.async (and lazy evaluation too).
How should I go about solving this problem and why?