I’ve been telling people that Sync means “happening at the same time” and Async means “Not happening at the same time”. And people have challenged me for this interpretation, but I stand by it. Not only is it the dictionary meaning, but it’s also the logical CompSci way to interpret them. And I’ll explain:
In a single threaded computation model, things can never happen at the same time unless concurrency is added, such as a process that starts and interrupts half-way (by cooperatively yielding), and another process is started to execute to completion, and then the prior process is resumed. And with multi-threaded you get parallelization, where many things can run at the same time.
So in the case of concurrency and parallelization, you have the case of two or more processes which run at the same time.
;; Doing two things in parallel
(future (do-something))
(future (do-something-else))
;; Doing two things concurrently
(let [continue (do-something)] ;; do-something will yield half-way
(do-something-else)
(continue)) ;; call the function returned by do-something to finish what it was doing
Now, if do-something
and do-something-else
can be executed “at the same time”, you don’t need asynchronous programming at all. That’s right, you need absolutely no mechanism to “synchronize” them. You don’t need callbacks, you don’t need .then
, you don’t need await
, you don’t need <!
, etc.
The reason you don’t need async programming features, is because both operations can happen synchronously, meaning, they can happen at the same time.
What if they can’t happen at the same time? Well you need asynchronous programming features then, because you need a mechanism to enforce that they do not happen synchronously, meaning that they do not happen at the same time.
So you see, if you have concurrent or parallel processes, but the order in which they execute matters, you need to make your code asynchronous, so that you can enforce the order in which they must execute.
Now where I think it gets confusing, is that we say we need to synchronize concurrent or parallel code which cannot run at the same time, and that’s true. This is because to synchronize
means to make synchronous in operation
. And this is exactly what we want.
If we have code that cannot be run synchronously, meaning it cannot be run at the same time, we want to transform this code into code that can be run synchronously, meaning that it becomes code that can be run at the same time. This is done by using asynchronous programming, which is the technique of taking code that was running at the same time (but shouldn’t be), and making it so it does not run at the same time, thus asynchronously.
I know this is confusing, so let me recap.
If you add concurrency or parallelization to some code, you make it so that multiple processes can run at the same time. So you made the code synchronous (happening at the same time). Now, while you made it so multiple processes do run at the same time, logically it might be that they shouldn’t be running at the same time, because that leads to race conditions and other bugs and logical error in your program. So you need a way so that the code that is now running at the same time (due to added concurrency or parallelization) is made so it doesn’t run at the same time, even in the presence of such concurrency or parallelization. So you need to make the code asynchronous (not happening at the same time).
There you go
Now you might say, but what’s the point of making the code synchronous by adding concurrency or parallelization, only to go and make it asynchronous again after, why add the concurrency and parallelization to begin with? What a good question! The answer is this would be absolutely stupid, and you’d only make the code slower overall then simply keeping it single threaded without concurrency or parallelization, except for the fact that in reality, you don’t make all of your code asynchronous, only the bits that cannot run at the same time.
What do you think?