The only foolproof way to opt into shared nothing in Go is not to spawn any goroutines. Global variables (which are all mutable, because there aren't any other kinds of variables in Go) are used all over the place in Go, including in the standard library.
How many of the concurrency bugs in this paper trace to the combination of "share-nothing" designs (channels) with mutable global variables in the standard library? If the answer is "none", what evidence does this paper present that mutable globals in the standard library are a practical impediment to "share-nothing" designs in real programs?
I mean, standard library global variables not being thread-safe would generally be treated as bugs in the standard library, so I wouldn't expect to see bugs there.
The point is that shared-nothing designs are just not how Go typically works. You can see that in functions like http.HandleFunc() (and everything else that uses the DefaultServeMux), which registers a global handler across all threads of the program.
Is that a good example of impediments to correctness in shared-nothing designs in Go? Using the default mux makes it hard for two different services to share the same Go program, and reduces the flexibility of libraries, but it doesn't appear to harm correctness or drag programs into shared memory designs. It seems like more of a purity test than a practical critique.
But the default serve mux is shared memory (it's literally a mutable global variable in net/http). If it isn't shared memory, what is?
I mean, Go doesn't force you to use shared memory; no language with threads does. It encourages it through library design (e.g. the default serve mux) and language design (e.g. package init() functions) though.
Right, I'm not disagreeing with you that the Go standard library and a few idiomatic Go standard library transactions use shared memory. I'm disputing that these are real impediments to building programs that benefit from shared-nothing designs. Obviously, Go does a better job of minimizing shared memory than eliminating it. I'm asking: does this distinction matter in practice?
There's Go functionality such as pprof that requires the use of the default serve mux and therefore you can't use pprof with a true shared nothing design. The log module is similar.
Does that lead to more bugs in programs? I don't know. It's quite possible it doesn't matter in terms of defect count. It's not shared nothing, though, is all I'm saying.
Right, thus the distinction I'm making between purity test concerns and practical concerns. Go is not, and has never claimed to be, a pure share-nothing design. It's pretty up front about not being that!
Right, but I don’t need “foolproof”, especially if it comes at high costs. I can already get mostly correct code in Go and the time I spend debugging is less than the overhead in other languages.