I'm trying to learn about how coroutines work in Kotlin. I've read several articles online, including this one - https://proandroiddev.com/demystifying-coroutinecontext-1ce5b68407ad - but I still find myself a bit confused about how coroutine elements in the current context can be accessed. Here's the part that's confusing me.
The elements in the current context can be obtained by using the top-level suspending coroutineContext read-only property.
println("Running in ${coroutineContext[CoroutineName]}")
In this case, CoroutineName is a reference to the key that maps to the CoroutineName element. I understand that the get method on the coroutineContext looks at the generic type of the key provided to it - in this case, CoroutineName - to get the appropriate element. What I'm trying to understand is how  CoroutineName, or for that matter Job, CoroutineExceptionHandler or CoroutineDispatcher are even available to refer to in the current scope, when they are not properties of the CoroutineScope receiver.