4 ms·
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 thing
by scott_s 9y ago
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.
- arghwhat 9y agoKnowing 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.
- marcus_holmes 9y agoBut this concept does also solve that problem. Maybe more simply. Rust is renowned for being a total headache with borrowing and lifetimes. Nurseries might be a simpler solution for this. As you say, a corner case. But a common one...
- lilyball 9y agoNurseries and lifetimes are orthogonal concepts. In fact, Rust already has a "nursery", except it's generally called a scoped threadpool. They use lifetimes to ensure the threads can reference stuff on the stack without copying it. So a "nursery" is basically just a scoped threadpool with a 'static lifetime.
- steveklabnik 9y agoThere is some interesting stuff about this in the /r/programming thread https://www.reddit.com/r/programming/comments/8es8x3/notes_on_structured_concurrency_or_go_statement/dxxucgi/ https://www.reddit.com/r/programming/comments/8es8x3/notes_o...
- stouset 9y agoI don’t think there’s any reason a nursery has to have a static lifetime.
- eridius 9y agoThe description of the nursery is you can pass it around wherever you like. More generally, this concept seems to have been designed in a language without lifetimes. You obviously can have a scoped threadpool without a 'static lifetime, but if you want to pass it around to arbitrary locations then you do.
- twic 9y agoI think the whole point of the nursery's design is that you can create and destroy them during the life of your program, and that destroying them forms a barrier where the owner of the nursery waits for its children to finish. Having a nursery with a static lifetime in Rust would therefore be pointless, as it would live until the end of the program.
- eridius 9y agoI think you misunderstand. I'm talking about writing something like `ScopedThreadpool<'static>`, which means any external data referenced by the threadpool must have a static lifetime (or rather, it means the ScopedThreadpool cannot reference anything on the stack, because that would prevent you from e.g. returning it to your caller or passing it to another thread). The ScopedThreadpool itself can be created and destroyed whenever.
- arghwhat 9y ago
- arghwhat 9y agoIt actually does not solve the problem of lifetimes. It only solves a very isolated instance of it. For example, if we take the problem of an os.File, some library might store the reference, and use it unexpectedly in a later function call after you called Close. This presents the exact same issue as a goroutine holding it. (I honestly have no other examples of this issue than files/connections being closed prematurely for Go.)
- wybiral 9y agoI've never encountered a situation in Go where I'm passing file handles around like this. In practice you'd probably have one goroutine manage the resource and its lifespan then other code would communicate with that goroutine using channels.
- arghwhat 9y agoYou might pass an os.File or a network connection as an io.Reader or io.Writer to something that might keep it. The GC actually has an extension to sorta have destructors to help with leaking fd's from forgotten os.File's (runtime.SetFinalizer). However, having coded Go for quite a few years by now, I haven't found it to be an issue at all.
- noxecanexx 9y agoThis is very true. The same way one doesn't know if a background was started is the same way you can't know if a file was written to or some global state was changed. I thought async/await solves most of his examples
- wilun 9y agoOne can also not "known" of all the other side effect that will happen. Unless they are documented informally or encoded formally.