Hacker News new | ask | show | jobs
by TeMPOraL 1957 days ago
I thought TFA meant flashing in the metaphorical sense - it's the code paths that light up, not things on the screen.

Circular dependencies are an unfortunate fact of life, and I wish we had tools to deal with them, instead of desperately trying to avoid them.

A good test for a UI paradigm is, how do you handle a UI like this:

  A = [50] [====|     ]
  B = [10] [|         ]
  C = [60] [=====|    ]
  A + B = C
Where [===| ] things are sliders, all three are changeable, and the relation A+B=C must always hold.
2 comments

The problem is under-specified. When you move a slider, how should the other two adjust? There are many possible solutions and you haven't specified any preference here.

The easiest solution is to maintain a fixed order of preference, something like:

  values = [a:0, b:0, c:0]
  fn onChange(key, value) {
    values[key] = value
    for (k,v) in values {
      if (k !== key) values[k] = adjust(k)
    }
  }
  fn adjust(key) {
    switch(key) {
      case 'a': return max(0, values[c] - values[b])
      case 'b': return max(0, values[c] - values[a])
      case 'c': return values[a] + values[b]
    }
  }
The alternative is to maintain the latest selections made by the user and use that as the iteration order.

Whatever approach you go with, the "single source of truth" approach of react/vue/svelte + state (whether it is state in hooks, redux, mobx or whatever) holds. The "values" above is the source of truth, and the components just reflect that.

In other words: from a state point of view you don't have three sliders each with a value but a "three-valued component that happens to be shown as three sliders".

You can add a constraint solver on top of it. So when e.g. C changes, you solve for A and B. You then update the state of A, B, C and redraw. This kind of interaction can be handled by a separate library which is not necessarily part of a GUI system.
A constraint solver is overkill here, in particular as you cannot solve for A and B uniquely, you might want to add some further rule, like A and B should grow proportionally, when C is modified.

But otherwise, yes, just use a framework that separates State from UI and has bidirectional updates, like SwiftUI.