Ascending Functional Reactive Programming 5/7

Nicolas Roumiantzeff
Esker-Labs
Published in
8 min readDec 2, 2020
Photo by Simon

How did Functional Reactive Programming Originate?

Quite likely, after reading the previous posts in the series, simple unanimous functional reactive programming has become your holy grail too. The remaining episodes cast light on the state of the art of functional reactive programming. This post is dedicated to academic works, where it all began.

Part 1/7 Why is Reactive Programming so Complicated?
Part 2/7 Functional Programming to the Rescue?
Part 3/7 Why is Functional Programming so Controversial?
Part 4/7 Functional Reactive Programming: Simple and Unanimous?
Part 5/7 How did Functional Reactive Programming Originate?
Part 6/7 Where is Functional Reactive Programming Now?
Part 7/7 Which Functional Reactive Programming is the Grail?

In the sections below, I will share with you my findings uncovered throughout my quest for simple unanimous functional reactive programming.

I will give a score from 0 to 10 for each of the following criteria: functional, reactive, simple and unanimous.

To support the score, I will list the corresponding facts and thoughts, prefixed with “✅” when positive, “❌” when negative or “💡” when informational.

Disclaimer:

There are so many Functional Reactive Programming projects, frameworks, PHDs, libraries, languages that I could not list them all. The more you dig, the more comes up.

Although I tried to be honest (at least with myself) and objective when evaluating the criteria, the scores only reflect my humble own feelings. Although I dug and dug until I was comfortable with a criteria, I still might have missed or misunderstood important points.

Because of the browser-side web applications target, for the simplicity criteria, I gave my preference to JavaScript implementations and formalisms over alternative languages. Likewise, for the unanimity criteria, I gave my preference to real world Web applications over academic works and esoteric applications.

When it comes to the evaluation of the simplicity criteria, a low score most certainly reflects my own limited capacity to grasp complex abstractions. When it comes to the evaluation of the unanimity criteria by myself alone, I take responsibility for the shortcomings.

1. Functional Reactive Animation (Fran) 25/40

The term Functional Reactive Programming, FRP, is attributed to Conal Elliott and Paul Hudak following their 1997 publication. The Fran model is based on 2 main notions, Behavior (continuous) and Event (discrete) functions of time.

1.1. Functional 10/10

✅ Fran is declarative: “a set of richly expressive recursive data types, combined with a declarative language, serves comfortably for modeling animations, in contrast with the common practice of using imperative languages to program in the hybrid modeling/presentation style”.

✅ A Fran program is made of functions that transform functions over time (input Behaviors and Events) into functions over time (output Behaviors and Events).

✅ Fran is implemented in a pure functional language (Haskell).

1.2. Reactive 5/10

✅ The animated model reacts to values that continuously change over time (called Behavior by the authors) and time occurring conditions (called Event by the author).

💡 Fran implements reactivity in an original way, in which the program modifies itself depending on the occurrence of an Event (Behavior switching).

❌ Conal Elliot himself published a post “Why classic FRP does not fit interactive behavior”.

1.3. Simplicity: 5/10

Behaviors and Events are functions over time. Damn simple!

💡 Some derivative FRP works unify the two notions of Behavior and Event into one called Signal.

❌ In Fran, occurrences of an Event is not a direct input to the system but needs to be detected using complex techniques (resolving the equation on t representing time and where e represents the Event function: e(t) = true).

❌ The Haskell formalism.

1.4. Unanimity: 5/10

✅ Being officially recognized as the reference of functional reactive programming is certainly a very good point.

❌ Fran is implemented in Haskell.

❌ The efficiency of Fran implementation has been challenged. Conal Elliot himself came up with a Fran enhancement called Push-Pull FPR, a push model for Events and a pull model for Behaviors. See below for derivative works on the subject.

❌ As stated by Conal Elliot himself, Fran model allows responding to future input, violating the principle of causality. See below for derivative works on the subject.

2. Signal-function FRP: 24/40

To enforce causality, Arrowized FRP, AFRP, restricts direct access to signals (functions over time): an AFRP program is an Arrow (a Monad generalization) of signal-functions (functions mapping signals to signals).

N-ary FRP considers a signal-function as a function from a signal vector to a signal vector. A distinction is made between Signal functions (continuous functions of time), Step functions (constant functions of time intervals) and Event functions (functions only defined at specific points in time). This allows an optimized evaluation of the system based on function changes.

TimesFlies introduces the concept of Push-Pull signal-function FRP. It optimizes N-ary FRP using a push-based evaluation of Events and a pull-based evaluation of Behaviors.

2.1. Functional 10/10

✅ All these signal-function FRP systems are functionally pure, pushing functional features to the edge (types, category theory).

2.2. Reactive 7/10

❌ AFRP is pull-based thus Event evaluation is not immediate (delayed until the end of the sampling interval).

Event evaluation optimization in N-ary FRP is not a full optimization (as stated in the thesis) thus, some Event evaluations may lag.

❌ Push-pull signal-function FRP uses a non-deterministic Event ordering (“there is no way to guarantee the order of observation of event occurrences occurring in the same sampling interval”). Swapped events is the last thing you need in reactive programming!

2.3. Simplicity: 2/10

❌ The complexity of signal-function FRP program is greater than of the classical FRP. Each enhancement of either the safety or the efficiency has come at the price of more complexity: for example, to enhance safety, we switched the global model from f(t) (functions over time) to f(f(t)).

