Thanks. This was a great read!
It’s always struck me as odd that so few VMs have lightweight threads. I guess the model wasn’t really proven until Go took off a while back, even if it seems obvious in hindsight.
Maintaining a native runtime for all platforms is a lot to ask, and this has forced a lot of languages down the async/await path (though Clojure notably did CSP as a macro – Loom will be great for them). I expect that support from the JVM (and soon WASM) will have a big impact on language designs, and make the CSP model a lot more ubiquitous. Your move, dotnet!
The model was perfectly well proven by Erlang, in the 80’s. Go, by design, was nothing groundbreakingly novel.
Yes, BEAM is the major exception of course. Though it seems fair to say that both Erlang and its VM are relatively niche. I think Go brought some of those ideas to the mainstream and convinced a lot of people that this approach was right in practice, especially outside of functional programming. It was influential for Julia’s approach to concurrency, for example.
But I am speculating; if you know why more VMs are only just starting to have this feature, I’d love to hear it. As you say, the ideas have been around for a while, so something else must have changed.
I suspect it has more to do with the leveling out of clock speeds, and the dominance of imperative programming. Prior to about a decade ago, computers got faster by improving single-threaded performance. Single-threaded programs got faster because the hardware got faster, and as such there wasn’t a strong pressure to move towards more concurrent systems.
In this single-threaded world, imperative programming thrived. If it ain’t broke, don’t fix it and all that. Imperative languages, however, make the already hard problem of thread scheduling even harder. If you read the justifications for Erlang’s design decisions, functional programming wasn’t chosen on its own merits, but the ease of expressing a coherent concurrency model.
Fast forward to the early 2010’s, clock speeds level out. Moore’s law is now completely reliant on cramming more cores onto a CPU. There ought to be a hard push towards more concurrency, but it’s sluggish, because the question isn’t “how do we program with more concurrency?” it’s “How do we make our imperative languages more concurrent?” which is a much harder problem than the other, already hard problem.