Live data from Hacker News

Coroutines for Go

research.swtch.com

41–50 of 191 posts

Re: Coroutines for Go

#41

I have written Go professionally for many years now and don't want to see it become something like the Python Twisted / Tornado / whatever frameworks. The go keyword nicely prevents the annoying function coloring problem, which causes quite a bit of pain. Sometimes in high performance contexts I'd like to be able to do something like e.g. per CPU core data sharding, but this proposal doesn't scratch those kinds of it…

> The go keyword nicely prevents the annoying function coloring problem

FYI when you write a goroutine and have to use Context, that's literally just function coloring

Re: Coroutines for Go

#42

I have written Go professionally for many years now and don't want to see it become something like the Python Twisted / Tornado / whatever frameworks. The go keyword nicely prevents the annoying function coloring problem, which causes quite a bit of pain. Sometimes in high performance contexts I'd like to be able to do something like e.g. per CPU core data sharding, but this proposal doesn't scratch those kinds of it…

> The go keyword nicely prevents the annoying function coloring problem FYI when you write a goroutine and have to use Context, that's literally just function coloring

Ad absurdum, then anything other than full curried 1-ary-exclusive functions is coloring.

You can easily bridge context-using and non-context-using code, you can have nested contexts, you can have multiple unrelated contexts, you can ignore the context, probably most critically you can't pass values back up the context, I don't see any way these look like function coloring.

Re: Coroutines for Go

#43

It looks like a lot of people are missing the point here. Yes a coroutine library would be a worse/more cumbersome way to do concurrency than the go keyword. 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/obvious to most Go programmers.…

I think it's also worth mentioning that for 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. If you have two cooperating tasks that are logically synchronous anyway (e.g. an iterator) it's much more efficient to just run everything on the same CPU because the kernel doesn't have to reschedule anything or power down/wake up CPU cores, and the data is in the right CPU caches, so you'll get better cache latency and hit rates. With goroutines this may happen anyway, but it'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.

Google has internal kernel patches that implement cooperating multithreading this way (internally they'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: https://www.youtube.com/watch?v=KXuZi9aeGTw

Re: Coroutines for Go

#44
post #35

It looks like a lot of people are missing the point here. Yes a coroutine library would be a worse/more cumbersome way to do concurrency than the go keyword. 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/obvious to most Go programmers.…

What is wrong with: for { next := getNext() ... } What is the advantage of writing this as: for next := range getNext { ... }

In practice the difference would be closer to:

    getNext := iterableThing.Iterator()
    for {
        next, ok := getNext()
        if !ok {
            break
        }
        ...
    }
vs.

    for next := range iterableThing.Iterator() {
       ...
    }
One advantage is that it's slightly shorter, which matters for very common patterns--people complain about `err != nil` after all. Another advantage is there isn't another variable for everyone to name differently. Another advantage is that everyone can't do the control flow slightly differently either.

Re: Coroutines for Go

#45
post #37
post #36

Earlier quoted context omitted.

The first doesn't do control flow

Depends how getNext is defined.

The only way to do control flow in getNext, consistent with how you partially defined it, is to panic. That means there is some important code wrapping the whole loop body that you left out.

Re: Coroutines for Go

#46

Earlier quoted context omitted.

> The go keyword nicely prevents the annoying function coloring problem FYI when you write a goroutine and have to use Context, that's literally just function coloring

Ad absurdum, then anything other than full curried 1-ary-exclusive functions is coloring. You can easily bridge context-using and non-context-using code, you can have nested contexts, you can have multiple unrelated contexts, you can ignore the context, probably most critically you can't pass values back up the context , I don't see any way these look like function coloring.

Not sure about in Python, but in Rust, you can easily bridge sync and async code. The function coloring problem is, at least in that case, grossly overstated.

Re: Coroutines for Go

#48

I have written Go professionally for many years now and don't want to see it become something like the Python Twisted / Tornado / whatever frameworks. The go keyword nicely prevents the annoying function coloring problem, which causes quite a bit of pain. Sometimes in high performance contexts I'd like to be able to do something like e.g. per CPU core data sharding, but this proposal doesn't scratch those kinds of it…

Coroutines and goroutines fill different niches. The latter already fill the niche the likes of Twisted fill. There's nothing here trying to pull anything akin to async/await into Go.

Coroutines will fill a different nice more akin to Python's generators. There are a whole bunch of places where this could dramatically cut down on memory usage and code complexity where you have a composable pipeline of components you need to glue together. The design appears to me to be entirely synchronous.

Re: Coroutines for Go

#49

I don’t think Coroutines would fit in with Go. There is a huge emphasis on simplicity. Coroutines add a massive amount of complexity. In addition, goroutines provide the best parts of Coroutines - cheap, easy to use, non-blocking operations - without a lot of the pain pints such as “coloring” or functions and issues with using things like mutexes. Just the question of whether one should use a goroutine or a coroutine…

There are plenty of complicated things in Go, IMHO where it shines best is judiciously providing incredibly nice interfaces atop the complicated things.

Re: Coroutines for Go

#50

I don’t think Coroutines would fit in with Go. There is a huge emphasis on simplicity. Coroutines add a massive amount of complexity. In addition, goroutines provide the best parts of Coroutines - cheap, easy to use, non-blocking operations - without a lot of the pain pints such as “coloring” or functions and issues with using things like mutexes. Just the question of whether one should use a goroutine or a coroutine…

There's no colouring here. These are synchronous coroutines.
Post reply on HN