Understanding Real-World Concurrency Bugs in Go [pdf]
The two key takeaways for me are:<p>(1) "Contrary to the common belief that message passing is less error-prone, more blocking bugs in our studied Go applications are caused by wrong message passing than by wrong shared memory protection."<p>(2) "Shared memory synchronization operations are used more often than message passing, ..."<p>So basically, (1) people have more trouble writing correct multithreaded routines using message passing, and (2) in large production applications people tend to fall back to using shared-memory primitives rather than message-passing anyway.<p>It seems the intention of the Go language designers was to make a language that would be simple and easy for programmers to pick up.  Given that most programmers are already accustomed to multithreaded programming using shared memory and that this is conceptually simpler, I think the language designers made a mistake by throwing channels, a relatively new and experimental approach (yes, I know CSP is from 1978, but I'm talking about widely-adopted industrial languages), into the language.  I think it was the single biggest mistake in the design of Go.