bodil / purescript-signal

Elm style FRP library for PureScript
Apache License 2.0
258 stars 44 forks source link

Atomic update #55

Open zhangchiqing opened 7 years ago

zhangchiqing commented 7 years ago

Is it possible to implement atomic updates, so that if a signal receives multiple updates from its dependent signals, it will only emit one signal value if these updates are originally from the same signal update?

For example, let's say signal b and signal c depend on signal a, and signal d depends on both b and c. If there is new signal value sent to signal a, it should trigger only one signal. This is the dependency graph:

    a
  /   \
 b     c
  \   /
    d

As if right now, it triggers twice.

main = do
  cn <- channel 1
  let a = subscribe cn
  let b = (_ + 1) <$> a
  let c = (_ + 3) <$> a
  let d = (+) <$> b <*> c
  let ds = (\x -> [x]) <$> d
  let all = foldp (<>) [] ds
  send cn 100
  runSignal (all ~> show >>> log)
* Build successful.
[204,105,6]

^^^^^^^^^^^ Expect to be [204, 6], but got [204,105,6]. 204 = (100 + 1) + (100 + 3) 105 = (100 + 1) + (4) 6 = (1 + 1) + (1 + 3)

105 is an intermediate value that could be ignored if supports atomic updates.

Atomic updates is useful for UI rendering optimization. If a view's rendering depends on multiple signals, and they are all updated by the same signal value from their dependencies, atomic updates can make sure the view will only be rerendered once.

born2defy commented 6 years ago

I actually implemented this to solve the same issues, but ended up just doing a complete rewrite since it made more sense and I wanted a way to manually feed and extract values through the signal graph. I took influence from Elm's original implementation which essentially requires each node to keep track of its parent updates so that it knows when all parents have been updated before it recalculates its value. In order for this to happen though, all parents must pass a value down to their descendants on every update cycle regardless of whether the parent has updated or not. Evan talks about this issue in his white paper on Elm.