Functional Reactive Programming

Functional Reactive Programming (FRP) is like FunctionalProgramming except that each function can accept a stream of input values. If a new input value arrives on an argument, then the function is reevaluated with all the most recent input values, and a new output value is created. This is a kind of DataflowProgramming. It can handle nondeterminism, so it is more expressive than declarative concurrency. -- PeterVanRoy

FRP has intentionally deterministic semantics. Specifically, the meaning of a behavior/signal is a function from time to values. I don't know where the idea that it "can handle nondeterminism" came from. And I'd say, FRP is an example of FunctionalProgramming, rather than being like FunctionalProgramming. --ConalElliott

Note: ConalElliott and PaulHudak? were the inventors of FRP. If there is an authoritative definition, it is theirs. The original FRP supports instantaneous events in addition to continuous behaviors.

Experiments in this paradigm have been done in OzLanguage, HaskellLanguage, SchemeLanguage, and JavaScript. The commercial EsterelLanguage also looks promising. It also sounds similar to FlowBasedProgramming.


In modern design, FRP is often arrowized - we describe a behavior as a function from signal to signal:

  type Sig a = T -> a
  type SF a b = Sig a -> Sig b

By restricting constructors for SF, it is possible to protect against anti-causal behaviors (where we look into the future of the input) and enforce other efficiency properties.

Discrete-varying FRP is also popular, i.e. where behaviors change only at specific instants. They allow much greater performance.


Advantages of FRP

At the small scale, FRP doesn't offer any real advantages over FunctionalProgramming or ProceduralProgramming. I.e. given a small example such as 'a = b + c', the fact that 'a' might vary over time doesn't seem a big deal. When it changes, just re-evaluate the expression! If you need to know when it changes, just poll! poll! poll!

However, as the system begins to scale upwards in any one of several dimensions (number of inputs, number of observers, concurrency of changes, size of expressions, number of expressions, integration across modules, etc.) FunctionalReactiveProgramming begins to offer several advantages over other paradigms:


Challenges for FRP

FRP has very few troubles so long as it is written entirely in the 'perpetual NOW'. However, to update the 'perpetual NOW' in response to (for example) user input, one would certainly need to escape the FRP paradigm and resort to SideEffects that will modify the world as it NOW exists. "Escaping the paradigm" isn't a bad design option, though it might sound better if we called it a "companion paradigm". But the interface between paradigms becomes a point for much awkwardness, and is undesirable... and to handle 'interaction' is critical to develop pretty much any service at all, be it UserInterface or a WebServer or DeviceDriver or PluggableArchitecture.

[1]: an exception here is modifying the language implementation. A language that supports runtime specializations and beta-reduction of functions, and performs GarbageCollection to remove unnecessary code, would go a very long way towards draining many leaks. And enforcing that 'Time' is monotonically increasing may also help.

[2]: ReactiveDemandProgramming embraces these issues and notions fully, making reactive, concurrent, continuous, and potentially conflicting 'demand' an explicit part of the model.


FRP has intentionally deterministic semantics. Specifically, the meaning of a behavior/signal is a function from time to values. I don't know where the idea that it "can handle nondeterminism" came from. And I'd say, FRP is an example of FunctionalProgramming, rather than being like FunctionalProgramming. --ConalElliott

PeterVanRoy further explains FunctionalReactiveProgramming's ability to 'handle nondeterminism'. Paraphrasing from memory: FRP may be hooked to external time-varying values, perhaps controlled by user, an OS file, or hooking into sensors of other sorts. The updates to these external (time-varying) data sources may be non-deterministic (they certainly aren't determined locally), yet FRP can 'handle' this nondeterminism quite effectively by propagating the updates to observers of the function. Properly, this must be achieved without glitches. For example, a change of 'x' from 2 to 3 is essentially atomic across all observations - x*(x+2) must go from 8 -> 15, not 8 -> 12 -> 15 or 8 -> 10 -> 15 as would be the case if the update to x is seen in one sub-expression before another.

It may be necessary to sacrifice some determinism (or at least switch to eventual determinism) if FRP is to scale to very large programs.


It seems, then, that most HardwareDescriptionLanguages are FRP. Verilog simulators, in particular, try to optimize the simulation time by computing results only when inputs change. I seem to recall some Verilog simulators being able to farm out work to dedicated processing nodes too (imagine trying to simulate a VLSI chip on a single computer!). This would seem to suggest, then, that FRPLs would be ideal for simulation applications. --SamuelFalvo?

If you exclude delays then they'd be pure FRP. By introducing delays, they become state-machines, and a lot of the features offered by the less expressive pure FRP are lost. I won't say that impure FRP is 'bad', but even simple hybrids greatly hinder many composition and optimization that can be safely performed in a pure FRP design. One would be even better off with a clean separation between the FRP layer and the state/delay/communications layer.

FRP can model delays and state (e.g. accumulators of events, integrals). It's still a pure function of the input signals. There are some similarities with Verilog and SynchronousReactiveProgramming?, but FRP is pure with respect to outside communication (no $write equivalent).


There isn't much here about implementation of FunctionalReactiveProgramming. Much of what I have found while having a look is based on HaskellLanguage. See SpecifyingBehaviorInCpp for an isolated example in CeePlusPlus. Much of what there is can be applied for FunctionalSimulationProgramming. -- JohnFletcher

There are many ways to implement FunctionalReactiveProgramming. Haskell has a library for it. Many spreadsheets software serve as simple implementations. Flapjax, Bling, LabView, etc. also offer impure FRP. I have not seen many languages aimed at pure FRP, but FRP really needs a companion paradigm to make a practical language. You might peruse http://lambda-the-ultimate.org/node/2057

There are two easily accessed examples of very-large-scale implementations (though the programmers might not have used the term "FunctionalReactiveProgramming" to describe what they do) complete with open source code, published API's, and large development communities to learn from --Twitter and Google Wave. Wave lets everyone on a wave see what you are doing to it in real time, so I'd guess they've found good answers to all the interesting questions. -- MarcThibault


See also HaskellArrows.
CategoryFunctionalProgramming ProgrammingParadigm

EditText of this page (last edited April 17, 2012) or FindPage with title or text search