Only Erlang got it right, not Go. And channels were not even invented for real life programming, they were just an easy notation for mathematicians. But an interesting thing about concurrency is that the Erlang myth is actually true, getting deeper into concurrency always leads to reinventing Erlang. The road typically goes from synchronous multithreaded applications to asynchronous single threaded to event loops to higher-order abstractions around events to wrapping them into killable process/context abstractions to adding message passing and to reinvented Erlang.