I don't think the M:N model will be highly different from the 1:N model regarding channel and it's use.
I surely propose some kind of channel for the implementation detail of goThread, but in fact, it would be more complex than that. to avoid tryRecv loop. In fact, to implement Coroutine-aware channel, we must add a threadqueue in the dispatcher that wake up the listener coroutine accordingly. So the whole thread is not block: * The receiver will tell the dispatcher he is waiting for a channel, suspend itself (it might be possible to do it optimistically and go to sleep only when the channel is empty) * The sender will tell the according waiting dispatcher that he has sent data (the constraint it to limit ourself to only own receiver, although multiple receiver could be possible to implement. Depending of if the send operation can block, having multiple senders might be or not possible or easy) So maybe the channel term is not appropriate, because indeed, we won't block the whole dispatcher thread. TimeoutMs could certainly be added to the channel. Deadlocks are likely to happen (just like any other language that uses channels) -> making debugging difficult because of the presence of the dispatcher. However, the user will likely rely more on "goThread/wait" instead of directly using channels, which will avoid a lot of problems and deadlocks, because taken care of. I also tend to avoid `wait` if possible, because explicit waiting is optional in NimGo (all code are executed when `runEventLoop()` is encountered until the dispatcher is empty). Without using wait explicitly, dealocks aren't very common. I hope my explanations wasn't too confusing and might convince you.