4 ms·
You realise that makes you sound exactly like an old Fortran programmer refusing to give up goto? A for loop is just a wrapped goto! ;-) I think the author pro
by speleding 8y ago
You realise that makes you sound exactly like an old Fortran programmer refusing to give up goto? A for loop is just a wrapped goto! ;-)
I think the author proposes a useful way to structure multi-threading. The comparison to goto isn't perfect and he needs to play fast and loose with some terms to keep the analogy working but he makes a good point.
I'm not convinced yet that the nursery pattern should be the only allowed way to start a thread but saying "you should use it unless you have a good reason not to" is a good provocation to get the discussion going.
- platinumrad 8y ago"I think x is like goto." "I disagree; I don't think x is like goto." "Now that we've agreed that x is like goto, not wanting to give up x makes you like a big dinosauric dummy~"
- kybernetikos 8y ago> 'A for loop is just a wrapped goto!' corresponds fairly closely with > 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. The fact that the 'nursery' can and has been implemented with more 'primitive' constructs is actually a point of similarity with goto/structured programming not a point of difference. The GP didn't seem to spot this, despite making it their first complaint, so it was good that the post you're responding to did. The post you're responding to is not calling the GP a dummy because of a disagreement, it's pointing out the apparent criticism the GP levelled was exactly the same criticism levelled against structured programming, and ultimately goto lost.
- arghwhat 8y agoAs someone whose work includes hardware driver programming, I'd rather not give up goto. It would make a lot of error handling extremely cumbersome, and much less readable. :( However, I find "go" and "goto" to not intersect at all. I've written this many times in other comments on this thread, so I'd rather not type it out again, but the TL;DR: is that "goto" can make understanding a function when read difficult, while "go" is clear when read. No function is understood if never read, and spawning "background tasks" is a core part of asynchronous programming (and thus not an unusual side-effect). The "nursery pattern" is a decent construct that I have used quite often whenever I felt a need, but it doesn't appear to really solve any issues mentioned in the post. I also elaborated on this quite a few times already, so TL;DR: the only real problem of goroutines is things like references to potentially closed objects, but any method may end up storing an internal reference used at a later call, making the issue not related to concurrency.
- stouset 8y ago> while “go” is clear when read… I believe our industry’s several decades of demonstrated inability to write concurrent code correctly disagrees with you. Languages like go (and Rust, to a greater degree) have improved the situation. But there are still a ton of sharp edges that existing approaches still have, and—often—they’re ones that aren’t readily apparent until after a project starts growing and begins unearthing issues that are rare, only happen on faster hardware, or require higher levels of concurrency than we’re previously used.
- arghwhat 8y ago> I believe our industry’s several decades of demonstrated inability to write concurrent code correctly disagrees with you. Not at all. Concurrent/parallel code isn't particularly difficult to write—there's just a unique class of problems related to it that might occur, but that does not mean it is hard. Rather, the industry has through several decades demonstrated an inability to write bug free code in general. I wouldn't blame concurrency/parallelism for this.
- camgunz 8y agoI guess we can debate what "hard" means, but I think "adds a lot more problems that are much harder to reason about and avoid" is exactly the definition of hard. If it's not, I'm honestly not sure what is. Torn reads, deadlocks, concurrent modification, the effects on optimizers, the overhead of scheduling and lock management. Each of these are deep, complicated issues you only have to deal with when writing concurrent (well, parallel) code. But yeah I mean, if you mean it's pretty easy to call pthread_create then OK. But if you at all care about your program working, then parallel code is much, much harder to write.
- arghwhat 8y agoAll the problems you present go into the category of sharing state. This is the unique problem presented by concurrent programming, which is no harder than all the other problems in programming. This does not mean that concurrent programming is hard, but that just like all other programming, it has some sharp edges. The issues related to sharing state can be easily avoided by, for example, using a CSP-style paradigm (channels in Go). In Go, this only leaves behind a deadlock, which are automatically panic, making it incredibly easy to debug. Overhead of scheduling and effects on optimizers are not related to concurrency/parallelism. The scheduler is affected by many things even under single-threaded execution which is far beyond the scope of normal application developers, and optimizers are largely unaffected by concurrent/parallel programming (although shared structures must internally present memory barriers). The optimizer is also beyond the scope of normal application development. If you are doing development that requires precise control over optimizations and scheduling (like I do), then all bets are off. However, with "normal" (i.e. not-processing-8x100Gb/s streams) programming, concurrent programming is a breeze unless you intentionally shoot yourself in the foot.