Live data from Hacker News

Managing State with Signals

tonsky.me

81–90 of 126 posts

Re: Managing State with Signals

#81
post #23

Earlier quoted context omitted.

Thanks for this thoughtful and insightful comment. Many problems can be workflow problems, sometimes even pulling in a rule engine, or require a job queue to do things that can fail. Then you have software such as https://temporal.io/ which is really powerful for resilient workflows. Imagine coordinating the user with a workflow with asynchronous data collection steps. Imagine programming "reaction to user behaviour…

Thanks for the compliment. Since you seem to like it, i’ll emphasis a little as to how i came to realize that : It’s very common that workflows are suited for data manipulation: write the data to disk, when it’s complete send it to the network, then once it’s completed, etc. I/O are known to be asynchronous, so we’re already equiped for that. What i noticed is that the screen of your app is also a source of asynchron…

Would love to talk more.

You're right, users are asynchronous event sources. I feel UI development is very hard to read and complicated to implement complicated features.

Turning desired behaviours into code is pretty difficult for me.

I have written a few Java Swing apps and an Electron app. I also tried to use Qt but I wasn't a C++ developer so that didn't go so well.

There is a good article that the mouse is a database. The idea that the mouse creates data that can be reacted to. https://queue.acm.org/detail.cfm?id=2169076

Re: Managing State with Signals

#82
post #80

Not sure I like the mixed push/pull approach. If you're already traversing the tree to mark nodes as possibly dirty, you might as well recompute the node's value and store it while you're there. Otherwise on pull/lazy update, you're traversing the tree all over again! Terrible for cache locality, particularly for large graphs. You might be tempted to say that the lazy approach might avoid some recomputations, but if…

I implemented the eager recomputation model for the observable utilities in vscode [1] and it quickly fell on my feet because of these glitches. In particular this is problematic if you have observable optional state that has inner observable/derived state and someone reactively reads the outer state and then it's inner if the outer one is defined. Then you clear and dispose the outer state and at the same time set s…

Yes, if you want to better tolerate glitches you have to separate internal and external reactivity, and only run the external ones after the full reaction is complete. I think this would prevent the scenario you describe, assuming your operators are well-defined.

The other option is to use FrTime's approach and only update nodes in dependency order.

Re: Managing State with Signals

#83
post #25

Elm started as a FRP language and ended up giving up FRP[1] for ease of use. If ease of use is targeted, signals might not be the best approach. I distinctly remember things becoming easier when they went away. [1] https://elm-lang.org/news/farewell-to-frp

That was one of the most interesting developments in the already fascinating saga of Elm. Czaplicki gets a lot of flak, but it's almost all about how he keeps tight control of his language & ecosystem. No one duns him for brains, because he's clearly very smart. So when he says, "everything related to signals has been replaced with something simpler and nicer", it's news, eh?

Re: Managing State with Signals

#84
post #69

Earlier quoted context omitted.

Thanks for this thoughtful and insightful comment. Many problems can be workflow problems, sometimes even pulling in a rule engine, or require a job queue to do things that can fail. Then you have software such as https://temporal.io/ which is really powerful for resilient workflows. Imagine coordinating the user with a workflow with asynchronous data collection steps. Imagine programming "reaction to user behaviour…

I often wonder about some sort of unified distributed system, encompassing frontend & backend into a single whole. One where user input is just something the system can ask and wait for, no matter which frontend or client it comes from. But I’ve only ever been able to catch glimpses of it. More of a nebulous feeling and intuition than a real understanding of how such a thing would work. Something that feels obviously…

I like your thinking a lot.

There was a Haskell project that seamlessly transferred state between frontend and backend but I don't think it was a distributed system. I don't remember what it was called.

Writing APIs to glue together data fetching and actions and GUI state is all very siloed. If you could talk about the system as a whole including GUI interactions at the same time as system interactions that could be truly powerful.

Imagine multi omnichannel event streams that map to the users notifications, email inboxes, chat interface, post, deliveries, accounting, customer data, synchronisations, integrations, microservices and business CRM and ERP. Everything is linked together by powerful workflows. An interaction with a customer is just an extension of the system. It's a distributed system of human tasks as well as digital tasks and interactions between the customer and the company.

Re: Managing State with Signals

#85
post #80

Earlier quoted context omitted.

