Async: Magical Realism in Computing
We are living in the era of the asynchronous — the promise land of everything will work out or will go terribly wrong but not just yet so keep on pushing. This movement has not only infiltrated our machines and how they run software but also our collaborations in extreme ways.
Every time I think of async, the epitome of asynchronous processes, I remember this unfortunate scene of the TV show Narcos about magical realism. Magical realism is a style of fiction popularised by Gabriel García Márquez that combines a genuine realistic description of the world with magical elements. I also remember every time I had to communicate with some governmental body or giant corporation and the stress of not knowing if and when you will hear from them.
Asynchronous programming is like writing a novel in the style of magical realism with the difference that machines are your readers and they don’t have feelings. On that note, software development is often portrayed as nurturing a living being — how many software developers have referred to some code as their baby? As I mentioned in my previous post, software is not real. As a software developer, whatever needs you might perceive from your software are coming from its users. You don’t get an email from your main function complaining that it is hurting — you fix some bug because it impacts someone that you care about; you refactor an API because it eases up the development of another module, etc… The fact that most of the times that person you care about is yourself shouldn’t make you believe that some git repository is alive — that’s magical realism.
In the need for speed, it is no surprise that the advent of asynchronous processing first started in hardware. There was probably a time when you could find someone at Intel who could tell you in great detail how a microprocessor behaves. Given that the current Intel Software Developer manual has 4922 pages, I think it’s safe to say that this is no longer the case. Certainly, from the perspective of a developer, understanding how the code is going to be executed can be perceived as magical. This is often the case for web developers because of the nature of interactions and the wish to entertain users. Make no mistake, hiding computation with async can only be useful if you are not giving up your understanding of what the code can do.
Having spent several years working on verification of concurrent programs, it is still surprising for me to hear developers say that “concurrent or parallel programs are very hard to understand” when the vast majority of developers are doing some form of asynchronous programming on a daily basis. I consider asynchronous programming (specially with dynamic languages) to be concurrent programming on steroids. My working hypothesis is that this could be connected with the fact that most developers are encouraged to start coding without a mental model of what the code is suppose to do. In fact, reading this discussion on Hacker news, it seems that having mental models is a feature of senior engineers.
There is not much hope for a breakthrough in the automated tools developers can use to better understand code if themselves are not willing to provide clues of what their code is supposed to be doing at a higher level of abstraction. A representation of this high level of abstraction is this mental model — sharing those models with your colleagues in a synchronous way is an excellent way to establish a common vocabulary that enables sustained high-productivity.
We live in the most connected world in human history yet our interactions are shortening and becoming more impersonal. Asynchronicity is a trade-off between individual processes: understanding and time usage. You can’t understand and predict the output of your team members if you don’t spend the time with them — and that can be a huge time saver down the road. The same goes to code — don’t fall in the trap of magical realism.