3 ms·
I've been using Go since 2011. One year less than the author. Channels are bad. No prioritization. No combining with other synchronisation primitives without ex
by anacrolix 2y ago
I've been using Go since 2011. One year less than the author. Channels are bad. No prioritization. No combining with other synchronisation primitives without extra goroutines. In Go, no way to select on a variable number of channels (without more goroutines). The poor type system doesn't let you improve abstractions. Basically anywhere I see a channel in most people's code particular in the public interface, I know it's going to be buggy. And I've seen so many bugs. Lots of abandoned projects are because they started with channels and never dug themselves out.
The lure to use channels is too strong for new users.
The nil and various strange shapes of channel methods aren't really a problem they're just hard for newbs.
Channels in Go should really only be used for signalling, and only if you intend to use a select. They can also act as reducers, fan out in certain cases. Very often in those cases you have a very specific buffer size, and you're still only using them to avoid adding extra goroutines and reverting to pure signalling.
- politician 2y agoOne nit: reflect.Select supports a dynamic set of channels. Very few programs need it though, so a rough API isn’t a bad trade-off. In my entire experience with Go, I’ve needed it once, and it worked perfectly.
- lanstin 1y agoI almost always only use Channels as the data path between fixed sized pools of workers. At each point I can control if blocking or not, and my code uses all the (allocated) CPUs pretty evenly. Channels are excellent for this data flow design use case. I have a little pain when I do a cli as the work appears during the run and it’s tricky to guarantee you exit when all the work is done and not before. Usually Ihave a sleep one second, wait for wait group, sleep one more second at the end of the CLI main. If my work doesn’t take minutes or hours to run, I generally don’t use Go.
- jessekv 2y agoHow about channel channels? https://github.com/twpayne/go-pubsub/blob/master/pubsub.go#L17 https://github.com/twpayne/go-pubsub/blob/master/pubsub.go#L...
- sapiogram 2y agoYou joke, but this is not uncommon at all among channels purists, and is the inevitable result when they try to create any kind of concurrency abstractions using channels. Ugh... I hope I never have to work with channels again.
- __s 2y agoI'm guilty of this too https://github.com/PeerDB-io/peerdb/blob/d36da8bb2f4f6c1c821b17ddf7b5217be5b6c331/flow/connectors/utils/lua.go#L105 https://github.com/PeerDB-io/peerdb/blob/d36da8bb2f4f6c1c821... The inner channel is a poor man's future. Came up with this to have lua runtimes be able to process in parallel while maintaining ordering (A B C in, results of A B C out)
- lanstin 1y agoI have a channel for my gRPC calls to send work to the static and lock free workers; I have a channel of channels to reuse the same channels as allocating 40k channels per second was a bit of CPU. Some days I am very pleased with this fix and some days I am ashamed of it.
- hajile 2y agoThis is almost completely down to Go's type terrible system and is more proof that Google should have improved SML/CML (StandardML/ConcurrentML) implementations/libraries rather than create a new language. They'd have a simpler and more powerful language without all the weirdness they've added on (eg, generics being elegant and simple rather than a tacked-on abomination of syntax that Go has).
- hesdeadjim 2y agoGo user for ten years and I don’t know what happened, but this year I hit some internal threshold with the garbage type system, tedious data structures, and incessant error checking being 38% of the LoC. I’m hesitant to even admit what language I’m considering a full pivot to.
- chuckadams 2y agoRaku? Unison? Qi? Don't tell me it's something boring like C# ;)
- hesdeadjim 2y agoCaught me, C#. Library quality has improved a lot in ten years, the language feels modern, and one of Go's biggest advantages, single binary cross-compile, is way less relevant now that dotnet standard installs easily on every OS I care about. I was prototyping some code that needed to talk to OpenAI, Slack, and Linear and the result was.. fast and extremely readable inline async code. I've interacted with these APIs in Go as well and by comparison, ultra clunky. We're a video game studio as well using C#, and while game programmer != backend programmer, I can at least delegate small fixes and enhancements out to the team more easily.
- hedora 2y ago“Game studio” suggests you made the right choice, but the advantages you mention apply to rust and typescript too. Both those alternatives are data race free, unlike go, c# c++ and java. (Typescript is single threaded and gc’ed. Together, those properties mean it doesn’t need a borrow checker.)
- eikenberry 1y agoI've always thought a lot of it was due to how channels + goroutines were designed with CSP in mind, but how often do you see CSP used "in the wild"? Go channels are good for implementing CSP and can be good at similar patterns. Not that this is a big secret, if you watch all the concurrency pattern videos they made in Go's early days you get a good feeling for what they are good at. But I can only think of a handful of time I've seen those patterns in use. Though much of this is likely due to having so much of our code designed by mid-level developers because we don't value experience in this field.