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... 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.
Sure, 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:
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.
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?
> 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.
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... 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.