6 ms·
Just took a glance but it seems like this is exactly the kind of project I saw coming out of generics going live. I was really surprised to see how subtly hard
by JamesSwift 4y ago
Just took a glance but it seems like this is exactly the kind of project I saw coming out of generics going live. I was really surprised to see how subtly hard go concurrency was to do right when initially learning it. Something like this that formalizes patterns and keeps you from leaking goroutines / deadlocking without fuss is great.
- PaulKeeble 4y agoIts was initially something that surprised me about Go. It was famous for good concurrency and yet compared to many functional languages and contemporary OO languages it had a lot of foot guns. There is a lot of repetition of code that even in languages like Java had long been made common. Go seems to lack obvious concurrency abstractions. When they announced generics the first thing I did with it was rewrite my common slice parallel algorithm and my limited concurrency pool. It is an obvious area needing improvement for common use cases.
- sudhirj 4y agoThe Java Stream API is pretty awesome, it's my biggest wishlist item for Go.
- masklinn 4y ago> It was famous for good concurrency That’s because people confuse “easy” and “good”. Go has easy concurrency, but it’s not good. The opposite really. It’s at best the similar problematic model you get in other, older, procedural / oo langages. At worst it’s a lot worse given how difficult it is (and even more so was before generics) to build abstractions and concurrent data structures.
- philosopher1234 4y agoWhat is bad about it? An example would help me understand you better.
- masklinn 4y ago> What is bad about it? That nothing about it’s good? It’s the same shared-memory concurrency everybody else has, that it had to built-in a thread-safe queue doesn’t fix that. In some ways it makes it worse, because it’s easy for the unwary to assume channel = safe, whereas nothing could be further from the truth: a channel only protects itself, sending a slice through a channel is not safe, sending a map through a channel is not safe, sending a pointer to a channel is not safe, etc… and this is transitive, sending by value a struct which contains any of those isn’t safe either. Not to mention the easy and common issue of implicit concurrent sharing via `go` closures. Here’s a bunch of examples: https://www.uber.com/blog/data-race-patterns-in-go https://www.uber.com/blog/data-race-patterns-in-go And these are data races, not merely concurrency issues.
- philosopher1234 4y ago> That nothing about it’s good You have a very myopic view of what makes concurrency designs good. I suggest you broaden your perspective, and consider the practical effects of language design on humans, as opposed to just mathematically provable safety.
- masklinn 4y agoAh, you’re a fanboy. You could have just put that upfront I would not have wasted my time taking you seriously.
- philosopher1234 4y agoYou wrote "That nothing about it’s good". That's stupid. I agree we are wasting our time.
- Smurfix 4y agoWell, Ok, so the main thing that's good about it is that it's dead easy to start a goroutine. But that's actually bad, just like randomly jumping to any piece of code whatsoever is bad in in a procedural language. Read the Structured Concurrency notes (https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ https://vorpus.org/blog/notes-on-structured-concurrency-or-g...) for the reasons why.
- pkolaczk 4y agoIt is easy to learn the concepts, but not actually to use them. It is like with assembly, learning mnemonics is easy, but writing useful programs is a whole lot different story.
- pkolaczk 4y agoIt is surprising to me that so many people think that message passing is simpler to get right than shared memory concurrency, when in fact it is not: https://cseweb.ucsd.edu/~yiying/GoStudy-ASPLOS19.pdf https://cseweb.ucsd.edu/~yiying/GoStudy-ASPLOS19.pdf
- klabb3 4y agoIf you’re only going to learn one concurrency paradigm, it has to be message passing, because that’s the only one that works between machines. The only reason why people don’t see the similarities when it comes to in-process concurrency is that the request-response paradigm muddies the waters. Anyway, that’s the world we live, so people have to work around the N+1 problem and similar, living in a mixed sync-async world of pain :) It’ll take at least a decade to fix, if we ever do.
- pkolaczk 4y ago> because that’s the only one that works between machines There is a non-negligible number of problems that don't need multiple machines and are much easier to deal with using other concurrency paradigms. When the language forces only one model onto the developer, things are actually more complex than they need to be.
- klabb3 4y agoYeah, I agree, but Go is allowing traditional mutices that work the same way (except the rwlock discrepancy as pointed out by the paper). Channels aren’t forced, just encouraged. There are cases where locks are preferable. My main criticism against the paper is that what tipped the scales for concurrency bugs is the “blocking category” which of course is going to be higher with message passing since it’s a blocking paradigm. Locks only block until unlocked, and isn’t used as a general purpose signaling mechanism. The “non-blocking” bugs are over represented by locks, which are generally more serious (non-deterministic data races vs deterministic deadlocks). That said, I have criticism against Go as well. The decision to not implement structured concurrency (fire-and-forget goroutines) makes these deadlocks largely go unnoticed. If goroutines had ownership or scope, runtime detection a la ‘-race’ would help detect a lot of these bugs.