
Reactive Programming and MVC (2014) - ghosthamlet
http://aaronstacy.com/writings/reactive-programming-and-mvc/
======
bsaul
The rx fallacy is to make you believe that programming at the most general
abstract level is the best. It’s just wrong. An array is not a stream, an
observable that can fire at any time isn’t the same as a predefined list of
things.

Whenever you abstract a data structure, you loose some meaning, some
peculiarities that helps you understand what you’re doing.

Rx should be used by framework or low level libraries developers, to factor
code. But it should be almost invisible to the api user.

~~~
coldtea
> _The rx fallacy is to make you believe that programming at the most general
> abstract level is the best. It’s just wrong._

Citation needed.

> _Whenever you abstract a data structure, you loose some meaning, some
> peculiarities that helps you understand what you’re doing._

That's obviously not true.

The whole idea is to abstract over peculiarities that are not needed
(implementation details for example).

So, you "loose some meaning, some peculiarities that helps you understand what
you’re doing" only some times (when you abstract badly) and not "whenever you
abstract a data structure".

> _Rx should be used by framework or low level libraries developers, to factor
> code. But it should be almost invisible to the api user._

That makes even less sense - having abstraction as the hidden lower level. The
whole point of abstraction is giving a higher level interface.

~~~
bsaul
Abstraction is, by definition, reducing different things to a shared subset of
their attributes.

Eg : the concept of "Human" is an abstraction over all the different
attributes of all the individuals, to reduce them to the ones they all share.
If i say i met a "human being", you can't tell if it's a "he" or a "she", if
he has dark of blond hair, etc. What you can tell, is that it has a heart and
a brain, stand on at most two legs, and has at most two arms. That could be
all you need to deduce a few things, but by saying so, i kept some details
hidden from you.

Now, if we get back to rx, its whole purpose is to work with the concept of
"streams of events". Noting that many data structure and patterns (such as
iterators over arrays, or event source observation) can be thought a specific
kind of even streams.

This lets you define stream-combination operations, that work on all those
structure. Which _may_ , _sometimes_ , be convenient.

The problem is when people start telling you that the generic tools around Rx
Stream (producer, consumer, publish subject, etc) are the best tools to model
the behavior of all your application, because "everything is in fact one big
giant stream of events".

And then you end up with code monstruosities, because you realize that it's
more complicated than that. Maintaining a UI state and mutating it becomes a
nightmare, you start wrapping every native structures (such as arrays) into
Observers just to perform the equivalent of a join, etc. Either the stdlib and
frameworks are "reactive", and then using rx pattern would be invisible, or
you're going to have a horrible code.

In some way, it's exactly like generics, or base superclass : you define them
in the stdlib, for example to share code between Sets and Arrays, but what the
end user is manipulating 99% of the time isn't "Iterable". It's Arrays and
Sets.

~~~
CuriousSkeptic
The problem is that Rx isn’t about “streams of events”. The main interface,
IObservable, is entirely about _subscribing_ to “streams of events”.

It’s the awful brittleness of handling those subscriptions that makes it so
hard to program with.

Compare that to something like signals in Elm (originally, it has changed now)
while it makes some things Rx allow you to do impossible reports from users
are that once it type checks “it just works”

~~~
breatheoften
An interesting podcast on the topic where the creator of elm discusses the
creation (and removal) of signals in elm.

