fonsp / Pluto.jl

🎈 Simple reactive notebooks for Julia
https://plutojl.org/
MIT License
4.94k stars 285 forks source link

[FR] Judge if code is changed by Expr rather by text #377

Open marius311 opened 4 years ago

marius311 commented 4 years ago

Sometimes I clean up code in an already evaluated cell with spaces, etc... and Pluto marks the cell as dirty. I think it'd be great if Pluto could know that nothing has actually changed, thus avoiding the wasted computation time (I often work with cells that take non-trivial amounts of time evaluate).

If the comparison was done by running Meta.parse on the contents and comparing the resulting Expr objects with ==, from what I can tell, it's perfect. Here's an example,

julia> ex1 = Meta.parse("""
       if     x
                   1
       end
       """);

julia> ex2 = Meta.parse("""
       if x
           1
       end
       """);

julia> ex3 = Meta.parse("""
       if x

           1
       end
       """);

julia> ex1 == ex2
true

julia> ex2 == ex3
false

Note the false in the second case is because the line numbering changed, and ==(::Expr, ::Expr) is smart enough to compare this. This is the desired behavior because even though things like inserting newlines don't affect the result, it may affect future stack traces, so this is a case we do want to re-evaluate (ideally there might be a way to deal with line numbering changing without re-running code, but that seems realy hard, so this is probably what we want for now).

I did some benchmarking of Meta.parse for some random 10-20 line code samples from my notebooks and its ~1ms, which I think is probably fast enough to work in real-time.

Assuming I haven't missed anything and there's no objections, I wouldn't mind trying to hack on this myself, although no doubt someone more familiar with the code than me could do it faster, so no problem if anyone else wants to try.

fonsp commented 4 years ago

Yeah I'd like this too! But I think it should do that check and save while you type, and always run when you press the run button or Shift+Enter. So if you're just writing comments in your code, you would see your cell become outofsync, and a after a while it turns happy again

Otherwise the Run button doesn't always run the code - this would be confusing

ericphanson commented 3 years ago

+1 to shift-enter always running the code even if nothing's changed! Sometimes I re-run already executed cells if there's some stateful affect (unfortunately) or for a reactivity issue

fonsp commented 3 years ago

I implemented this request in https://github.com/fonsp/Pluto.jl/pull/1055 (including the comment above). Try it out and leave feedback on the PR!