Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use core.async in Clojure?

When should I use Clojure's core.async library, what kind of applications need that kinda async thing?

Clojure provides 4 basic mutable models like refs, agents, atoms and thread locals/vars. Can't these mutable references provide in any way what core.async provides with ease?

Could you provide real world use cases for async programming?

How can I gain an understanding of it so that when I see a problem, it clicks and I say "This is the place I should apply core.async"?

Also we can use core.async in ClojureScript which is a single threaded environment, what are the advantages there (besides avoiding callback hell)?

like image 616
Ertuğrul Çetin Avatar asked Mar 18 '18 20:03

Ertuğrul Çetin


2 Answers

You may wish to read this:

  • Clojure core.async Channels Introductory blog by Rich Hickey
  • Mastering Concurrent Processes with core.async Brave Clojure entry

The best use case for core.async is ClojureScript, since it allows you to simulate multi-threaded programming and avoid Callback Hell.

In JVM Clojure, core.async can also by handy where you want a (lightweight) producer-consumer architecure. Of course, you could always use native Java queues for that, as well.

like image 170
Alan Thompson Avatar answered Sep 22 '22 19:09

Alan Thompson


It's important to point out that there are 2 common meanings associated to the word 'async' in programming circles:

  1. asynchronous messaging: Systems in which components send messages without expecting a response from their consumers, and often without even knowing who the consumers are (via queues)
  2. non-blocking (a.k.a event-driven) I/O: Programs structured in such a way that they don't block expensive computational resources (threads, cores, ...) while awaiting a response. There are several approches, with varying levels of abstraction, for dealing with such systems: callback-based APIs (low-level, difficult to manage because based on side-effects), Promise/Futures/Deferreds (representations of values that we don't yet have, more manageable as they are value-based), Green Threads ('logical' threads which emulate ordinary control flow, but are inexpensive)

core.async is very opinionated towards 1 (asynchronous messaging via queues), and provides a macro for implementing Green Threading (the go macro).

From my experience, if non-blocking is all you need, I would personally recommend starting with Manifold, which makes fewer assumptions about your use case, then use core.async for the more advanced use cases where it falls short; note that both libraries interoperate well.

like image 21
Valentin Waeselynck Avatar answered Sep 24 '22 19:09

Valentin Waeselynck