It's worth noting that green threads are not 'enough' -- in any language with concurrency, you still need to be explicit about what work can run concurrently and what needs to be sequential. In Go, for example, the default is sequential operation; if you want to run a bunch of code concurrently, you need to do extra work to launch a bunch of new goroutines / wait for everyone to finish. In Haskell, which also (typically) has green threads, there's a popular `async` package that supplies a promise-like construct -- it's quite useful when you want to be explicit about concurrency and ordering.