The major perk is that you queue computation (read: "thread"), not callbacks, so you can write stuff like this:
while true:
let bytesRead = read(fd, buf, bufsize)
if bytesRead == -1:
if errno == EAGAIN or errno == EWOULDBLOCK:
wait(fd, Read) # Queue this computation until the fd is readable
else:
raise newIOError(errno)
else:
return bytesRead
Even IOCP is made simple here: let overlapped = new Overlapped
# <do your operation>
if error == WSA_IO_PENDING:
wait(handle, overlapped) # Queue this computation until the overlapped operation is complete
if WSAGetOverlappedResult(...) == FALSE:
raise newIOError(errno)
else: ...
I think this kind of simplicity afforded to user code is rarely seen in most languages, which is why I decided to base my stdlib on this.Relevant recent articles:
- https://without.boats/blog/let-futures-be-futures/
- https://adam.nels.onl//blog/maybe-everything-is-a-coroutine/