That documentation starts out with “Coroutines can be executed concurrently”. Multiple coroutines running concurrently is the only scenario it’s taking about. The var in distinctUntilChangedBy is only ever accessed by one coroutine. The code that touches it all runs sequencially. collect processes items one at a time so the var is never touched by multiple threads at the same time.
It’s mutable state that can only be accessed by one execution of code
Yeah, but the coroutine can be still executed on different threads which could lead to problems - eg. something has to ensure that cpu caches are properly flushed to main memory - otherwise each thread could see different data.
I though that coroutine is compiled as a class and coroutine’s local variables become instance variables of that class + there is an instance variable which says at which suspension point was coroutine suspended?
I do not know the exact implementation details, but there is a class involved somewhere of course.
The point is that the coroutine framework takes care of thread synchronization, and you can use local variables as local variables. You do not have to worry about synchronization issues when writing a coroutine. That is what makes them powerful: they are easy to reason about.
Just a small warning, this was the design document for the implementation of coroutines. There might be a few minor changes to coroutines since this was written. However the basic idea of how coroutines work internally should still be the same.