This is not dependent on the specifics of any of the proposals under discussion, but I wanted to explore a little bit what the introduction of async/await might mean for the way we program in the long term. I have just two related concerns at this point. I hope the proposers have considered these questions and have some answers, but I'd be interested in anyone's thoughts.
First, in discussing async algorithms with Eric Niebler, he made the case that composable algorithms depend on “deep support for cancellation”. In all of the concurrency systems I know of, that means async code doing significant computation needs to be written with periodic cancellation checks—not so often as to slow things down, but often enough to be responsive. To me that seems like a pain to get right. Is there anything we can do to address that?
Secondly I fear that, unless we have some way to write code that is generic over whether an algorithm is invoked from a synchronous or asynchronous function, it means any synchronous ordinary algorithm doing significant computation may be incompatible with composable async algorithms. Instead, we'll need an async copy of the algorithm that does these periodic cancellation checks. I suppose in the end this may be another argument for a generalized effects system in the language. Are there any alternative approaches?
It should be possible to build tools which measure how long an async function continues executing after it was cancelled, or how many times it suspended despite being cancelled, etc. That would allow developers to find a balance between the cost of checking cancellation and having more unwanted tasks that continue to execute.
I found this blog post to be an interesting discussion about cancelation and timeouts. I believe this was linked from the original concurrency design direction and it helped shape the "structured concurrency" part of the design.
These issues cleanly layer on top of async/await, so they aren't (and shouldn't be) part of the core async await proposal itself.
To be perfectly clear, I brought this up in a separate thread from the review specifically to avoid creating the impression that I was claiming it should have been addressed in the proposal.
A PGO-style approach is an interesting idea for getting the parameters right. I'm mostly concerned about what supporting this does to general program structure and reusable components. Will we find ourselves passing a “cancellation-checks-per-1M-elements” parameter to things like sort?