Coroutines are a powerful general control abstraction that were introduced in the early 1960s. It is attributed to Conway, who described coroutines as “subroutines who act as the master program.”
Their ability to express several useful control behaviours was explored in the next 20 years, including simulation, artificial intelligence, concurrent programming, text processing, and various kinds of data-structure manipulation.
But language designers have since disregarded providing a programmer with this powerful control construct (barring a few exceptions), and we will explore several interesting reasons why, ranging from not having a precise definition and semantics, to the introduction of Algol-60.
Go provides powerful primitives for concurrency and parellelism, but Coroutines are not a pattern provided natively.
We see how in certain specific use cases coroutines are much more efficient than a full goroutine, because switching to/from a coroutine doesn’t require context switching or rescheduling anything. Also, function iterators, where range can be used on functions of type func() (T, bool). This has been discussed in the Go community for a long time, and can be achieved using Coroutines intuitively.
How can we go about designing these control structures in Go? We dive into the fundamentals of Coroutines, a brief look at its history and slowly build up to a Full Asymmetric Coroutine from its less general forms, and how this very expressive abstraction can be implemented using Goroutines, Channels and other existing Go definitions. Russ Cox’s recent proposal for this is a great case study to explore how we can achieve this, as well as improvements to the runtime to make this even more efficient.