Mutable values with multiple setters "bounce" forever

I have a notebook here where I have a few variables set by sliders, and elsewhere I have some increment and decrement buttons.

I’ve noticed that if I adjust the values quickly, sometimes they get caught in loops and the value will bounce back and forth. Not only do I then lose the ability to control that variable, but sometimes the entire notebook gets stuck and I have to refresh.

Kudos to the team for this not exploding my browser when it happens, but it’s still annoying.

Thanks!

Hello! The problem here is a circular definition:

{
  if (p !== mutable p_value) {
    mutable p_value = p;
    viewof p.input.p_value = p;
    viewof p.dispatchEvent(new CustomEvent("input"));
  }
}

The above cell references p and viewof p, so it will run whenever either of those change. But it also sets the value of p (indirectly) by dispatching an input event on viewof p. And, it sets mutable p_value, which triggers viewof p to be re-initialized, because viewof p depends on p_value.

You should avoid circular definitions. I’d delete the mutable p_value cell and instead use only viewof. Make viewof p the sole definition of the value of p, rather than trying to synchronize a view and a mutable. Here’s a short notebook showing how to mutate a view such as a slider from other cells:

Alternatively, you could use a custom view as your definition of p. Here’s my notebook on custom views:

With a custom view, both the slider and the buttons would be considered “secondary” views: they would mutate the primary view, and listen non-reactively to the main view for value changes.

This is definitely where I expected the issue to lie, but one of the reasons I got into all this mess with values and variables is because I couldn’t figure out how to:

  • update range of other variables when p changes
  • leave them alone if they were still within the bounds

Before, they were changing back to their default every time p changed. Additionally, I couldn’t get the max range to update without rerunning the cells.

Can you elaborate on what you mean by “update range of other variables when p changes”?

Yes, sorry.

When the value of p changes, it impacts the possible values for n, a, and k; n can be no larger than p-1, a can be no larger than (p-1)/2, and k can be no larger than p-1. Thus I’d like to adjust the range sliders.

I recommend using this:

This is awesome! Thank you!

1 Like

Closer, but still stuck actually. Using your example, I fixed up the sliders, which is great. But now my increment and decrement buttons dont work(if I try to increment and decrement viewof I get a SyntaxError: Assigning to r value). Following the example from the Change Log and here I tried making them mutable, which isn’t compatible with the sliders. :thinking:

Hey Bryan.

Here’s a fork of your sketch that implements the pattern Mike described above — avoiding the circularity in the definitions:

Now, the values (p, n, a …) are the single sources of truth, and the views are mutated directly by the increment and decrement buttons.

You’ll notice two new helper functions: update, and incdec, to DRY up the code a bit for mutating the slider views.

Let me know if anything in there isn’t making sense.

Cheers,
Jeremy

That was extremely helpful, thank you.

Here’s an updated one. Open to other feedback if you have it!