Plans for async vs blocking IO #693
Replies: 1 comment 3 replies
-
My intuition is that it should be possible to express the choice between synchronous and asynchronous I/O within the effect system, so that it is a matter of which handler is used. So, perhaps what I would want to see here is an effect like
Go has only blocking I/O, The approach there is to always let I/O block, but to separate the threads doing I/O from the threads doing work, which is a style enabled by threads themselves being very cheap. Perhaps there is some confusion of terminology here, though. To me, "async" specifically means concurrency implemented in terms of continuation passing (or effect handling, which generalizes continuation passing, in the case of Koka). It seems like you're using it more to mean what I would call "concurrent." |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This may be a premature discussion, but I'm very interested in what the plan is for blocking IO (or its absence).
Once async IO support is merged in and rock solid on all compile targets, the big question is whether there are two versions of every IO function - one that blocks the thread (as IO does today), and one that's async. Or, whether all the current IO functions (and sleep() etc) are rewritten to be fully async, and we adopt a rule of never adding a blocking IO function to the stdlib.
I think it'd be ideal if we rule out blocking IO entirely, so that there's no choice. The effect system should mean that there is no real usability impact to users, and it's a fantastic proposition to know that it's simply impossible to block the current thread on IO (outside of FFI).
So in my mind it's a no-brainer, I would want everything to be async. I'm coming at it from a usability perspective though, I'm interested to hear the counter-arguments?
Prior art:
One of Go's most powerful aspects (IMO) is that there's no such thing as blocking the current thread. All IO and waiting is async, and that removes one big way to screw things up (in terms of performance and thread starvation).
NodeJS is similar - there exist a few
doSomethingSync()
versions of various IO operations, but they're frowned upon aside from quick & dirty scripts, essentially everything in apps/libraries will be async. In the early days the main appeal of thesesync
versions was to avoid writing callbacks, though I imagine async/await has removed most of that friction (I haven't used node for a long time).Scala on the other hand has many problems with this, because most FP libraries use a (nonblocking) IO monad, whereas all of the Scala stdlib (and almost all Java libraries) happily block the thread and ruin your day. To workaround this requires the user to be careful and constantly aware of the distinction. Libraries like linebacker exist because of this problem (but it's still up to you to be aware of where blocking can happen).
Beta Was this translation helpful? Give feedback.
All reactions