Swift's future asynchronous solution is again in heated conversations on Twitter and the forums. Some of the discussions end up being about personal arguments on how one system makes the other obsolete, which is completely bollocks. I'm here writing this today to give some arguments to both sides and to try to stop the incorrect thinking that async/await is unnecessary.
we were late to the party
don't shut other ideas
new better stuff is already out there, we're late again
what it is and what's the advandge
don't enter on discussions about being syntatic sugar for promises, that's an implementation detail of a specific language. swift's solution doesn't have to be like that, and by the initial conversations looks like it could be completly the other way around.
what it is how ti should be used why it's overused
If you fully treat your app as a complete event system fair enough, but not sure how man people does that, or better said, can deal with that level of complexity. And there are better ways of building apps anyway that don't require all of this.
## the broken promise of a single api
A lot of the conversation on Twitter and the forums around Swift Evolution often ends up with a discussion on priorities. That's a healty conversation to have, except when it derails into personal arguments about how a featurein heated arguments about what should be priorities. Part of these discussions often involve the promised async feature for the language. One of the things that often surprises me is how Rx (or FRP in general) lovers tend to shut down the benefits of having async/await on the language.
Usually the argument is that with an FRP library you have everything you need, that you can use Future/Promise and we don't need anything else. In my opinion this a shortsighted way of seeing things, specially when on the iOS community FRP was considered a good way of doing things so late compared with others, seems like we're always late to the party 😂 . It doesn't make much sense to me that now we treat FRP as the silver bullet and repeat the mistakes of the past, mainly shutting down other tools and techniques.
But I'm not here to say that you will absolutely need async/await if you already use Rx, no of course not, Rx can do whatever async/await does and much more. But for many problems, it can't do it such an elegant way. *I can hear you screaming*.
Let me explain. The main advantage of async/await is to be able to written what looks like procedural code but that in reality runs asynchronously. If we're talking about working with asyncronous work of course Rx can also work with that. The problem with Rx is that it's much more than that it has a dicotonmy that can't be solved.
You you read about the original work from Microsoft Research about the Observable pattern that made Rx famous one of the important things noted is that there is a single type, interface, that can take the job of your APIs. That was for me what of the most excisting things about it, being able to unify different communication patterns (delegate, action, callback closures, notifications...) into a single type it's a great technique. And that's how I did things for years before libraries matured and started introducing other more concrete and convenient types.
Single, Future, Completable, Maybe... if you look at modern FRP implementations you will see that the Observable type is far from being alone. That completely breaks the fact that you have 1 type for everything. Now if you want to mix and match those you need to start polluting your codebase to convert this different kinds of streams to each other.
But on the other side this is great! We like APIs where the types tells us the whole story, it means that the compiler will catch a lot of mistakes. So you can see, there is no good solution, both sides of the coin are equally valuable.
So, if you already have different systems for dealing with Futures vs. Streams of data what's the harm on having a language supported system for one of them, that helps make it way nicer and way more approachable?
But there is another reason to prefer async/await. Going back to the origins of the Rx that came out from Microsoft. One of the ways to understand an Observable is to make the compression with its synchronous counterpart, an Array.
An array gives you **multiple values**. An observable gives you **multiple values** over time.
But what if you just want a single value? Well, on the synchronous world you will just use the value directly, an integer, a string, etc. In the async world you can use the famous Future and, of course, async/await.
You don't use an array of Ints to represent a single integer. There is no point on that. In the same way using an observable when you want to deliver one single value is pointless.
And finally, to the crude reality of the usage of Rx on most applications. The bast majority of people at least starts with Rx by using it on their API layer. And that my friends, is totally unnecessary in a world were the language provides nice asynchronous solutions. Yes, some of you may use Rx on your entire application, everything is an Observer! I've been there and it's great. But I'm not sure how many people out there can say that.
And of course, without talking about all the problems that a reactive solution for everything brings, let's not talk about debugging.
So my argument is that for the bast majority of people async/await will be a much better solution to reach for than any Rx library. Yes, if you are dealing with sockets or anything that needs streams of data, by all means Rx is your solution (for now), or if you fill your app with observables everywhere then of course go for it.
The point here is that I don't understand why some people dedicates so much effort ons hutting down progress with void arguments that Rx makes async/await useless.