## Reactive normal form

The post “Reactive values from the future” presented a simple formulation of functional *events* and *reactive values*, built on a functional notion of *future values*. In the current post, I’ll describe some of the implementation of events and reactive values*.

## Reactive values

### Switching

As mentioned previously, the `stepper`

function corresponds directly to the representation of `Reactive`

.

data Reactive a = Stepper a (Event a) stepper :: a -> Event a -> Reactive a stepper = Stepper

The representation of all other functions must therefore produce their result in terms of `stepper`

, which thereby serves as a kind of *reactive normal form* (RNF). The implementation can be understood as a set of rewrite rules that convert arbitrary reactive expressions into RNF. (These rewrite rules are all provably correct based on a simple semantics of events and reactive values.)

The more general switching form can be expressed in terms of `switcher`

and (monadic) `join`

:

switcher :: Reactive a -> Event (Reactive a) -> Reactive a r `switcher` er = join (r `stepper` er)

We’ll see below how to reduce `join`

to a `stepper`

.

### Functor

As a simple example, `fmap f`

applies a function `f`

to a reactive value pointwise, which is equivalent to applying `f`

to the initial value and to each occurrence value.

The `Event`

functor is also easily defined. Recall that an event is a future reactive value:

newtype Event = Future (Reactive a)

We want to map a given function over that reactive value, which we can do by combining `fmap`

on `Future`

with `fmap`

on `Reactive`

.

### Applicative

The `Functor`

definitions for `Reactive`

and `Event`

are straightforward, because the `Stepper`

structure is easily preserved. A more challenging case is `Applicative`

.

instance Applicative Reactive where ...

First the easy part. A pure value `a`

becomes reactive by using `a`

as the initial value and `mempty`

as the (never-occuring) change event:

` pure a = a `stepper` mempty`

Consider next applying a reactive function to a reactive argument:

rf@(f `Stepper` Event futf) <*> rx@(x `Stepper` Event futx) = f x `stepper` Event fut where ...

The initial value is `f x`

, and the change event occurs each time *either* the function or the argument changes. If the function changes first, we will (in the future) apply a new reactive function to an old argument:

fmap (\ rf' -> rf' <*> rx) futf

Similarly, if the argument changes first, we will apply an old reactive function and a new argument:

fmap (\ rx' -> rf <*> rx') futx

Combining these two futures as alternatives:

A wonderful thing about this `(<*>)`

definition for Reactive is that it automatically caches the previous value of the function or argument when the argument or function changes. This caching property is especially handy in nested applications of `(<*>)`

, which can arise either explicitly or through `liftA2`

, `liftA3`

, etc. Consider `u == liftA2 f r s`

or, equivalently, `u == pure f <*> r <*> s`

, where `r`

and `s`

are reactive values, with initial values `r0`

and `s0`

, respectively. (The `(<*>)`

operator is associates to the left.) The initial value `u0`

of `u`

is `f r0 s0`

. If `r`

changes from `r0`

to `r1`

, then the new value of `pure f <*> r`

will be `f r1`

, which then gets applied to `s0`

, i.e., `u1 == f r1 s0`

. However, if instead `s`

changes from `s0`

to `s1`

, then `u1 == f r0 s1`

. In this latter case, the old value `f r0`

of `pure f <*> r`

is passed on without having to be recomputed. The savings is significant for functions that do some work based partial applications.

### Monad

Above we saw a simple definition of `switcher`

:

r `switcher` er = join (r `stepper` er)

How does `join`

work for `Reactive`

? Rather than using the standard definition of `join`

in terms of `(>>=)`

, let’s do the reverse:

r >>= h = joinR (fmap h r)

where `joinR`

is `join`

for reactive values:

joinR :: Reactive (Reactive a) -> Reactive a

Defining `joinR`

is similar to `(<*>)`

above. For a reactive-reactive value `rr`

, either `rr`

or the reactive value that is the initial value of `rr`

changes first.

joinR ((a `Stepper` Event fut) `Stepper` e'@(Event fut')) = a `stepper` Event fut'' where -- If fut arrives first, switch and continue waiting for e'. -- If fut' arrives first, abandon fut and keep switching with new -- reactive values from fut'. fut'' = fmap (`switcher` e') fut `mappend` fmap join fut'

## Dynamic optimization

Operations on events and reactive values dynamically re-optimize themselves. For instance, the reactive value `fmap f r`

is known to quiesce (stop changing) when `r`

quiesces, which is knowable because futures have a special representation for the future that never comes. (Really, only easy common cases are optimized. An example of a hard-to-detect never-occuring event would be filtering out first the odd numbers and then the even numbers from an `Int`

-valued event.) Similarly, the reactive value `liftA2 f r s`

quiesces once *both* `r`

and `s`

quiesce. Once reactive values quiesce, no more computational resource is devoted to them.

## Events

The definitions above are mainly for reactive values. What about functional events?

### Monoid

Events form a monoid: `mempty`

is the never-occurring event, which is represented by the never-occuring future, while `e `mempty` e'`

is an event consisting of all occurrences from `e`

and `e'`

.

instance Monoid (Event a) where mempty = Event mempty Event fut `mappend` Event fut' = Event (fut `merge` fut')

This `merge`

operation combines two `Future`

streams into one.

merge :: Future (Reactive a) -> Future (Reactive a) -> Future (Reactive a) Never `merge` fut = fut fut `merge` Never = fut u `merge` v = (onFut (`merge` v) <$> u) `mappend` (onFut (u `merge`) <$> v) where onFut f (a `Stepper` Event t') = a `stepper` Event (f t')

The `mappend`

used in the definition of `merge`

is from `Future`

. It picks the earlier future and abandons the other. Thus the first of the two events to occur will contribute an occurrence value (`a`

), leaving a residual event, which is combined with the not-yet-occurring event.

### Applicative and Monad

The `Applicative`

and `Monad`

instances for events are like those for lists, and unlike those for reactive values (given above). For instance, the occurrences of `ef <*> ex`

consist of `f x`

for all occurrences `f`

of `ef`

and occurrences `x`

of `ex`

. See the source code for details.

## Conclusion

I’m happy with the simplicity of this new functional formulation of events and reactive values. While most previous FRP implementations used polling, Reactive is change-driven and so has the can be much more efficient. It also uses a dynamically self-optimizing representation.

## Conal Elliott » Blog Archive » Invasion of the composable Mutant-Bots:

[...] a few recent posts, I’ve been writing about a new basis for functional reactive programming (FRP), [...]

6 February 2008, 9:14 am## Conal Elliott » Blog Archive » Applicative bots:

[...] Instead, I’d like lf <*> lx to have an output whenever either lf or lx has an output. If lf has an output f, I want to output f x, where x is the most recent lx output. Similarly, if lx has an output, I want to output f x, where f is the most recent lf output. This behavior is exactly how Applicative works for Reactive, as described in reactive-normal-form. [...]

15 February 2008, 9:35 am