Users of coroutine-friendly libraries will have to adopt the async function coloring (co_await, co_yield, co_return, Task<T>).
So saying that coroutines are low-level / not application code is misguided.
So saying that coroutines are low-level / not application code is misguided.
It's pretty easy to write a library with them (using your own executor) and not reveal their use to the user.
Obviously sharing an executor between application and library is another matter.
Especially when there is not one, but several libraries, and the application itself doesn't actually has or uses any executors, now that's a fun challenge.
Although doesn't that defeat the purpose of structured concurrency?
i.e. creating tasks that are plumbed to some background thread/executor.
By directly invoking the coroutine, lifetime issues become much easier to avoid.