4 ms·
That is a good example. It illustrates that async is a partial abstraction on the way to dataflow. It's not immediately obvious from your example what's reall
by spinningslate 7y ago
That is a good example. It illustrates that async is a partial abstraction on the way to dataflow. It's not immediately obvious from your example what's really going on: whereas re-writing it as dataflow pipelines makes the intent clear:
LoadWasher() | RunWasher() | LoadDryer() | RunDryer() | IronClothes()
CleanKitchen()
where `|` is piping the output of one operation into the next one (as per *nix shell). The two lines are independent and so can be scheduled according to resources available.
Doing so makes the inherent dependencies trivially clear. It doesn't matter which are "long" running and which aren't: it's not possible to run the washer until it's been loaded. Using async/await conflates two things:
1. What's "long" running, for some definition of "long" (--> make it async)
2. What's dependent on what (await)
--
EDIT: fix formatting & added missing "RunDryer()" step
- dmix 7y agoSo you basically you'd have to rely on each of the function signatures, probably with some text editor/IDE by hovering over them, to figure out which one in the pipe list is Async? Or jump to each of them with ctags. Then wrap it in a try/catch or pattern match the result to handle the various errors different errors...
- spinningslate 7y ago> So you basically you'd have to rely on each of the function signatures, probably with some text editor/IDE by hovering over them, to figure out which one in the pipe list is Async? Or jump to each of them with ctags. No, the point is you don't _need_ async. At least not as a language primitive. Instead, one expresses directly where the data dependencies lie. If an operation in a pipeline blocks, the runtime is at liberty to switch to another task. That already happens today, whether in language runtimes (e.g. Node) or the underlying OS. I don't need to tell the runtime "this operation might block". It already knows. Instead, we've explicitly defined intent: when `RunWasher()` finishes, `LoadDryer()`. It doesn't matter if the washer takes one micro second or one hour; I can't load the dryer until it's done. >Then wrap it in a try/catch or pattern match the result to handle the various errors different errors... True, error handling is missing. But then it's not in the parent example either. The requirements aren't fundamentally different in either case.