
On Fri, 2012-03-30 at 02:30 +0200, Ertugrul Söylemez wrote:
Peter Minten
wrote: I've been trying to get my head around Functional Reactive Programming by writing a basic explanation of it, following the logic that explaining something is the best way to understand it.
Am I on the right track with this explanation?
You are explaining a particular instance of FRP. Functional reactive programming is not a single concept, but a whole family of them. Traditional FRP as implemented by reactive-banana (and older libraries like Elerea, Fran and Reactive) is based on behaviors and events. It uses the notion of a time-dependent value in a direct fashion. Conceptionally traditional FRP is this:
Behavior a = Time -> a Event a = [(Time, a)]
-- The current time at even seconds and half the current time at odd -- seconds:
alterTime = fullTime fullTime = switch (after 1) currentTime halfTime halfTime = switch (after 1) (fmap (/ 2) currentTime) fullTime
There is a second instance of FRP though called AFRP. The A stands for "arrowized", but in modern times I prefer to think of it as "applicative". The underlying control structure is now a category and the concept of a time-varying value is changed to a time-varying function (called signal function (SF)), which is just an automaton and there is an arrow for it. This simplifies implementation, makes code more flexible and performance more predictable. The libraries Animas and Yampa implement this concept (Animas is a fork of Yampa). Conceptionally:
SF a b = a -> (b, SF a b) Event a b = SF a (Maybe b)
alterTime = fullTime fullTime = switch (after 1) currentTime halfTime halfTime = switch (after 1) ((/ 2) ^<< currentTime) fullTime
Sorry, I don't understand this. Would it be correct to say that AFRP shares the basic ideas of FRP in that it has behaviors and events/signals and that the main difference comes from the way AFRP is implemented? As I see FRP it has three components: the basic concepts, the underlying theory and the way the libraries actually work. As far as I understand FRP (which is not very far at all) the basic concepts can, simplified, be formulated as: * There are things which have a different value depending on when you look at them. (behaviors) * It is possible to express that something has occured at a certain point in time. (events/signals) * Behaviors can change in response to events/signals. * A behavior's value may be different on different points in time even if no event has come in. "Normal" FRP theory expresses behaviors as "Time -> a" and events as "[(Time,a)]". AFRP uses some kind of "signal function" to express behaviors, or behaviors are signal functions and those functions interact with events. Anyway AFRP uses a completely different theoretical way of thinking about events and behaviors. The reactive-banana library uses some internal representation which exposes an API using applicative functors. The theory behind it, as shown in the haddock comments, is "Normal" FRP. The reactive library uses monads and not just applicative functors. It uses the "Normal" FRP style. Yampa/Animas use arrows and have a different underpinning in math. However the basic concepts of FRP are shared with all the other libraries. Netwire also uses AFRP but extends the theory with something called signal inhibition. Like everything else it shares the basic concepts of FRP. FRP concepts -> FRP -> reactive -> reactive-banana -> AFRP -> Yampa -> Animas -> wired AFRP -> Netwire Is this a correct way to summarize the differences? Greetings, Peter Minten