Get help from the marimo community

Updated 6 months ago

Recommended way for self-triggering computation / semi-infinite loop?

At a glance

The community member is looking for a recommended way to trigger a cell that mutates state to re-run after it's done, under certain conditions. They tried using a combination of switch and stop, but it seems to result in an infinite loop. The community member's actual use case is to plot the output of an iterated map at every iteration, and they want a "as quick as possible" update instead of fixed time increments.

The comments suggest trying to use the include_self flag on set_state, but that doesn't seem to help. Another community member suggests putting the get and set in the same cell and using include_self. However, the original community member is not sure that's the issue, and they just want a way to kill the infinite loop once it's running.

The community members discuss various ideas, such as using the on_change parameter of the mo.ui.switch input to emit an event to break the set/get cycle, raising an error, and using mo.output.replace. However, no definitive solution is

Useful resources
Is there a recommended way to trigger a cell (which mutates state) to re-run after it's done -- under some conditions?

I was under the impression the following combination of switch/stop would do the trick, but it doesn't seem to be able to escape the infinite loop?

Plain Text
import marimo as mo
import random
import time


Plain Text
get_seconds, set_seconds = mo.state(1)


Plain Text
def expensive_computation():
    seconds = get_seconds()
    time.sleep(seconds)
    set_seconds(random.randint(1,3))


Plain Text
infinite_loop = mo.ui.switch(
    False,
    label="infinite loop",
)
infinite_loop

Plain Text
mo.stop(not infinite_loop.value)
expensive_computation()


My actual use-case (https://marimo.io/p/@gvarnavides/iterative-ptychography) is less contrived. Essentially I'd like to plot the output of an iterated map at every iteration. Right now, I'm doing it with mo.ui.refresh - which works well, but I'd like a "as quick as possible" update instead of fixed time-increments (since the computation time varies with batch_size).
M
G
A
13 comments
On set_state, I think there is an include_self flag you can pass
The refresh button has network latency and other latencies included so not great as an accurate timer
I played around with include_self and it doesn't seem to help (in-fact presumably the default False is designed to capture this infinite-loop behaviour?)
I think you can put get and set in the same cell and use include_self
Not sure that's the issue? like I can get set/get to loop infinitely just fine.
I just want a way to kill that once it's running. The following doesn't seem to work
Plain Text
mo.stop(not infinite_loop.value)
expensive_computation()


playground here: https://marimo.app/?slug=19s2hr
oh sorry I misunderstood. Hmm yea Iโ€™m not sure how to interrupt that
I wondered if the on_change parameter of the mo.ui.switch input could be used to emit some sort of event to break the set/get cycle, but not sure what that would be
Could you raise an error?
wow, that doesn't seem to bother it either haha
Plain Text
def raise_(val):
    if not val:
        raise ValueError()

infinite_loop = mo.ui.switch(
    False,
    label="infinite loop",
    on_change=lambda v: raise_(v)
)
hmm I have no other ideas. We can look into supporting this if there is a good api. Seems like start/stop has been somewhat tried a few times
@Georgios Varnavides can you use mo.output.replace?
hmm, trying to think how exactly ๐Ÿค”
I'd still need to mutate state for the iteration of the sort x_{n+1} = f[x_n] right?
Recommended way for self-triggering computation / semi-infinite loop?
Add a reply
Sign up and join the conversation on Discord