Skip to content

Latest commit

 

History

History
197 lines (163 loc) · 5.08 KB

core.async.md

File metadata and controls

197 lines (163 loc) · 5.08 KB

class: center, middle, title title: Short Intro to core.async

Short Intro to core.async


Sources


About Me

4clojure stats

About core.async

  • Implementation of Communicating Sequential Processes (CSP)
  • Provides a Channel abstraction
  • Similar to how Go(lang) implemented Channels
  • Works well in both Clojure and ClojureScript

Leiningen coordinates

;; in project.clj
(defproject my.project "0.1.0-SNAPSHOT"
  ;; ...
  :dependencies [ ;; ...
  [org.clojure/core.async "0.1.267.0-0d7780-alpha"] ;; ...
;; in your code that uses core.async
(ns my.project.core
  (:require [core.async :as async
             ;; commonly:
             :refer (go put! take!)]))

Channels

  • You can create them
    • without a buffer
      (def a-channel (chan))
    • with a buffer of size n
      (def a-channel (chan n))
      chan

Channels - close

  • You can close them
      (close! a-channel)
    close!

Channels - put

  • You can put things onto them
    • parking - only in go block
      (>! a-channel 100)
    • blocking
      (>!! a-channel 100)
    • non-blocking
      (put! a-channel 100)
      >! | >!! | put!

Channels - take

  • You can take things off of them
    • parking - only in go block
      (<! a-channel)
    • blocking
      (<!! a-channel)
    • non-blocking
      (take! a-channel)
      <! | <!! | take!

Go macro

<iframe src="//clojure.github.io/core.async/index.html#clojure.core.async/go" scrolling="no" style="width: 80%; height: 10em; overflow: hidden"></iframe> --
Rewrites your code using crazy inversion-of-control macros, creating a state machine scaffolding for turning blocking takes/puts into parked, individual lightweight threads

Go macro

  • .strike[Rewrites your code using crazy inversion-of-control macros, creating a state machine scaffolding for turning blocking takes/puts into parked, individual lightweight threads]
  • Allows you to write blocking code as if it weren't
    (let [c (chan)]
      (go
        (println (<! c)))
      (go
        (>! c :some-value)))
    ;; => prints :some-value
    ;; despite the take appearing before the put

alts! and alts!!

  • Perform the next available operation on a set of channels
  • Go(lang) select, similar to Linux select call
    (def a (chan))
    (def b (chan))
    (put! a 42)
    (alts!! [a b])
  • alts! - in a go block
  • alts!! - outside

alts! | alts!!


Types of channels

timeout

  • Times out after n milliseconds
  • Useful with alts!/alts!!
    (let [c (chan)
          t (timeout 100)]
      (let [[v ch] (alts!! [c t])]
        (prn {:ch ch :v v})))

Types of channels

dropping buffer

  • When full, puts can complete, but won't have any effect
    (async/dropping-buffer n)

dropping-buffer


Types of channels

sliding buffer

  • When full, puts can complete, but first item still in the channel is dropped
    (async/sliding-buffer n)

sliding-buffer