Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

See results during calculation #476

Closed
j-fu opened this issue Sep 23, 2020 · 9 comments · Fixed by #1597
Closed

See results during calculation #476

j-fu opened this issue Sep 23, 2020 · 9 comments · Fixed by #1597
Labels
reactivity The Pluto programming paradigm

Comments

@j-fu
Copy link
Contributor

j-fu commented Sep 23, 2020

Just an idea - I am thinking about possibilities to present results of time dependent calculations within Pluto. The possibility to do this via animated @gif in Plots is there, but this is quite restricted and a bit far away with other packages.

I was thinking about the following: Currently, cell1 like

for i in 1:10
    global a
    a = i
end

with the dependent cell2

a

results in the value 10.

Now I imagine a macro, let's name it @emit which allows the following

for i in 1:10
    global a
    a = i
    @emit a
end

@emit would trigger the recalculation in cell2 each time it is called, and we would see the development
of it's results. It could be restricted to work only in places where the cell value would be returned if it would not be there.

@karlwessel
Copy link
Contributor

If this is possible to do it could be really cool, for example for a live display of statistics collected with OnlineStats.jl.
And of course for debugging purposes.

@Pocket-titan
Copy link
Contributor

Though not as comprehensive as the potential @emit macro you're describing, there is already a way to do time-dependent computations in Pluto using the Clock function from PlutoUI:

clock2

As of right now there are no ways to programmatically stop or start the Clock (which might be desirable - note that in the gif, the third cell keeps rerunning even though its value doesn't change, since the clock keeps ticking), but if there were, I think you'd be pretty close to achieving the behaviour you're describing.

@j-fu
Copy link
Contributor Author

j-fu commented Sep 23, 2020

Yeah it could be done via a kind of iterator over an collection which spits out the next value only if i has changed. Something like this

mutable struct ClockChecker
    last_i
    count
    ClockChecker() = new(1,0)
end
checker = ClockChecker()
if running(checker, i) # just check if i has changed since last call, and if so increase counter
    j = count(checker) 
    algorithmic_step(j)
end

This hinges at the situation that Pluto doesn't detect mutations in structs (and array elements).
With the right naming (tried so here) this might be explainable to students, so may be this is good enough if @emit doesn't get a go. The it might also got into PlutoUI. Thinking about a PR...

@j-fu
Copy link
Contributor Author

j-fu commented Sep 23, 2020

But it would be good it the clock would not start on loading, but only after the first push of "start".

@GiggleLiu
Copy link
Contributor

+1 for adding a kwarg to allow not start on loading.

@fonsp
Copy link
Owner

fonsp commented Sep 24, 2020

(continuing a discussion from JuliaPluto/PlutoUI.jl#47)

updating a scene from within the for loop

This is a problem, because it breaks the all important goal: "At any instant, the program state is completely described by the code you see."

I think that the solution could be lazy lists. The basic use case:

Animation([expensive_result(t) for t in 1:100])

Could be made runtime/memory efficient by describing the frames using a lazy map:

Animation(map(expensive_result, @lazy 1:100))

Here, Animation is called immediately, and can generate frames lazily, when the UI requests one.

In your example, the simulation depends on the previous step, which makes it a trickier accumulate/reduce problem:

Animation(accumulate(advance, @lazy 1:100, init=x0))

with

function advance(old_solution::Array, t::Number)::Array
	...
	return new_solution
end

@fonsp fonsp added the reactivity The Pluto programming paradigm label Sep 24, 2020
@GiggleLiu
Copy link
Contributor

GiggleLiu commented Sep 24, 2020

At any instant, the program state is completely described by the code you see.

Interesting. But I am wondering if Pluto can have more possibility as a stateful machine.
A typical using case is GUI, it have to be a state machine in most cases. Currently, we can use mutable structs as the state of the machine to simulate it.

I think the key point is how to make this robust. I am quite interested in thinking more into this direction. An example is given here.
https://gist.github.com/GiggleLiu/7ab57094475d0a496112807d3235b8f5

@fonsp fonsp changed the title Emit cell results during calculation See results during calculation Sep 25, 2020
@fonsp fonsp linked a pull request Nov 3, 2021 that will close this issue
13 tasks
@fonsp
Copy link
Owner

fonsp commented Nov 3, 2021

#1597 together with https://github.com/JuliaPluto/PlutoHooks.jl will make this possible! #437 is also related

@fonsp fonsp removed a link to a pull request Nov 3, 2021
13 tasks
@fonsp fonsp linked a pull request Nov 3, 2021 that will close this issue
8 tasks
@kbarros
Copy link

kbarros commented Jul 18, 2022

For us late-comers, here is how to achieve j-fu's original goal with the new Pluto features.

Use PlutoUI to create a clock widget with start/stop buttons:

@bind i Clock() 

Then create a new cell which gets triggered by each update to i. The key is to use the @use_ref macro from PlutoHooks to store mutable state in the variable ref::Ref. The code is:

begin
    i # dependency on clock variable
    ref = @use_ref(1.0)
    θ = 0.01
    ref[] *= exp(2π*im*θ)
end

The variable i appears at the top to indicate a dependency between cells, but its value is never actually used. In this example, clicking the start button of the clock will cause ref[] to spin around the complex plane.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reactivity The Pluto programming paradigm
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants