Even though the goal of the coroutine library is to abstract away threads and simplify concurrent programming, all functions—suspending or normal—must eventually run on a thread somewhere at some time. We can hide the thread mechanism from the user, but ultimately it is still a key part of how operating systems schedule and execute processes.
Therefore, in order to execute our suspendable functions they must run in some kind of container or task that utilizes a thread. This container or task is what is called a coroutine. Although each coroutine must run on a thread, they are not bound to any particular thread, and the actual thread may change when a function is resumed after suspension.
In order to invoke a suspendable function, we first must create the coroutine that will contain it. This is achieved using a coroutine builder. A coroutine builder...