Clojure Conj 2014 - Paradigms of core.async - Julian Gamble
-
Upload
julian-gamble -
Category
Technology
-
view
511 -
download
0
description
Transcript of Clojure Conj 2014 - Paradigms of core.async - Julian Gamble
Paradigms of core.async
Clojure Conj Washington Nov 2014
Julian Gamble @juliansgamble
Paradigms of core.async
Clojure Conj Washington Nov 2014
Julian Gamble @juliansgamble
Paradigms of core.async
Clojure Conj Washington Nov 2014
Julian Gamble @juliansgamble
Core.async is about:
Core.async is about:
• queues in your application
Core.async is about:
• queues in your application
• making your application simpler to reason about
Benefits
In this talk you will gain an understanding of: • go blocks and how they do concurrency • core.async queues
Benefits
In this talk you will gain an understanding of: • go blocks and how they do concurrency • core.async queues • go block timers • alts! macro and how it enables reading multiple queues
Benefits
In this talk you will gain an understanding of: • go blocks and how they do concurrency • core.async queues • go block timers • alts! functions and how it enables reading multiple queues • how core.async processes work in ClojureScript • the visual impacts of how the core.async function enables
simple ‘process-level’ pauses • how to use core.async to separate out the calculation and
display parts of your code
Benefits
In this talk you will gain an understanding of: • converting a Clojure code-base to ClojureScript • some tips for optimising ClojureScript
What is core.async?
What is core.async?
• A set of primitives for creating, reading and writing to queues
• A code walking macro that splices go blocks into state machines
What is core.async?
• A set of primitives for creating, reading and writing to queues
• A code walking macro that splices go blocks into state machines
• A mechanism for asynchronous computation
• A library in both Clojure and ClojureScript
What does core.async say about Clojure?
• core.async is implemented using a sophisticated Lisp macro - something only possible in a functional language
• in non-functional languages like Go and C# - CSP is achieved by compiler-extensions - whereas in a functional language like Clojure - this functionality comes as a mere library
What is CSP?• Communicating Sequential Processes
• Comes out of process calculi – an attempt in the 1960’s and 1970’s to optimise computer usage through specialised algebra.
What is CSP?• Communicating Sequential Processes
• Comes out of process calculi – an attempt in the 1960’s and 1970’s to optimise computer usage through specialised algebra.
• Based on message passing via channels
• Subject of 1978 Book by C.A.R. Hoare
basic example
-‐main function
first go block
second go blockmy-‐q>! <!
2-basic-example
2-basic-example
2-basic-example
2-basic-example
2-basic-example
basic example
[Demo]
basic example
basic multi-channel example-‐main function
first go block
third go block
my-‐q1>!
alts!
second go block my-‐q2>!
basic multi-channel example
[DEMO]
basic multi-channel example
Tim Baldridge 10K processes
make-‐scene function
make-‐cell function10K
go block 1. Set colour 2. Paint canvas cell 3. Pause for random interval 4. Loop
[DEMO]
not 10K processes
makeScene function10K
makeCell function
mainLoop function
100
[DEMO]
[DEMO]
swanodette 10K processes
[go block] let block
[go block] render-‐loop render!‘render’ ‘queue’
[idx v] [idx v]
core.async channel parameter passed in during function call
swanodette 10K processes
No more than 1024 pending puts are allowed on a single channel.
[go block] let block
[go block] render-‐loop render!‘render’ ‘queue’
[idx v] [idx v]
core.async channel parameter passed in during function call
[DEMO]
Events with core.async
-‐main function
listen to DOM event and return channel
[go block] print queue message
out/clicksput! <!
JS event queue
Parallelism is not Concurrency
Imagine streams of execution in your program
Parallelism is not Concurrency
Imagine streams of execution in your program
Parallelism is not Concurrency
Imagine streams of execution in your program
Parallelism1. For core.async "use it where ever you'd use a queue"
2. In the Tim Baldridge 10K processes example above - it is not explicitly using a queue
(<! (timeout (rand-int 1000)))))))
Parallelism1. For core.async "use it where ever you'd use a queue"
2. In the Tim Baldridge 10K processes example above - it is not explicitly using a queue
(<! (timeout (rand-int 1000)))))))
3. But in the same example - it is implicitly using the queue of the core.async process scheduler - so you're still using a queue.
4. Go blocks are the lightweight equivalent of 'heavyweight' threads
Parallelism1. For core.async "use it where ever you'd use a queue"
2. In the Tim Baldridge 10K processes example above - it is not explicitly using a queue
(<! (timeout (rand-int 1000)))))))
3. But in the same example - it is implicitly using the queue of the core.async process scheduler - so you're still using a queue.
4. Go blocks are the lightweight equivalent of 'heavyweight' threads
5. Heavyweight threads implicitly listen to the queue of the OS 'ready queue'
6. You're already implicitly using queues whenever you use threads.
Quick recap• core.async is all about queues
Quick recap• core.async is all about queues
• queues can used in your application for:
• parallelism
• separating the calculation from the display logic
• event handling
[DEMO]
Rich Hickey original ants demo
Rich Hickey original ants demo-‐main function
animation agent
ant behaviour agent
evaporation agent
world symbol (vector of vectors)
send-‐off send-‐offsend-‐off
Converting to ClojureScriptMissing functions in ClojureScript:
Converting to ClojureScriptMissing functions in ClojureScript:
• defstruct - replace with a map
• alter - replace with swap!
Converting to ClojureScriptMissing functions in ClojureScript:
• defstruct - replace with a map
• alter - replace with swap!
• sync
• dosync
• agent
ants cljs no asyncanimate function
send-‐off-‐animation function
behave-‐ants function
evaporate function
world symbol (vector of vectors)
single call single callsingle call
requestAnimationFrame (callback)
[DEMO]
Adding core.async
Adding core.async
• You can use a go block with a timeout queue in the same way you’d use a thread with a sleep function
adding core.async
adding core.async
[DEMO]
Using optimisations from David Nolen’s chambered example
• Macros for creating arrays and for-loops
• Underlying assumptions:
• cljs data structures are not yet fully performant - so consider replacing with arrays for speed
• The cljs compiler does not yet fully optimise higher order functions - the most efficient looping construct will be a for-loop macro that uses the loop function
Using optimisations from David Nolen’s chambered example
Using optimisations from David Nolen’s chambered example
[DEMO]
Back to The Italian Job
• Who or what was the hero of the story?
Summary• core.async is about using queues • core.async is about making your application simpler to reason about
Summary• core.async is about using queues • core.async is about making your application simpler to reason about • classic applications are: user interface events, presentation loops,
parallelism in non-parallel environments • you can consider a multithreaded application a queue listener even if
it doesn’t appear to use queues
Summary• core.async is about using queues • core.async is about making your application simpler to reason about • classic applications are: user interface events, presentation loops,
parallelism in non-parallel environments • you can consider a multithreaded application a queue listener even if
it doesn’t appear to use queues • in porting an application from Clojure to ClojureScript you have to
rethink your concurrency • There are lots of optimisations available to make ClojureScript
applications run faster • core.async is not a magic sauce you can sprinkle everywhere - know
when to use it
Questions?
Clojure Conj Nov 2014 Julian Gamble @juliansgamble
github.com/juliangamble/clojure-‐conj-‐2014-‐paradigms-‐of-‐core-‐async