Hacker News new | past | comments | ask | show | jobs | submit
> Async is not I/O. It can be used for I/O, but it's just a way of writing pure, deterministic state machines that keeps a logical flow together instead of scattered over a bunch of transitions.

I argue that it is exactly opposite. Blocking threads are a much more natural way of thinking about concurrency.

Quote from the erlang creator Joe Armstrong's thesis. He argues that the only way to understand multi-threaded programs is writing strictly sequential code for every thread and not muddling all the code for all the threads in one place:

"The structure of the program should exactly follow the structure of the problem. Each real world concurrent activity should be mapped onto exactly one concurrent process in our programming language. If there is a 1:1 mapping of the problem onto the program we say that the program is isomorphic to the problem. It is extremely important that the mapping is exactly 1:1. The reason for this is that it minimizes the conceptual gap between the problem and the solution. If this mapping is not 1:1 the program will quickly degenerate, and become difficult to understand. This degeneration is often observed when non-CO languages ["non concurrency-oriented", looking at you JavaScript!] are used to solve concurrent problems. Often the only way to get the program to work is to force several independent activities to be controlled by the same language thread or process. This leads to a inevitable loss of clarity, and makes the programs subject to complex and irreproducible interference errors." [0]

[0] https://erlang.org/download/armstrong_thesis_2003.pdf

It's interesting that we've gone from cooperative to preemptive to cooperative multitasking again.

I agree that blocking threads is generally more natural / obvious. Cooperative multitasking was always done for performance reasons and more recently for simplicity (in single thread implementations with no locking) and/or scaling reasons.

Message passing concurrency is going even further though, and never really seems to have taken off wholistically. Again, primarily for performance reasons. When we do pass messages (across networks, too/from RAM or disk, etc) we usually add caching and other optimizations which make concurrency even harder to reason about.