What is the definition of a "glitch" in the context of Functional Reactive Programming?
I know that in some FRP frameworks "glitches" can occur while in others not. For example RX is not glitch free while ReactFX is glitch free [1].
Could someone give a very simple example demonstrating how and when glitches can occur when using RX and show on the same example how and why the corresponding ReactFX solution is glitch free.
Thanks for reading.
Reactive programming is simply to program using, and relying on, events. instead of the order of lines in the code. Usually this involves more. than one event, and those events happen in a sequence over time.
Functional programming paradigm is built upon the idea that everything is a pure function. Reactive programming paradigm is built upon the idea that everything is a stream observer and observable philosophy.
Reactive programming is a programming paradigm that deals with data flows and the propagation of change. It means that when a data flow is emitted by one component, the change will be propagated to other components by reactive programming library.
The basic idea behind reactive programming is that there are certain datatypes that represent a value "over time". Computations that involve these changing-over-time values will themselves have values that change over time. For example, you could represent the mouse coordinates as a pair of integer-over-time values.
My (own) favorite definition:
A glitch is a temporary inconsistency in the observable state.
Definition from Scala.Rx:
In the context of FRP, a glitch is a temporary inconsistency in the dataflow graph. Due to the fact that updates do not happen instantaneously, but instead take time to compute, the values within an FRP system may be transiently out of sync during the update process. Furthermore, depending on the nature of the FRP system, it is possible to have nodes be updated more than once in a propagation.
Consider integer variables a
, b
. Define sum
and prod
such thatsum := a + b
,prod := a * b
.
Let's rewrite this example to JavaFX:
IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
NumberBinding sum = a.add(b);
NumberBinding prod = a.multiply(b);
Now let's write a little consistency check:
InvalidationListener consistencyCheck = obs -> {
assert sum.intValue() == a.get() + b.get();
assert prod.intValue() == a.get() * b.get();
};
sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);
a.set(1);
b.set(2);
This code fails with an assertion error on the last line, because:
b
is updated (to 2)
sum
is updated (to 3)
This is a glitch — prod
is temporarily inconsistent with a
and b
.
First note that ReactFX is not "glitch free" out of the box, but it gives you tools to eliminate glitches. Unless you take some conscious effort to use them, ReactFX is not more glitch-free than RX (e.g. rxJava).
The techniques to eliminate glitches in ReactFX rely on the fact that event propagation is synchronous. On the other hand, event propagation in RX is always asynchronous, thus these techniques cannot be implemented in an RX system.
In the example above, we want to defer listener notifications until both sum
and prod
have been updated. This is how to achieve this with ReactFX:
import org.reactfx.Guardian;
import org.reactfx.inhibeans.binding.Binding;
IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
Binding<Number> sum = Binding.wrap(a.add(b)); // Binding imported from ReactFX
Binding<Number> prod = Binding.wrap(a.multiply(b)); // Binding imported from ReactFX
InvalidationListener consistencyCheck = obs -> {
assert sum.getValue().intValue() == a.get() + b.get();
assert prod.getValue().intValue() == a.get() * b.get();
};
sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);
// defer sum and prod listeners until the end of the block
Guardian.combine(sum, prod).guardWhile(() -> {
a.set(1);
b.set(2);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With