Ok, I've never actually written anything in go so humour me here.

The generally given reasons on HN that threads mapped 1:1 to pthreads are bad seem to be as follows:

Shared mutable state is hard.

Memory usage is inefficient when you are allocating a fixed size stack per thread and those threads spend most of their time blocked waiting for IO.

Let's assume you are using some thread pooling pattern , so thread startup time is not such an issue.

Apart from perhaps better syntax with channels etc, how does go fundamentally solve these problems in way that you cannot with standard threads?

For example, shared mutable state problems can be mitigated to a degree by going down a "shared nothing" approach and handling shared state through some middleman like a Queue or a SQL/NoSQL DB.

I assume go supports some form of pass by reference so you can still make shared mutable state an issue with it if you pass a reference to a goroutine.

Each goroutine has it's own stack regardless of how many pthreads exist so there can still be wasted memory on a blocking operation.

Nothing stops you from doing anything you want with threads, including using them to implement very safe patterns. The problems are, 1: the thread libraries do not afford those safe patterns, and indeed, afford very unsafe ones (and also ones that compose poorly) 2: libraries written for the ecosystem will end up using the poor patterns 3: lack of compiler enforcement and how easy it is to accidentally mutate something unexpectedly mean that unless you are superhumanly careful you will still screw something up, somewhere.

And you are correct that Go does not enforce shared-nothing between the goroutines. It has better affordances on those fronts that conventional C, but it is not enforced as it is in Erlang or Haskell. And while I say the affordances are "better", I still think that people screwing it up will be a practical problem.

Yeah, this is exactly right... I have to say Go changed my thinking about concurrency. But now I want to write a very small wrapper around pthreads that lets you write in the actor style. It just adds those "affordances".

Go is more or less the actors style, except with the (discouraged) possibility of sharing mutable state... even though for some reason it doesn't seem to be advertised as such.

The reason is that I don't think Go can cover what C + Python can. C gives you more low level control and Python is still shorter (and thus quicker). I like Go a lot but I would rather program in C + Python (like I do now) than C + Python + Go.

And then the other component to this is de-emphasizing the somewhat-horrible-for-concurrency Python/C API. The library I'm talking about would have channels, and you would have one end open in Python, and one end open in C. Python and C are running in different threads. Rather than the crazy subroutine/callback hell you have now with any nontrivial Python/C binding.

So basically I want to fix the C/Python interface, which is the only reason it is awkward to program in C + Python (the languages themselves are both great), rather than adding another language that overlaps highly with both of them.

The OS is written in C, so you've never going to get past C. If there was a whole world written in Go, that might be reasonable... but I don't believe in portability layers.

What does the OS being written in C matter? libc has to make a syscall to access OS functions just like anything else does. There's no obligation on a language implementation to make calls through C. It's a thin enough layer that if your language runtime is otherwise written in C you may as well, but that's a design decision.

It would be perfectly reasonable to write a non-C language runtime targeting Linux against syscall instructions or against Windows' documented system DLL interfaces.

Even if it didn't there's no reason to ever add a C dependency to your system if one of the languages you're already using has sufficient "systems" versatility. Go is clearly intended to fill this role.

tl;dr: you can get past C just fine even on an OS written in C and the C dependency isn't free.

I find this pretty interesting. It is basically using Erlang as an OS on top of Xen. http://erlangonxen.org/

Haskell had a similar project but I can't remember what it was called.