core.async is a macro. Call an already compiled function under a library that blocks and the whole system will come to a screeching halt. Goroutines don't have that limitation.
Core.async lets you freely mix both. You use the same channels, the only difference being that your coroutine blocks will be wrapped in `go` and use `<!` (parks coroutine if it needs to block), while your full threads with be wrapped in `thread` and use `<!!` (blocks). It makes the tradeoffs explicit (the tradeoff always exists) and isn't a problem at all.