None of this is functional reactive programming as originally formulated by Conal Elliott and Paul Hudak, which in particular emphasized the need to model reactive programs as the algebraic composition of simple abstract units, events and behaviors. If you have to set up a listener for an event, you aren't doing FRP, you're just doing Reactive Programming.
This same discussion comes up every time FRP is mentioned, because most articles that say they are about FRP are about Reactive Programming using Functional methods. You can keep bring it up every time you see such a post, but maybe it's better for your own sanity to just realise that ship has sailed: when people write about FRP, they write about this.
As Elliott himself suggested [0], it might be a good idea to use the term DCTP when talking about the concept you're talking about. Yes, it might feel wrong because his FRP was "first", but at least it's clear.
> To reduce confusion, I would like to see the term “functional reactive programming” replaced by the more accurate & descriptive “denotative, continuous-time programming” (DCTP)
This same discussion comes up every time FRP is mentioned, because most articles that say they are about FRP are about Reactive Programming using Functional methods. You can keep bring it up every time you see such a post, but maybe it's better for your own sanity to just realise that ship has sailed: when people write about FRP, they write about this.
My job is to write actual FRP so it's no sweat for me to vigorously complain every time that people are stealing "my" term :p
While Conal may have distanced himself from FRP, in the Haskell FRP community that's what we still call it.
Unfortunately a very common mixup. Here is Erik Meijer (aka headinthebox), the main guy behind Rx, talking about the difference[1]:
Let's keep "FRP" for what it really stands for in honor of it's inventor (http://conal.net/talks/). Rx is not FRP and was explicitly designed as a discrete collection API on purpose (as opposed to continuous time varying values).
...
Of course Conal no longer likes the name Functional Reactive Programming for what he did. And "Reactive Programming" was never really a good name for the non-continuous case either, it's really just a variant of dataflow programming.
> And "Reactive Programming" was never really a good name for the non-continuous case either, it's really just a variant of dataflow programming.
well, dataflow programming has always been central to reactive programming, isn't it ? that's what all reactive languages, Esterel, Lustre, etc. were about.
Yes, that's what I am saying, or rather: it's not "central to it", it is the thing itself.
"Reactive" is really just a re-branding of (synchronous) dataflow programming, and a fairly bad one at that because it just jumbles up and confuses so many things.
"Reactive" is/was really a type of system: one where you have continuous interaction with the outside world and the world generally cannot wait (similar but not identical to real-time). Contrasting with "transformational", where you just get some inputs turn them into outputs and are done, and "interactive", where you interact with the outside world but the world can wait.
It turned out that the synchronous dataflow languages (like Esterel, which is imperative, and Lustre, which is functional) had some fairly nice properties when it came to building reactive systems. As far as I know, Esterel is used for Airbus avionics...so the outside world really, really cannot wait :-)
How people somehow managed to mix up the style of system with the technology and then somehow also put in a claim that "functional" was an essential part of it is a little beyond me.
This has been very frustrating to me because it feels like many reactive frameworks for OOP languages are actively muddying the waters. I've had stuff like ReactiveX recommended to me as "FRP" and it's nothing like the form, and just wastes my time.
If actual FRP for web wasn't doing so relatively well, I would begin to fear that FRP is heading the same way OOP did after Smalltalk, a shadow of the actual thing pushed as a buzzword to sell to marketing managers with no clue or concern about the actual tech.
And god help me, I do not want to see what the C++ of FRP looks like ...
judging from where i work, that has already happened to a large degree, and i would guess elsewhere too... as alan kay would say "its all a pop culture"
Can someone explain the synergy of using reactive with functional? Reactive is great and functional is great but I don't see what they have to do with each other.
You are correct, there isn't really any synergy, and it's just a re-framing of synchronous dataflow programming using somewhat convoluted terminology and technology.
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...
Elm is pure function and reactive but it is not FRP especially with its latest Elm architecture. The language does not use anything like Haskell's IO or State monad, yet is perfectly capable of building complex applications. It shows that one can have pure functional language for reactive systems with relatively simple type system. One just needs to provide thoughtful architecture and libraries.
The framework is custom. But I was really talking about how great reactive was for my application. It is a control system with a lot of inputs and outputs. The graph is about a dozen levels deep.
I can't answer this without knowing your definition of reactive.
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.
It's easier to reason about highly asynchronous code if all you can do is transform and compose streams, and all side-effecting work happens at the "ends of the pipe", so to say.
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.
> Arbitrary side-effects coupled with asynchronicity are a recipe for Heisenbugs.
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.
Well, sure, you can program imperatively without side-effects, but you can also use side-effects within asynchronous streams. The point of using functional programming with reactive programming is that you have a guarantee that you won't get non-deterministic behavior.
From my small experience with following Elm tutorials and implementing simple apps is that such debugging is not necessary. Elm strongly encourages to use a serializable state with no things like long-lived lambdas or closures capturing arbitrary stack frames. In turns it makes reasoning about the code very easy. In my cases just by observing the bug for the first time I could almost immediately find the code triggering the misfeature. This was absolutely not the case with pages with relatively small JS that I dealt occasionally in past.
The fundamental building block of FRP is something called a Behavior, which is a container for a value that changes over time. More specifically, it's not just any container - but rather one which follows laws that make it a candidate for passing into pure functions that expect certain typeclasses (specifically it's a Functor, Applicative, and some others)
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.
In practice, I've used socket.io and redis to glue dbs and apis and queues and schedulers and clients together and the clients listen to sockets for data payloads to modify the views. View interaction sends event payloads to modify the various systems which kick off further data payloads. That is the entire concept. No article was necessary in the making of this post.
Why was this downvoted? React essentially uses observables, right? Child components don’t directly listen to changes in the state objects of their parents. Instead, parents know how to update their children when setState is called. Thus, the inversion of dependencies decouples objects in React in the same way observers are decoupled from their subjects in RxJS. Redux has a dependency on RXJS for a reason.