I think the point he's trying to make is that if you make a blocking system call, it blocks the thread that goroutine is scheduled within, but other goroutines will not be blocked by this and will continue to execute.
This is not the case with many other (single-threaded) systems built exclusively around a god-loop that schedules coroutines. One coroutine making a blocking system call gums up the whole works.
The current implementations are cooperatively scheduled, but nothing in the specification prevents a preemptively scheduled implementation. After all, gccgo had a preemptively scheduled implementation until a few months ago.
That being said, I prefer my goroutines to be cooperatively scheduled.
When Go was first presented Rob said the term "Goroutine" was introduced precisely to avoid this kind of confusions, but old habits are hard to kill and seems that even Rob himself still falls into this trap from time to time :)
Similar/analogous (I believe these all have significant differences)to F# MailboxProcessor, akka actors, erlang/BEAM processes and userspace/green threads in e.g. GHC,
But the title of the slide said, "Goroutines are not threads."
I understand what you meant, but it's kind of confusing to use the same term for different things within the same slide while claiming they are different.
No, that is not a typo. A goroutine that blocks by making the thread it's currently running in block in the kernel is blocking that thread too; it must since the kernel needs some context for the on-going operation. What he's saying is that the pool of other threads used by the scheduler can continue to run other goroutines, just not the one that's blocked. No typo.
I have seen this same idea ("goroutines are very light and multiplexed into OS threads, don't worry about it") stated often, but I do not understand it, and I have not found any place where the implementation of this is actually discussed, do you have any pointers?
For the general case, not Go specific, there's a scheduler that tracks what processes (in the CSP sense, e.g. goroutine) are waiting on what channels. Whenever a channel becomes ready, e.g. something is available to read from it, one of the processes waiting to read from it is non-deterministically (that's important) chosen and control (the CPU's program counter, still in user-space) jumps to where it returns from the `read'. It then has the CPU all to itself until it gives control back to the scheduler by needing another particular channel-state. I'm omitting sleeping, etc., for simplicity. The switching of control is all in user-space so quite lightweight.
I hope that's a typo. A thread is blocked when a goroutine blocks would exhaust the worker thread pool pretty fast. Can an GO expert clarify on that?