Saturday 1 August 2015

Go Play

I've been reading up on core.async lately, mainly because of its shared semantics with Go and alleged benefits of the CSP model.

The literature around core.async is a little sparse, though it is simple enough to pick up.
The main benefits (as I understand them) are:
  1. Uses lightweight threads for concurrency
  2. Redeems asynchronous code from callback hell 
Time to see it in action:

(require '[clojure.core.async :refer [chan go alt! >!]])

(def even (chan))
(def odd  (chan))

(go (while true
  (alt!
    even ([v] (println "Got" v "from even"))
    odd  ([v] (println "Got" v "from odd")))))

(go (doseq [i (range 0 10 2)]
      (>! even i)
      (Thread/sleep (rand-int 1000))))

(go (doseq [i (range 1 10 2)]
      (>! odd i)
      (Thread/sleep (rand-int 1000))))

Here's what's happening above:
We create two 'channels' - even and odd
Channels are very much like queues or conveyor-belts in that we can insert values on one end and retrieve values from the other.
We then create three asynchronous processes using go blocks -
  1. The first process has an infinite loop that 'listens' to our channels using alt!. If either of the channels has received a value, it prints some information to the console.
  2. The next two processes produce numbers from 0-9 at random intervals and put them on corresponding channels using the >! operator.
..and this is enough to get started!

In the real world, we can use channels to listen to changes in state such as mouse moves and key events, and update state accordingly. I might write a game using core.async soon.

This was fun!
---

EDIT: Find this and other core.async examples here.