In fact, what "reactive programming" does is solve the problem that FP has with reactive systems[1], in that it isn't suited for them at all. FP, pretty much by definition, is suitable for transformational systems, i.e. systems that map some inputs to some outputs and are then done.
With just FP, there really isn't any way to build reactive systems, that is systems that continuously react to external and internal stimuli, whereas reacting (responding) to stimuli (messages) is pretty much the definition of OO.
By treating input as (infinite) streams of data and applying collection processing to those, you can sort of map this to the aforementioned dataflow programming and solve your problem. Of course, just using dataflow programming directly is both simpler and faster, but hey...
[1] https://www.inf.ed.ac.uk/teaching/courses/seoc/2005_2006/res...
But a good reactive system is simpler to write, understand, and debug. At least that is what I found in my latest project.
Because what you write certainly sounds a lot like just dataflow.
To me, dataflow is simply a stream of data triggering calculations even if the data is unchanged. e.g. the stream of 1,2,2,3 would cause four calculations.
Reactive means that only 1,2,3 would appear to the calculations. In other word only changes are reacted to.
My framework is reactive by these definitions.
Arbitrary side-effects coupled with asynchronicity are a recipe for Heisenbugs.
Additionally, if you add in the constraint that you can't change signal routing at runtime and you only use pure functions on stream, you can actually debug by moving streams to any point in their history and figuring out what the system is doing with them. That's a very common debugging technique in the Elm programming language, for instance, as shown here: https://www.youtube.com/watch?v=RUeLd7T7Xi4.
I find it easy to avoid side-effects in imperative reactive code. With side-effects I wouldn't call it reactive.
> , if you add in the constraint that you can't change signal routing at runtime
Once again, this is easy in imperative code.
I am not complaining about functional code. It definitely has its place (just not for me). I just finished an awesome product with imperative reactive code and I thought maybe I was missing something.
The result is that you can do the same things with a Behavior as you can with other Functors and Applicatives and things - for example you can `map` it with a function that operates on that inner value (whatever it may be) and you'll get a new Behavior which contains that transformed inner value.