Live data from Hacker News

Coroutines for Go

research.swtch.com

61–70 of 191 posts

Re: Coroutines for Go

#61
post #33

Earlier quoted context omitted.

Coroutines are a control-flow mechanism. They're a single-threaded pattern in as much as for loops are a single-threaded pattern. Ability to write multithreaded programs does not exclude the need for good single-threaded tools.

Looking at python's asyncio coroutine library, they are just mocking multithreading with asyncio.gather. Since coroutines can be executed in any order they are not really control-flow mechanisms. The selling point of coroutines over traditional threads is its lightweight but its moot since goroutines has similar memory cost to coroutines. The only real benefit is that coroutines are non blocking while goroutines may…

I don't know about Python, but this description of coroutines, the general concept, doesn't seem accurate to me. They most definitely cannot be executed in any order. They also have nothing to do with multithreading whatsoever. Lua has the most honest-to-god implementation of coroutines I know of, so I'd suggest looking at that. I've seen the word "coroutines" used in some weird way suggesting multithreading, which probably means Python used them to fake multithreading, but the idea originally has nothing to do with it. The idea actually started out as a way to better structure an assembly program in 1958: http://melconway.com/Home/pdf/compiler.pdf>.

Re: Coroutines for Go

#63
post #10
post #9

Earlier quoted context omitted.

Goroutines + channels add an enormous amount of overhead. Using them as iterators is basically insane.

Why? Channels are already iterable using the range keyword. ch := make(chan int) go func() { for i := 0; i That is very simple.

Aside from the massive performance penalty, cache thrashing and context switching, this code will also leak a goroutine (and so, memory) if you don't finish receiving from `ch`. It's more brittle, longer to write, less local and in every other way worse than a for loop. Why would you ever do it?

Re: Coroutines for Go

#64
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 { ... }

Besides what everyone else said, the obvious advantage is the latter builds in the logic for exiting the loop once getNext has run out of elements in the slice/map. Your former example will need a final step that's like:

    ...
    if getNext() == nil {
      break
    }
    ...
This isn't a huge boon, and is mostly a matter of style. But I prefer the latter because it's logic that gets handled with the range builtin, so my code can be more about application logic, rather than muddling in breaking out of loop logic.

Re: Coroutines for Go

#65
post #33

Earlier quoted context omitted.

Coroutines are a control-flow mechanism. They're a single-threaded pattern in as much as for loops are a single-threaded pattern. Ability to write multithreaded programs does not exclude the need for good single-threaded tools.

Looking at python's asyncio coroutine library, they are just mocking multithreading with asyncio.gather. Since coroutines can be executed in any order they are not really control-flow mechanisms. The selling point of coroutines over traditional threads is its lightweight but its moot since goroutines has similar memory cost to coroutines. The only real benefit is that coroutines are non blocking while goroutines may…

Goroutines are non-blocking. Channels may not always be, however.

Re: Coroutines for Go

#66
Somewhat on topic given that OP brought up coroutines in Python: what resources have folks used to understand Python's asyncio story in depth? I'm just now finally understanding how to use stuff, but it was through a combination of the official documentation, the books "Using Asyncio in Python" and "Expert Python Programming", none of which were particularly good. Normally I'd rely just on the official docs, but the docs have created much confusion, it seems, because there's a lot in them that are useful more so for library/framework developers than for users. So, I'm just wondering if anyone has great resources for really gaining a strong understanding of Python's asyncio or how else you might have gone about gaining proficiency to the point where you felt comfortable using asyncio in real projects.

Re: Coroutines for Go

#67

Somewhat on topic given that OP brought up coroutines in Python: what resources have folks used to understand Python's asyncio story in depth? I'm just now finally understanding how to use stuff, but it was through a combination of the official documentation, the books "Using Asyncio in Python" and "Expert Python Programming", none of which were particularly good. Normally I'd rely just on the official docs, but the…

I read the same books you did, and I was equally unsatisfied afterwards. The "Using Asyncio in Python 3" book was good enough to help me write some code that had to hit an API 400k times without blocking, but I never returned to asyncio after that.

Afterwards, I realized there was a package called aiohttp that I could've used, but too late.

I'll be interested to see what other HN people have done.

Re: Coroutines for Go

#68
post #62

Aside: Lua is an absolute work of art. Everything about the tiny language, how it works, and even all the little peculiarities, just makes sense.

[flagged]

As it stands, this comment contains no information. Can you explain what about Lua is problematic?

Re: Coroutines for Go

#69
Coroutines are one thing that i'd probably prefer language support for rather than a library.

    x := co func(){
        var z int
        for {
            z++
            yield z
        }
    }

    y := x()

    for y := range x {
        ...
    }

or something to that effect. It's cool that it can be done at all in pure go, and I can see the appeal of having a standard library package for it with an optimized runtime instead of complecting the language specification. After all, if it's possible to do in pure go, then other implementations can be quickly bootstrapped.

My $0.02, as someone that uses go at $work daily: I'd be happy to have either, but I'd prefer it baked into the language. Go's concurrency primitives have always been a strength, just lean into it.

Re: Coroutines for Go

#70

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…

Arguably the "problem" with other async/threading frameworks is that they build threading on top of iterators/coroutines. In this case they would be orthogonal, so it's probably not as bad as you think, though almost certainly some clever developer out there will do something stupid with it that will also get very popular (my bet would be abstracting goroutines and coroutines into a single thing)
Post reply on HN