I often hear that if a distinction exists, it should be represented in the type system; functions are either async or not, so we should track it at compile time. The thing most people don't understand about language design is that if you follow this line of thinking to the extreme, your complexity goes through the roof as all of the infectious constraints spread upward through your call graph, sometimes conflicting w…
I think the view of asynchronous functions as "upwardly infectious" comes from focusing too much on JavaScript. Async/Await arguably[1] first debuted on C#, and in C# you could always call Task.Wait() or Task.Result to block on the Task returned from the code. Similarly, Python async coroutines can be run from blocking functions using event_loop.run_until_complete(coroutine). Kotlin similarly has runBlocking(). Runni…
AFAIK, they only pin the thread. They are absolutely callable, you just don’t get all the advantages.