How to implement a Skynet 1m micro lens with core.async?

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?

+5
source share
1 answer

There are some restrictions on what core.async can do, so you cannot use map or for functions.

Your implementation is pretty close to correct. Some moments:

  • go == one process, so you just create one process, not 1m
  • <!! must be used outside the go block
  • <! should be used inside go blocks
  • You use for wrong
  • doall accepts only one parameter

A working implementation that can probably be improved:

 (defn skynet [parent num size div] (go ;; We create a new process each time skynet is called (if (= 1 size) (>! parent num) (let [self (chan) new-size (/ size div)] (dotimes [i div] ;; dotimes is more explicit for side effects (skynet self (+ num (* i new-size)) new-size div)) (loop [i div ;; Manual reduce t 0] (if (zero? i) (>! parent t) (recur (dec i) (+ t (<! self))))))))) 

And to call him:

  (time (do (def result (chan)) (def x (skynet result 0 1000000 10)) (<!! result))) 
+7
source

Source: https://habr.com/ru/post/1243018/


All Articles