Earlier quoted context omitted.
> By contrast, if you only have those other abstractions you're quite limited in how you can structure your code. OK... but what languages only have those abstractions?
I think it's fair to say that neither JavaScript, Perl, nor Python, notwithstanding Web Workers or rough POSIX threading support; but Lua and Scheme do even though their threading construct is not based on the system threading model (though strictly speaking it's likewise available to those languages). What I really meant to get at was that Go provides a flavor of threading that is lightweight, simple, and ergonomic.…
Ah yes, how could I forget Javascript :)
> The fact that languages like Python, C#, and C++ use async/await terminology shows how they put the cart before the horse
Of these, I'm very familiar with C# (15+ years' experience). C# had great threading constructs long before it added async/await, and still does. It actually provides a great variety of threading constructs - you can go low level with mutexes, wait handles, and threads; then there's the Task.Run abstraction, Parallel.ForEach, the TPL...
When async/await in C# was first announced, it was hailed as making concurrency much simpler for devs, but I've always found threads much simpler to reason about and debug, while async/await gives you a variety of footguns that can be difficult to debug.
FWIW, I've been using async/await in C# for years now, but coming from much more of a threading background, I confess it's only now beginning to feel intuitive. I dunno, maybe if new devs come to concurrency from the async perspective first, it's easier to grok.