Most resources on reactive programming, e.g. "A Survey on Reactive Programming" (Bainomugisha et al., 2012), introduce several characteristics by which different reactive solutions can be classified. One of these is which evaluation model is employed, that is, whether the reactive language (or library) is push-based or pull-based (or both).
Example: Let's take a look a this piece of pseudocode: var c = a + b;
In a reactive environment, c
is expected to always contain the sum of a
and b
. Accordingly, if a
or b
change, the value of c
has to be recomputed. In a push-based solution, a
and b
notify c
when their values have changed, so that c
's value can be recomputed instantly. In a pull-based solution, c
looks up the current values of a
and b
as soon as the value c
itself is being demanded. Thus, all recomputations are being delayed until c
's value is requested.
For quite some time now, I have tried to figure out what evaluation model is being employed by the JavaScript library Bacon.js. Let's assume the following:
var a = Bacon.constant(21); // Creates a Property
var b = Bacon.constant(21);
var c = a.combine(b, function (x, y) {
return x + y;
});
According to this section of the Bacon.js documentation, combinators such as combine
use lazy evaluation, that is, they "avoid evaluating values that aren't actually needed".
- Question 1: When are values "actually" needed?
- Question 2: Is it safe to assume that--at least in the case of the example above--Bacon.js employs a pull-based approach? Or am I mixing things up here?
However, towards the end of the section, the Bacon.js documentation mentions that if one wants "[t]o force evaluation at the time of original event, [one] can just use flatMap
". Really, now I am confused:
- Question 3: Respectively, is it safe to assume that Bacon.js employs a push-based evaluation model whenever I use
flatMap
? Or am I mixing things up here--again? - Question 4: I cannot really reproduce the example from above using
flatMap
instead ofcombine
. Does that mean that depending on what I am trying to do, Bacon.js sometimes employs a pull-based propagation of change, and sometimes it comes up with a push-based one?
To the one who can provide clarification, I would be very greatful. :P