💡 Attempts have been made to simplify the formalisms (notably using Haskell syntactic sugar) but require additional knowledge.

2.4. Unanimity: 5/10

✅ Safety is an important factor.

✅ Efficiency is an important factor.

❌ Complexity is a factor even more important when it comes to mass adoption.

💡 The benefits of enhancements over classical FRP are balanced by the loss of simplicity.

3. Real-Time FRP, Event-Driven FRP: 23/40

Real-Time FRP (RT-FRP) is a resource-bounded sub-set of classical FRP which makes it well suited for real-time or embedded systems.

Event-Driven FRP (E-FPR) generalizes RT-FRP replacing the clock ticks by numerous arbitrary events while maintaining a proof of resource bounds.

3.1. Functional 5/10

❌ E-FRP syntax is not the typical functional syntax as it uses phase tags (for example, ϕ: “” or “later”) which seems to break referential transparency and is not point-free. For example, here is the syntax to define a reactive Behavior: r ≡ stepAccum x = c in {Ii ⇒ di ϕi}.

❌ It is not clear whether reactive Behaviors may be combined using combinators.

3.2. Reactive 9/10

✅ E-FRP programs react to Events (the program itself has a reactive behavior and may change upon Event occurrence).

✅ E-FRP responds to an Event with a resource bound handler ensuring that the system is highly responsive.

❌ An event carries no value except its type (it is unsure whether implementing values attached to events would break the soundness of E-FRP or not).

3.3. Simplicity: 7/10

✅ The definition of events is simple.

✅ The full syntax of E-FPR is short.

❌ Some notions, as phase and store, are not simple to grasp.

❌ E-FRP compiles a declarative source language program into a procedural target language.

3.4. Unanimity: 5/10

✅ The definition of events in E-FRP is close to that of client-side web applications.

❌ E-FRP has been used for niche applications (programming of interrupt-driven micro-controllers) and has not demonstrated its usefulness for client-side applications yet.

4. Concurrent FRP (ELM): 30/40

ELM is a pure functional language for GUI development, it compiles to JavaScript and its design prevents run time exceptions thanks to its static type system.

ELM is also an architecture, The ELM Architecture, pioneer of the unidirectional-binding model (which tends to take over the older tumbling two-way-binding model) and the virtual DOM.

The ELM Architecture is based on the following concepts: Model (a type defining the structure of the GUI state), View (a function transforming the GUI state to the GUI rendering), Update (a function from the GUI state and a GUI event to a new GUI state).

4.1. Functional 7/10

✅ ELM is a pure functional language.

✅ ELM promotes declarative programs.

❌ Some have argued that although each concept of the ELM architecture (Model, View, Update) is composable, defining and combining GUI components requires a lot of wiring.

❌ Since version 0.17 (where signal functions have been removed in favor of event subscription), ELM has moved away from FRP. Isn’t ironic that ELM started with an FRP thesis in 2012 then underwent a reversal in direction with “a farewell to FRP” in 2016.

4.2. Reactive 10/10

✅ ELM programs respond to an event in a timely manner even when previous event computations take a long time (concurrency).

✅ ELM programs respond to an event efficiently, avoiding re-computation of functions not affected by the event (memoization).

4.3. Simplicity: 7/10

❌ Compiling to JavaScript adds a layer of complexity.

✅ The ELM Architecture is simple.

✅ The ELM language is simple. Furthermore, since version 0.17, the ELM learning curve is easier.

4.4. Unanimity: 6/10

✅ The ELM language is safe.

✅ The ELM Architecture is powerful (it is unidirectional and fractal).

❌ Learning a new language.

❌ Although the Virtual DOM is a bright idea, It has its disadvantages: efficiency, duplication, difficulty to maintain the entire model in the state (such as the caret position).

❌ Elm is rather inconvenient in areas such as URL routing support and scaling.

❌ Defining state-full components (for instance a component representing an HTML input element) seems difficult.

Should I care or should I not?

It depends whether you are an academic researcher or a professional software developer!

The path is more important than the goal!

Ignorance of your culture is not considered cool!

Well, I have not found the Grail yet but taking a deep dive into the academic ocean was indeed a singular experience, exhausting but interesting. In the following post, we will review the most significant functional reactive programming implementations in the professional world and see how they compare to their academic elders. Are you longing to know whether or not React actually is functional reactive?

Thanks
I would like to thank Wikipedia without which the Ascending Functional Reactive Programming series would not exist, its website creators, content contributors and financial donors (perhaps including you and me).

About the author
Nicolas Roumiantzeff is a developer team member in one of 10 R&D scrum teams at Esker, a French SaaS company, where he designed and implemented several client-side JavaScript frameworks for highly customizable Web applications.
He likes music, JavaScript (he might already have told you that) and planet Earth.
His tech superheroes are:
Albert Einstein who showed that you could achieve astonishing findings with an extremely cheap experiment, long before the browser console is at your (F12) fingertips,
Andrew Wiles who showed that you could reach your most inconceivable dream even if your first attempt fails,
Alan Turing who showed that you could prove the unprovable,
Grigori Perelman who showed that being skilled in rocket science does not prevent you from being skilled in rocket lifestyle,
Brendan Eich who showed that such a big huge impact could come out of such a tiny little thing.

--

--

Nicolas Roumiantzeff
Esker-Labs

Nicolas Roumiantzeff is a developer team member in one of 10 R&D scrum teams at Esker a French SaaS company. He likes music, JavaScript and planet Earth.