Hacker News new | past | comments | ask | show | jobs | submit login

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.




What you described are all well defined in the docs.


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:

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://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]


> 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

You might also need read https://blog.golang.org/pipelines and 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-use-cases.html * https://go101.org/article/channel-closing.html




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: