That said, there are occasions when channels have proven invaluable. I think the real issue is they were branded as a killer feature but in reality their usefulness is a little more niche than a mutex.
That said, there are occasions when channels have proven invaluable. I think the real issue is they were branded as a killer feature but in reality their usefulness is a little more niche than a mutex.
Agree - and many people are surprised to learn both: a) how fast mutex ops are in practice, and b) how channels use mutexes under the covers.
Fortunately one can code a replacement for channels in Go using mutexes and semaphores. And that exercise in turn allows one to see that in many cases the channels are just a bad model. Things like having a single polymorphic priority message queue per go routine suits many cases better than dealing with multiple channels.
And this has been known since nineties if not eighties when Ada had to add mutexes after early designs based purely on channels. So it is puzzling why Go made channels such a central feature when the priority queue just works judging by Erlang or many successful C/C++ libraries.
To each their own though. I hear a lot of people prefer it.
The close is built into the language itself which is useful, along with the other built in language functionality. I wrote about it here, with an example of how to do it https://boyter.org/posts/file-read-challange/
I agree that the ergonomics of Go channels leave a lot to be desired. Also, channels are still a primitive: you still need to build abstractions to do anything nontrivially useful with them. I think something like a good coroutine abstraction, or thread nursery abstraction would be ideal.