Live data from Hacker News

Notes on structured concurrency, or: Go statement considered harmful

vorpus.org

21–30 of 234 posts

Re: Notes on structured concurrency, or: Go statement considered harmful

#22
I LOVE Go's concurrency model, but this article has won me over (pending some experimentation anyway).

If you just skimmed, this is actually worth a careful read. The parallels between "go" and "goto" are explained very clearly, and you get some awesome Dijkstra quotes to boot!

Re: Notes on structured concurrency, or: Go statement considered harmful

#23

This is very very long to explain a very simple pair of ideas: 1) You should be able to declare scoped blocks that mandate execution of all tasks started in that block ends when the scope ends. 2) This is fundamentally superior to all other forms of concurrency. I get it; this is basically what async/await gets you, but conceptually you can spawn parallel tasks inside an awaited block, and know, absolutely that all o…

Pure fork/join concurrency isn't a novel idea. I was doing some work on it in grad school. Without blocking channels, fork/join has some really nice properties, such as guaranteed deadlock freedom.

However, I agree with you that there's no one-size-fits-all approach to concurrency. Sometimes you want long-lived tasks that communicate—the actor model, in other words—in which case fork/join doesn't buy you much. I do think that fork/join is frequently what you want, though.

Re: Notes on structured concurrency, or: Go statement considered harmful

#24

What. This article proposes a "nursery", which is just a wrapped sync.WaitGroup/pthread_join/futures::future::join_all/a reactor that waits for all tasks to terminate/etc. It then uses an exception-like model for error propagation to "solve" error handling (which is fairly easy to handle with a channel). The construct is a decently usable, already applied tool to handle a set of problems, but the article takes the is…

I thought the article's comparison of go routines to goto was fair, in the context made: when calling a function in a language that allows go-routine like things (including pthread_create), one can't know if background tasks will be spawned. This is similar in the free-form time of unrestricted goto that one could not know if control flow really would return to the point lexically after the function call. His proposed abstraction does allow one to look after a nursery block and know whether or not background tasks are still running.

Re: Notes on structured concurrency, or: Go statement considered harmful

#25

This is usually why I end up using https://godoc.org/golang.org/x/sync/errgroup instead of straight go statements, as it addresses some of the cancellation and error propogation issues. When I think of my use of naked go statements, it's usually for periodic tasks; having something similarly structured for them would be a clear win to me (though potentially the impact is less significant, as it's less painful to writ…

Ah, neat. It's relatively new—I've always rolled my own implementation whenever I needed it (it's super simple, which is why this library is 67 lines of implementation, half being comments), but why roll your own when it's part of the (experimental) standard library?

Re: Notes on structured concurrency, or: Go statement considered harmful

#26
post #14
post #11

How is this different than calling join(), after spawn()?

How is if different that just using goto to go to either the true or false clause? It isn't about what you can do, it's about what you can't do if you use this mechanism (this restricts where you can call spawn and join) and the guarantees you can then build on top of that.

build what on top of it? If i want a blocking thread i would just call a function.. something something goto something isn't a valid argument that applies to everything. The other way to propagate errors up is chaining promises.

Re: Notes on structured concurrency, or: Go statement considered harmful

#27
post #24

What. This article proposes a "nursery", which is just a wrapped sync.WaitGroup/pthread_join/futures::future::join_all/a reactor that waits for all tasks to terminate/etc. It then uses an exception-like model for error propagation to "solve" error handling (which is fairly easy to handle with a channel). The construct is a decently usable, already applied tool to handle a set of problems, but the article takes the is…

I thought the article's comparison of go routines to goto was fair, in the context made: when calling a function in a language that allows go-routine like things (including pthread_create), one can't know if background tasks will be spawned. This is similar in the free-form time of unrestricted goto that one could not know if control flow really would return to the point lexically after the function call. His propose…

Knowing whether a background task has spawned is very different from not being able to follow the control flow (goto potentially jumping to an entirely different function body).

Now, while Go is designed mostly for you to not care about goroutines, there are some corner cases where one must know if a resource is used by anything, such as the chase of when you wish to close a file handle.

However, I'd argue that this is not related to go's concurrency model and the presence of background tasks at all. It's related to object lifetimes. This should be made clear at API surfaces.

A language solution to this would be Rust's lifetimes, not a new concurrency model.

Re: Notes on structured concurrency, or: Go statement considered harmful

#28

This is very very long to explain a very simple pair of ideas: 1) You should be able to declare scoped blocks that mandate execution of all tasks started in that block ends when the scope ends. 2) This is fundamentally superior to all other forms of concurrency. I get it; this is basically what async/await gets you, but conceptually you can spawn parallel tasks inside an awaited block, and know, absolutely that all o…

>this is distinct from a normal awaited block which will execute tasks inside it sequentially, awaiting each one in turn

I believe that python's `async for` construct (which may be stolen from c#, but I'm not sure) does this, and another user mentioned Promise.all which in javascript I believe allows the child promises to resolve concurrently.

In both cases, these are for concurrency, not parallelism.

Re: Notes on structured concurrency, or: Go statement considered harmful

#30
I'm really growing fond of the async/await abstraction. How do I get this in more C-like languages like Go, Rust, or C++? (I have a bunch of C++ code that I want to call via C ABIs.)

I'm intrigued by libdill but it's mysterious enough that I'm scared to include it in my project -- I don't want to risk getting sidetracked by having to debug my concurrency primitives.

Post reply on HN