Clojure
ClojureScript vs clojure.core.async
I’m going to make a somewhat bold statement: core.async
does not work with ClojureScript. And, in this post, I’m going to show some examples why this is true, at least for the current versions of core.async.
So let’s start by understanding a little bit about the runtime: Javascript is a single-threaded runtime that implicitly runs an event-loop. So, for example, when you ask to read a file, you can do it synchronously or asynchronously. If you decide to run in that asynchronously, it means that as soon as you issue the fs.readFile
command, you need to register a callback and the control is returned to the “main thread”. It’ll keep running until it runs out of commands to execute, then the runtime will wait the result from the callback; when it returns, the function that you registered will be called with the file contents. When the function ends, the JS runtime will await to see if there’s any other pending call, and it’ll exit if there’s nothing else to do.
The same thing happens in browser environment, but in this case the callbacks are events from the DOM: like clicking on buttons or listening for changes in some elements. The same rules apply here: the runtime is single threaded and when something happens it will first execute everything that needs to be executed, then it will be called back with the event that happened.
So maybe we can change these callbacks with core.async
channels right? But the answer is no, because core.async
s go
blocks will not run in different threads (because, again, the runtime is single-threaded). Instead, it creates a state machine and it’ll control of when each of these go
blocks will be called, at what time, eventually replacing the event-loop that Javascript environment already have.
(more…)