Terminology: What is a “glitch” in Functional Reactive Programming / RX?

前端 未结 3 1930
情书的邮戳
情书的邮戳 2020-12-28 19:11

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 n

相关标签:
3条回答
  • 2020-12-28 19:58

    Short answer : glitch = inonconsistent/illegal/meaningless state.

    Here is a relevant link : https://social.msdn.microsoft.com/Forums/en-US/bc2c4b71-c97b-428e-ad71-324055a3cd03/another-discussion-on-glitches-and-rx?forum=rx

    Also, see the 29th minute of Sodium's author talk for another answer : http://youtu.be/gaG3tIb3Lbk.

    And a relevant SOF answer : how to avoid glitches in Rx

    So here is my understanding of what a glitch is based on Tomas' answer.

    There is a dataflow graph, with 3 nodes : A, B, C

    A->B

    A->C

    In this simple example, a glitch happens if I change A and that causes to change B but C has not been updated yet. This is a glitch.

    C is not consistent with B.

    Say B=2*A, C=2*A.

    Then if B is not equal C then that is a glitch.

    0 讨论(0)
  • 2020-12-28 20:00

    Here is an extremely short and theoretical example of a fatal "glitch" situation in C# RX

    var t = Observable
            .Interval(TimeSpan.FromSeconds(1))
            .Publish()
            .RefCount();
    
    var s = t.CombineLatest(t, (t1,t2) => 1/(1-(t1-t2));
    

    Since t1 and t2 both represent the latest value of the hot observable t, one would assume t1-t2 to always be 0. So s should always be 1.

    But when subscribing to s, we indeed get 1 as the first observed value, but then we get a division by zero exception. In RxJS we would get NaN.

    The reason is simple: a.CombineLatest(b, f) will react when either a or b produces a value, combining this new value and the last observed value of the other observable. This is by design, but from my experience, people using RX sometimes consider these to be glitches, especially when coming from other FRP libraries that have a different notion of "latest".

    This is of course a contrived example, just meant to illustrate a misconception about CombineLatest.

    Maybe CombineLatest should have been called WhenAny as in the ReactiveUI library, this would clarify the operational semantics?

    0 讨论(0)
  • 2020-12-28 20:15

    Definition

    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.

    Example

    Consider integer variables a, b. Define sum and prod such that
    sum := 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)
        • `consistencyCheck` is triggered, `a == 1`, `b == 2`, but `prod == 0`, because `prod` has not been updated yet

    This is a glitch — prod is temporarily inconsistent with a and b.

    Glitch Elimination Using ReactFX

    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);
    });
    
    0 讨论(0)
提交回复
热议问题