fonsp / Pluto.jl

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

Issue when running macro. Not evaluating Symbols properly. #2765

Closed co1emi11er2 closed 6 months ago

co1emi11er2 commented 6 months ago

Hello,

I am new to Julia, but feel like I have a somewhat good grasp on metaprogramming after spending quite a bit of hours trying to get this macro to work. I am a structural engineer who is trying to create a better alternative to excel for calculations. The gist of the macro is it takes the popular latexdefine macro from latexify and adds only two extra lines. This allows me to see both the symbolic equation as well as the numeric substitution before the final result.

It essentially parses through the expression and evaluates the symbols to replace them with their numeric value. This works the first time I enter the equation, but if I update any of the variables, it reruns the cell but does not update the variable value in the numeric substitution. If I then re-run the cell with the macro, the variable disappears. I can fix it by re-running the include("handcalc.jl") cell that initializes the macro into the notebook and then re-running the cell where I call the macro. I thought this may be a global/local scope issue, but this seems to be a non-issue in a jupyter notebook, and it works as intended. See video below:

https://github.com/fonsp/Pluto.jl/assets/143426779/71e2f5e0-beea-4331-b724-18fa1511c30c

Here is the code for the macro as well. I plan to either add pull request it to latexify or make it available in a package if they aren't interested. I need to modify it a bit though still before then!

image

Here is the link to the pluto notebook https://gist.github.com/co1emi11er2/ab972028afe52568ebcfa57655f6e4ec

Thanks in advance. I really love Pluto. I want to try and bring coworkers slowly away from excel, and I think Pluto could do it.

Thanks again, Cole.

Pangoraw commented 6 months ago

The problem here is calling eval(x) in the macro body which results in the literal value of x being put in the returned expression. Pluto only analyzes the @macroexpand @handcalc expr expression and cannot therefore see that x is referenced. Using something like Expr(:($), esc(x)) would be more Pluto friendly as the symbol contained in x would appear in the expanded expression.

co1emi11er2 commented 6 months ago

Substituting in Expr(:($), esc(x)) results in an error. I believe it is because it is returning something latexify can not evaluate since it is not a number. This is what is returns for example a. image

I don't think this is being evaluated either anyway, because doing something like this causes similar issues. When I change that respective value (a), the printed terminal line goes away. image

I guess what is Jupyter doing differently? I change the value of lets say a in Jupyter and then rerun the @handcalc h = (-b + sqrt(b^2 - 4*a*c))/(2*a) cell, and everything is updated and works.

I thought all Pluto did was rerun any cell that is dependent on a. I know it re-runs the cell, because the value of h changes properly as seen in the original video. It just seems strange that I get three different results when I change the a cell, then I manually re-run the handcalc cell, and then finally manually re-running the handcalc macro cell.

Pangoraw commented 6 months ago

It seems escapping is not needed so replacing eval(x) only with Expr(:($), x) appear to do what is expected and trigger reactivity.

I thought all Pluto did was rerun any cell that is dependent on a.

Yes, but it cannot know that the cell is dependent on a if a is not present in the expanded expression. The difference with Jupyter, is that every run will re-trigger macro expansion whereas it only happen in Pluto when the run button is explicitely clicked for that cell.

co1emi11er2 commented 6 months ago

Awesome! Thanks. This seems to be working!