
Taming the Asynchronous Beast with CSP in JavaScript - jlongster
http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript
======
craigching
He mentions using CSP with JavaScript:

> It's safe to say that it's becoming quite popular (and validated) and I
> think we need to try it out in JavaScript.

To be clear, and he mentions that Clojure has core.async, it's been done in
JavaScript (if you will) already via ClojureScript.

David Nolen has done a series of posts on it starting at [1].

[1] -- [http://swannodette.github.io/2013/07/12/communicating-
sequen...](http://swannodette.github.io/2013/07/12/communicating-sequential-
processes/)

EDIT: And I should have finished reading the post before posting this. He does
mention David Nolen's series of posts on ClojureScript and core.async

------
tracker1
What would be nice as an addendum to this, especially with the likes of
browserify and webpack for node and the browser would be a syntax to start an
async channel in a new process/webworker...

    
    
        var ch = new echan('moduleName');
    

Where the moduleName would be a module that exports a single function that
receives two channels.. in, and out for a request/response pattern. An "easy"
level of abstraction here where the request/response is only going to pass
what works with JSON.stringify/parse, removing circular references.

It could work really well for worker handlers... It only needs to be an
abstraction around the csp interfaces, as well as the current implementations
for web workers and forked processes in node.js

More advanced scenarios could use 0mq for passing a worker to multiple
processes... all of that said, it's just an idea.

I think where this lines up very cleanly is as a means of communication with
React and flux.

------
pablovidal85
I translated the pingpong example to use events instead of CSP.
[https://gist.github.com/aynik/94c9f3d01139986d2b91](https://gist.github.com/aynik/94c9f3d01139986d2b91)

------
kylebrown
Even mentioned transducers, cool! But, I was hoping for a treatment of CSP and
react/flux. jlongster teased us about that here[1]. Maybe the next post in the
series? (plz?)

1\. [https://justin.harmonize.fm/development/2014/08/05/om-and-
fl...](https://justin.harmonize.fm/development/2014/08/05/om-and-
flux.html#comment-1532327194)

------
BrianEatWorld
My understanding of Javascript is that it is essentially single-threaded.
Maybe I am mistaken, but if that is indeed the case, how does something like
JS-CSP or Clojurescript's core.async accomplish concurrency? Has there been a
change in the underlying Javascript? Is it just using tricks to make single-
thread act like multi-thread?

~~~
dminor
Say you have:

    
    
      function one() {
        console.log("one");
        setTimeout(one, 1000);
      }
      
      function two() {
        console.log("two");
        setTimeout(two, 2000);
      }
      
      one();
      two();
    

They are executing concurrently, but never in parallel (since javascript is
single threaded).

Now, how do you coordinate them if you need to? This is what CSP helps you do.

~~~
lbradstreet
I've spent a fair amount of time in core.async, and I feel like I'm on the
edge of enlightenment here, but I don't quite understand how CSP helps with
this example. Is the point that you can take multiple puts off the channel in
one go? That's the only thing I can think of.

Maybe you could present the CSP alternative, and a basic example use case?

* edit: I guess a basic example is a sliding-buffer that only keeps, and thus only reacts to, the last mouse event. Is this on the right track?

~~~
dminor
The example was more about showing that concurrency and threads are not
synonymous, but you can imagine one of the functions producing a stream of
values and the other waiting for and consuming them.

In vanilla javascript, you have to resort to breaking your code up into
callbacks, which looks trivial in a two function example but becomes unwieldy
once you add a few layers and do error handling.

With CSP you organize your code around channels according to the code's logic,
rather than according to the needs of coordination. This makes things like
error handling and reasoning about your logic much simpler.

~~~
lbradstreet
I totally agree that it helps with callback hell / reasoning, but I think your
argument was more about coordination. Hence the sliding buffer example -
something that would be very, very hard to /coordinate/ with callbacks.

------
vfclists
Why doesn't he state what CSP is upfront, requiring the reader to visit
Wikipedia to know what it is?

Buzz words and acronyms are getting out of hand on the web.

------
thesorrow
How does this compare to FRP style ?

~~~
jlongster
It's more general than FRP so is better at stuff like simple async
coordination (what most people use promises for). But you can easy do FRP-
style stuff on top of channels, which is basically what transducers are. So
they are closely related, but have different roots.

~~~
gozala
Rather than saying that CSP is more general, I'd say CSP is more provides you
a more low level constructs. In FRP signals are the key concept that represent
value that changes over time. Signals have a pushed based interface that's
kind of why it's reactive. FRP typically provides pure functional interface,
meaning you never put values or emit events, you just have control flow
structures that allow you define transformations over base signals. FRP
signals can be easily implemented via CSP channels, but not other way round,
that's because CSP channels are push based for the producer side and pull
based from the consumer side.

If I had to make an analogy channels would be queues while signals would be an
observable variable.

------
neilellis
You've got to wonder why exactly we still (in 2014) have to contort ourselves
around a single threaded model. So that we end up with this level of
complexity.

JavaScript is great with data but is becoming a monstrosity when it comes to
concurrency.

Can we all stop and have a deep look at how other languages deal with
concurrency. I have (like many of you) used many different languages and have
played with several different concurrency models. The bottom line for me is
that multiple threads + concurrency frameworks (i.e. no exposed concurrency
primitives) are still the best solution.

I appreciate JavaScript is trying to avoid deadlocking etc. but in modern
concurrency frameworks this just isn't an issue.

Seriously we're now contorting ourselves around dogma. Please browser folk,
come up with a decent solution to save us all of this.

VOTED DOWN FOR HERESY :-)

~~~
swannodette
It's not clear to me that you actually read the article since a large part of
it is about elegantly dealing with streams of UI events such as mouse movement
without resorting to callbacks. Not sure how multithreading even applies here.
But if you want to talk about multithreading the model described is exactly
the one embraced by a new up and coming language called Go - it's users love
this stuff precisely because it's more readable than writing code with
explicit threads and concurrent queues.

~~~
neilellis
So I'll avoid the potential language flame war as best as I can.

It is the sync on async part I am talking about (see code snippet in sub
thread). The layering of synchronous constructs on an asynchronous model which
only exists to support the single threaded browser model is getting very
convoluted. That's the part I'm talking about.

It is perfectly reasonable and trivial to support a multithreaded model in the
browser if the multi-threaded code does not alter shared state. Which
obviously is the intention of Web Workers and in there case there state seems
to be primarily the DOM, I just feel that this is the direction we and browser
developers should be looking into more and where the effort needs to be. And
that Web Workers are part of the story not the story.

In my experience concurrency can be kept to a remarkably simple level if
either the developer or the language/framework author are willing to follow
some simple constraints. In my ideal world:

    
    
         var x= concurrent(function(x) {
             return doSomething(x);
         })(1000);
    

Would execute the function without any closure or access to globals (like the
DOM). Now we have no shared state, so we could run this function in a parallel
thread. Now add back access to stateless resources like HTTP requests and
we're rocking and rolling.

Web Workers just seem to be a heavy handed approach to achieving this.

If there is a framework or method available to achieve this and I have missed
it out of ignorance please someone correct me and show how this can be done
simply. My goal is to have simpler code not to win an argument.

------
riffraff
funny, i read that as CPS and it still made sense.

~~~
calebm
Same here.

