<story><title>Coroutines for Go</title><url>https://research.swtch.com/coro</url></story><parent_chain><item><author>alphazard</author><text>It looks like a lot of people are missing the point here.  Yes a coroutine library would be a worse&amp;#x2F;more cumbersome way to do concurrency than the go keyword.&lt;p&gt;The use case motivating all the complexity is function iterators, where `range` can be used on functions of type `func() (T, bool)`.  That has been discussed in the Go community for a long time, and the semantics would be intuitive&amp;#x2F;obvious to most Go programmers.&lt;p&gt;This post addresses the next thing: Assuming function iterators are added to the language, how do I write one of these iterators that I can use in a for loop?&lt;p&gt;It starts by noticing that it is often very easy to write push iterators, and builds up to a push-to-pull adapter.  It also includes a general purpose mechanism for coroutines, which the adapter is built on.&lt;p&gt;If all of this goes in, I think it will be bad practice to use coroutines for things other than iteration, just like it&amp;#x27;s bad practice to use channels&amp;#x2F;goroutines in places where a mutex would do.</text></item></parent_chain><comment><author>eklitzke</author><text>I think it&amp;#x27;s also worth mentioning that for certain specific use cases coroutines are much more efficient than a full goroutine, because switching to&amp;#x2F;from a coroutine doesn&amp;#x27;t require context switching or rescheduling anything. If you have two cooperating tasks that are logically synchronous anyway (e.g. an iterator) it&amp;#x27;s much more efficient to just run everything on the same CPU because the kernel doesn&amp;#x27;t have to reschedule anything or power down&amp;#x2F;wake up CPU cores, and the data is in the right CPU caches, so you&amp;#x27;ll get better cache latency and hit rates. With goroutines this &lt;i&gt;may&lt;/i&gt; happen anyway, but it&amp;#x27;s not guaranteed and at the minimum you have the overhead of going through the Go runtime goroutine scheduler which is fast, but not as fast as just executing a different code context in the same goroutine. Coroutines offer more predictable scheduling behavior because you know that task A is switching directly to task B, whereas otherwise the goroutine scheduler could switch to another available task that wants to run. The last section of the blog post goes into this, where Russ shows that an optimized runtime implementation of coroutines is 10x faster than emulating them with goroutines.&lt;p&gt;Google has internal kernel patches that implement cooperating multithreading this way (internally they&amp;#x27;re called fibers), and the patches exist for precisely this reason: better latency and more predictable scheduling behavior. Paul Turner gave a presentation about this at LPC ~10 years ago that explains more about the motivation for the patches and why they improve efficiency: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;www.youtube.com&amp;#x2F;watch?v=KXuZi9aeGTw&quot;&gt;https:&amp;#x2F;&amp;#x2F;www.youtube.com&amp;#x2F;watch?v=KXuZi9aeGTw&lt;/a&gt;</text></comment>
<story><title>Coroutines for Go</title><url>https://research.swtch.com/coro</url></story><parent_chain><item><author>alphazard</author><text>It looks like a lot of people are missing the point here.  Yes a coroutine library would be a worse&amp;#x2F;more cumbersome way to do concurrency than the go keyword.&lt;p&gt;The use case motivating all the complexity is function iterators, where `range` can be used on functions of type `func() (T, bool)`.  That has been discussed in the Go community for a long time, and the semantics would be intuitive&amp;#x2F;obvious to most Go programmers.&lt;p&gt;This post addresses the next thing: Assuming function iterators are added to the language, how do I write one of these iterators that I can use in a for loop?&lt;p&gt;It starts by noticing that it is often very easy to write push iterators, and builds up to a push-to-pull adapter.  It also includes a general purpose mechanism for coroutines, which the adapter is built on.&lt;p&gt;If all of this goes in, I think it will be bad practice to use coroutines for things other than iteration, just like it&amp;#x27;s bad practice to use channels&amp;#x2F;goroutines in places where a mutex would do.</text></item></parent_chain><comment><author>rcme</author><text>What is wrong with:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    for {
        next := getNext()
        ...
    }
&lt;/code&gt;&lt;/pre&gt;
What is the advantage of writing this as:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    for next := range getNext {
        ...
    }&lt;/code&gt;&lt;/pre&gt;</text></comment>