To try to understand core.async, I unsuccessfully tried to implement a “Skynet 1 million microchips”, which:
Creates an actor (goroutine, whatever) that spawns 10 new actors, each of them spawns 10 more actors, etc., until there are a million actors created at the final level. Then each of them returns its serial number (from 0 to 999999), which are summed up to the previous level and sent back upstream until it reaches the root actor. (The answer should be 499999500000).
The implementation is implemented in many languages:
https://github.com/atemerev/skynet
Here is my completely 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 (* in)) n div)) (for [i [0 div]] (<! rc))))))))
And I tried to call all this from inside the go block on REPL:
(time (go (<!! (skynet (async/chan) 0 1000000 10))))
I was probably seriously confused in many things regarding core.async (and lazy rating too).
How can I solve this problem and why?
source share