I implemented the eager recomputation model for the observable utilities in vscode [1] and it quickly fell on my feet because of these glitches. In particular this is problematic if you have observable optional state that has inner observable/derived state and someone reactively reads the outer state and then it's inner if the outer one is defined. Then you clear and dispose the outer state and at the same time set s…

Yes, if you want to better tolerate glitches you have to separate internal and external reactivity, and only run the external ones after the full reaction is complete. I think this would prevent the scenario you describe, assuming your operators are well-defined. The other option is to use FrTime's approach and only update nodes in dependency order.

With dependency order you mean dependants before dependencies? (and dependencies lazily when they are requested again by the dependant)

If you update dependencies before dependants, the dependant might not depend on all it's dependencies anymore (because a derived might depend on A only if the observable B is true) and you do too much work/run into glitches.

Re: Managing State with Signals

#87
post #85

Earlier quoted context omitted.

Yes, if you want to better tolerate glitches you have to separate internal and external reactivity, and only run the external ones after the full reaction is complete. I think this would prevent the scenario you describe, assuming your operators are well-defined. The other option is to use FrTime's approach and only update nodes in dependency order.

With dependency order you mean dependants before dependencies? (and dependencies lazily when they are requested again by the dependant) If you update dependencies before dependants, the dependant might not depend on all it's dependencies anymore (because a derived might depend on A only if the observable B is true) and you do too much work/run into glitches.

Dependency order = values are computed in the same order as they would be in a purely pull-based system, which is intrinsically glitch-free

Push-based systems permit better efficiency and minimal state changes, but they should endeavour to preserve the above property for external observers.

Re: Managing State with Signals

#88
The author does a lovely job of covering a number of the interesting ideas in this space. But reactive programming is such a tough sell. I know from experience.

I maintain a reactive, state management library that overlaps many of the same ideas discussed in this blog post. https://github.com/yahoo/bgjs

There are two things I know to be true:

1. Our library does an amazing job of addressing the difficulties that come with complex, interdependent state in interactive software. We use it extensively and daily. I'm absolutely convinced it would be useful for many people.

2. We have completely failed to convince others to even try it, despite a decent amount of effort.

Giving someone a quick "here's your problem and this is how it solves it" for reactive programming still eludes me. The challenge in selling this style of programming is that it addresses complexity. How do you quickly show someone that? Give them a simple example and they will reasonably wonder why not just do it the easy way they already understand. Give them a complex example and you've lost them.

I've read plenty of reactive blog posts and reactive library documentation sets and they all struggle with communicating the benefits.

Re: Managing State with Signals

#89
post #41

It looks like we are going to keep reinventing dataflow constraints[1] over and over again, always with slightly different terminology (Rx, FRP, signals, ...) So it (a) appears to be a very useful or at least attractive concept, and (b) somehow difficult to fit into current programming languages/practice in a clean way. [1] https://blog.metaobject.com/2014/03/the-siren-call-of-kvo-an... (HN: https://news.ycombinator.…

Surprisingly, FRP doesn't have anything to do with dataflow constraints at all. In FRP, a program is fundamentally a function of type Stream Input → Stream Output. That is, a program transforms a stream of inputs into a stream of outputs. If you think about this a bit more, you realise that any implementable function has to be one whose first k outputs are determined by at most the first k inputs -- i.e., you can't l…

> Note that there is no dataflow here: it's just an ordinary state machine.

It sounds like you've converted data-flow to its state-space form. It's still data flow, just in a variant that might be easier to compute.

FWIW you probably need a pair of functions :

    next state = F(input, current state)  
    output     = G(input, current state)
Which in the signal-processing/control systems world is

    s = Ax + Bs
    y = Cx + Ds
Aka the "state space" formulation where A, B, C, and D are matrices, x is the input, s is the state, and y is the output. There are infinite ways to formulate the state space and infinite equivalent signal flow graphs that represent the same thing.

Re: Managing State with Signals

#90
post #88

The author does a lovely job of covering a number of the interesting ideas in this space. But reactive programming is such a tough sell. I know from experience. I maintain a reactive, state management library that overlaps many of the same ideas discussed in this blog post. https://github.com/yahoo/bgjs There are two things I know to be true: 1. Our library does an amazing job of addressing the difficulties that come…

Is it because of cognitive load? I briefly looked at your project, and I'm still not convinced that your solution is easier to comprehend than

function onLoginClick() { validateFields(); networkLogin(); updateUI(); }

Post reply on HN