It sounds like you're saying "explicit FSMs are strictly more powerful than promises/coroutines". Which is true. However, they're inherently difficult to program. In my view, the key to simplicity and correctness of programs is reducing the amount of states the program can possibly have. Isolating a piece of code into a blocking sequence seems like a fairly good way of doing it.
Not sure what you mean by "simple examples without error handling". Just like normal synchronous code, promises and coroutines use exceptions, which have the nice property of composability: one catch for several statements/promises. So error handling is the same as in synchronous code.
Now granted, there's a LOT of async/reactive problems where sequential abstractions like promises are irrelevant. GUI programming comes to mind, where you want the view to reflect some reactive state that changes in arbitrary order.
For one operation, sure. It doesn't work when you want to compose multiple async operations, wait until all are finished, or race several of them to completion (e.g. useful operation competing against timeout). The purpose of promises/futures is this composability that allows you to get the order and timing of operations right.
What if you want to abort, or take another path, depending on an error code ? With callbacks there's a convention that the first parameter is either null or an error.
That's what the mapping operators are for: `.mapResult` (same as `promise.then`), `.mapError` (same as `promise.catch`), or `.map`. The latter has an errback signature, like Node.js callbacks. They can also return new futures, transforming the result asynchronously. On top of that, error handling in promises/futures is much easier than in callbacks, as you can use one error handler for a chain of operations. Kinda like exceptions in synchronous code.
This is news to me. Last time I looked into RxJS, I was unable to get a minimum useful core of less than 100 KB minified. Might want to look again, thanks!
Correct. Most websites are better off with static HTML or server-side rendering and the least possible amount of JS. However some apps DO have to be fat. And don't forget about Node.js.
We need a standard destructor interface instead of choosing a different word every time. Cancel, close, destroy, drop, unmount, they do the same thing. If we settled on ONE destructor interface, we could have automatic resource management. [1] I use `deinit` in all my libraries, as it seems to be the most neutral word appropriate for every case.
`arrive` — no particular reason. It's one "errback" method rather than two methods like `resolve/reject`, so it needs to have a neutral tone. Not too happy with it, better suggestions are welcome.