3 ms·
Channels as a high-level abstraction are pretty simple, but API and implementation details matter. Go's implementation of channels are very simple to use for s
by tene 5y ago
Channels as a high-level abstraction are pretty simple, but API and implementation details matter.
Go's implementation of channels are very simple to use for some very simple use-cases, but Go's API choices mean there are a lot of subtle, non-obvious details you need to learn and keep in mind to do anything nontrivial.
I really like https://medium.com/justforfunc/why-are-there-nil-channels-in-go-9877cc0b2308 https://medium.com/justforfunc/why-are-there-nil-channels-in... as an example. Reading from two channels safely should be a simple task, but just doing the intuitive thing will look like it works for many uses until it starts fabricating zero values, or blocks forever, or spins the CPU at 100% doing no work.
I really love channels, but I really hate working with Go's channels.
The channel API in that other language well-known for its good concurrency support is much simpler to learn and use for me, without as many subtle sharp edges, but that's possibly a bit off-topic, so I've removed a detailed comparison.
- tapirl 5y agoWhat you described are all well defined in the docs.
- tene 5y agoSure, it's all out there, and it's possible to build useful software using Go's channels. I was specifically trying to explain why I say that Go's channels are not intuitive, because they require studying and memorizing these other arbitrary complications. I'm also curious about what docs you're referring to, exactly. Here's what I found when looking for golang channel docs: https://golang.org/ref/spec#Channel_types https://golang.org/ref/spec#Channel_types If the documentation's described behaviour, along with code patterns to accommodate that behaviour, are intuitive to you after reading this, then you have a very different perspective on the world than I do. I also found these: https://tour.golang.org/concurrency/2 https://tour.golang.org/concurrency/2 https://golang.org/doc/effective_go#channels https://golang.org/doc/effective_go#channels Unless I've missed it in my reading, I don't see any of these clearly stating that the single-return form of channel receive will fabricate zero values when misused, or describing how you need to replace a closed channel with a nil when selecting on multiple channels to avoid spinning the CPU when it's been closed. I agree that this stuff is learnable. I have learned it, and so have you. I agree that there are learning resources out there that help with learning the nuances of using Go's channels well. Hopefully this can help you feel less shocked the next time someone says that Go's channels are not intuitive. If you disagree, can you explain more about how Go's channel management choices are more intuitive than the alternatives to you? [Edit: I found the documentation on producing a zero value when reading from a closed channel here: https://golang.org/ref/spec#Receive_operator https://golang.org/ref/spec#Receive_operator]
- tapirl 5y ago> Unless I've missed it in my reading, I don't see any of these clearly stating that the single-return form of channel receive will fabricate zero values when misused, or describing how you need to replace a closed channel with a nil when selecting on multiple channels to avoid spinning the CPU when it's been closed. You certainly missed this: https://golang.org/ref/spec#Close https://golang.org/ref/spec#Close You might also need read https://blog.golang.org/pipelines https://blog.golang.org/pipelines and https://blog.golang.org/concurrency-timeouts https://blog.golang.org/concurrency-timeouts If you need a good summary, you could read my articles: * https://go101.org/article/channel.html https://go101.org/article/channel.html * https://go101.org/article/channel-use-cases.html https://go101.org/article/channel-use-cases.html * https://go101.org/article/channel-closing.html https://go101.org/article/channel-closing.html