[https://overcast.fm/+HSqxOglhQ/17:21](https://overcast.fm/+HSqxOglhQ/17:21)

------
dmitriid
A few problems I personally have with Rx are:

\- 99.9999% of examples and tutorials on the internet fit one page of code.
It's enough to look at something more complex, and you get immediately lost,
because:

\- Rx is very good at modelling streams that go _in one direction_ , from A to
B. From B to C. The to D etc. The moment you need the results of computation
in C back in A... Oh, yikes. You start having Subjects everywhere (or
BehaviourSubjects? Or ReplaySubjects? Or AsyncSubjects?) which may and will
(if you are just starting learning these things) become extremely messy

\- Rx may be easily viewed as async programming. Because your transformations
happen at some unspecified non-deterministic point in time (and a lot of
operations _are_ async). So, debugging is hell. RxJS and (IMO) RxJava have
tried to improve this, but it's still a mess. Properly structuring your code
and streams so that you understand why and when a certain something happens?
No one teaches you that. And you need that because your `.map(transform)` has
no idea when and who invoked it. Etc.

\- it doesn't help that Rx has cold and hot observables that _everyone_ gets
burned by. And I mean _everyone_. Oversubscription? Undersubscription? Events
not firing? Events firing multiple times? These all happen. And some stream
libraries go as far as not having cold observables at all. Good article about
that: [https://staltz.com/cold-and-hot-
callbacks.html](https://staltz.com/cold-and-hot-callbacks.html)

\- even such a fundamental thing as the concept of time may be screwed. See a
primer on schedulers: [https://staltz.com/primer-on-rxjs-
schedulers.html](https://staltz.com/primer-on-rxjs-schedulers.html)

\- My favourite thing: everyone tells you how easy and simple Rx is: it's just
observables. In his book on RxJava the _creator_ of RxJava says that it took
him several _months_ to understand Rx. While being tutored by one of the
_creators of ReactiveX_. It's "easy and simple" in the same sense as "Haskell
is easy and simple" or "rocket science is simple and easy" or <any branch of
human knowledge> is simple and easy once you know and understand it.

All in all, streams of things are a good idea. Splitting your work into small
isolated side-effect free chunks of work is a good idea. With Rx though,
unless you are bright yourself or you have someone to mentor you, Rx is an
unassailable bastion.

~~~
aaimnr
"\- My favourite thing: everyone tells you how easy and simple Rx is: it's
just observables. In his book on RxJava the creator of RxJava says that it
took him several months to understand Rx. While being tutored by one of the
creators of ReactiveX. It's "easy and simple" in the same sense as "Haskell is
easy and simple" or "rocket science is simple and easy" or <any branch of
human knowledge> is simple and easy once you know and understand it."

The problem here is that "simple" and "easy" are two completely different
concepts. "Simple" is absolute, "easy" is relative.
[https://www.infoq.com/presentations/Simple-Made-
Easy](https://www.infoq.com/presentations/Simple-Made-Easy)

~~~
dkersten
Rx is neither simple nor easy, for non-trivial projects. Its an incredibly
leaky abstraction and you end up having to understand the internals to do non-
trivial things. Understanding when something runs in what thread (and in
RxJava knowing when to use subscribe/subscribeOn/observeOn was much harder
than it claimed to be), how to correctly handle errors, retry failed
operations, apply backpressure without dropping data — these things
essentially force you (in my experience, at least, but I’m no Rx expert, just
used it for a few months) to dig into the internals to understand how they
work: ie not simple.

But because of its lack of simplicity, it was also incredibly hard to use, to
make it do what you want. So it was neither simple nor was it easy.

(And yes, I buy into the differences between simple and easy)

------
kylecordes
To rephrase a quip, I have found often that RxJS and similar tooling is the
worst way to get correct behavior... except for all the others.

More than once I have set down a path to avoid RxJS, because of the complexity
of explaining it and bringing a new developer up to speed... and ended up
writing more code and having more difficulty producing correct results.

My context is in web applications, SPAs. Typically with Angular, but I've used
many tools in this space, including React, Redux, Cycle (which has its own Rx-
like library), etc. The tricky part in all this is pervasive asynchronicity.

Here's an example. Looking back at the AngularJS era, most of the applications
I have seen (including review of many of our big customers applications) have
incorrect behavior in the case of servers with jittery response time. It is
quite easy to make an event handler load some data, and miss the fact that the
data arrives in a different order than it was requested. Very easy to avoid
with RxJS. If anyone's interested in this bit, here's a video explaining the
merit of RxJS even with AngularJS 1.x, before the adoption of RxJS in Angular
2+.

[https://www.youtube.com/watch?v=XY9VPrKuJaA](https://www.youtube.com/watch?v=XY9VPrKuJaA)

~~~
dfee
I "learned" RxPy in a couple hours yesterday (a 3rd party lib I'm using has an
interface that requires me to use them), and I figure I'll share a bit about
my experience:

1) the documentation is supremely lacking (subjects aren't even mentioned in
the RxPy repo
[https://github.com/ReactiveX/RxPY](https://github.com/ReactiveX/RxPY))

2) the generic documentation points to language specific documentation –
that's 80% just "TBD"
([http://reactivex.io/documentation/subject.html](http://reactivex.io/documentation/subject.html))

3) it's actually quite simple once you figure out it's just code level pub/sub
with a new naming convention.

4) there seem to be some opinionated perspectives around using it in the
community, though largely from a JS perspective (look into "should I use
subjects").

Despite those flaws, I've found it pretty accessible, and I'll actually switch
out some home-grown code for it.

[edit] I noticed some other comments complaining about execution handling
(threads, etc.) so I figured I'd update this and say, maybe I got lucky as
it's all pretty straightforward in Python (as long as you understand your
app's execution environment (threads, asyncio, etc.) ->
[https://github.com/ReactiveX/RxPY#schedulers](https://github.com/ReactiveX/RxPY#schedulers)

------
ivarru
Disappointing. The title should say (2014). I would say that this field has
matured a bit in 3.5 years.

~~~
sctb
Thanks, we've updated the title.

