4 ms·
I've done asynchronous programming with the reactive paradigm where I specify a chain of function calls I want applied to data and it happens in a thread indepe
by zests 6y ago
I've done asynchronous programming with the reactive paradigm where I specify a chain of function calls I want applied to data and it happens in a thread independent way. I have not done much programming with the new fancy "async/await" keywords. It seems like a worse abstraction because it mixes asynchronous code with synchronous code and is probably harder to reason about. Not to mention you can't do something like application wide backpressure unless everything is asynchronous.
Can anyone who has worked in both types of applications comment on their differences?
- calpaterson 6y agoI would say that there are maybe three different ways of async rather than two. Broadly: - wholly implicitly (by monkeypatching stuff with gevent typically) - async/await - by reactor (twisted) async/await is not really an alternative to the explicit style of twisted. To paraphase Guy Steele it is an attempt to drag the monkeypatchers halfway to twisted. It doesn't really solve the problem of mixing sync code in with your async code, the only preventative to that is programmer diligence. If you read from a file using open in the middle of your async code you're going to block the process while bytes are gathered for you. However it does prevent you from accidentally using async code in the middle of your sync code. Problems like backpressure and failure handling are largely unsolved in asyncio.
- dtech 6y agoI've done both, but 80% in reactive streams. I like async/await before it has a lot less hard stuff to think about - hot and cold streams take months if not years for devs to grok - and creates code a lot more similar to non-async code. In contrast Reactive Streams requires you to change your complete program. I like to compare it to Typescript/Kotlin-style null-safety v.s. the Java Optional or Scala Option. If you want make code null safe with option you have to rewrite basically your complete code from "procedural" to chains of (flat)maps. In contrast in Typescript you just change T to T? in a few places and add an if where you want to handle the optionality. async/await versus reactive streams has this same problem, reactive streams is highly impactful, much more than async/await. In practice I've seen this have the effect of turning applications turn into a small reactive stream outer shell with the app itself being mostly synchronouse/Future, while async/await is used a lot more liberally because the impact is smaller. > It seems like a worse abstraction because it mixes asynchronous code with synchronous code It doesn't, at least in Kotlin only an async function can call an async function. This isn't different from using `map` in a stream.
- lmeyerov 6y agoAs someone who writes + maintains systems with both: They both have their place. Reactive streams (FRP, Rx, ...) are good when you want to do operations over streams like 'fold', 'sample', 'tween', etc., but most code isn't like that. Instead, most code is 'at-most-once' (=> value or exn), where async/await is enough. That matters because adding streams means all of a sudden your code looks like 'one-or-more', which adds an entirely new world of behavior to define & test against. ("Is this a value or a stream? If I feed in a stream... What if I just want one...") 'Behaviors' in FRP help a bit here... but if you can avoid the complexity, why not? For when we do FRP, I like how we got it in our React code: Mostly synchronous functional code (React::render(), ...), and then we do animations and other stream-like concepts via Rx. Our nodejs code works similarly: mostly async/await route handlers, and now and then we do fancier http streams and whatnot via Rx. (Though even there async/await has been increasingly nice, as we generally aren't doing many fancy temporal operators nor contention handling.) We haven't figured out an equivalent solution for our Python async code, however as async/await is still new & changing, and afaict FRP/Rx never really made it there.