Can it be true that Revise doesn’t work with macros.
I experienced the problem when developing a package that has functions that use a macro. Then when I change the macro, the functions are not updated.
But a similar minimal working example can also be shown with includet:
# revisemacro.jl
macro returniffalse(verbose, ex)
quote
if !($(esc(ex)))
if $(esc(verbose))
println("A False expression in $(@__FILE__):$(@__LINE__): ", $(string(ex)))
end
return false
end
end
end
function afunction()
avariable = 23
@returniffalse(true, avariable == 20+1)
end
Open a REPL and do
julia> using Revise;
julia> includet("revisemacro.jl");
julia> afunction()
A False expression in /home/pakis/Playground/julia/ReviseMacro/revisemacro.jl:5: avariable == 20 + 1
false
Then if I change the macro in revisemacro.jl the function is not updated
Macros and generated functions
If you change a macro definition or methods that get called by @generated functions outside their quote block, these changes will not be propagated to functions that have already evaluated the macro or generated function.
You may explicitly call revise(MyModule) to force reevaluating every definition in module MyModule. Note that when a macro changes, you have to revise all of the modules that use it.
Revise.revise of course won’t work for a includet file because it’s not a tracked module.
Revise only makes it easier to do the same interactive evaluations you can manually run in the REPL, and despite the extra options for more reevaluations, that can never behave like reloading the session and evaluating everything from scratch. For example, you can’t successfully change the annotated type of a global variable. Redefinitions of methods called by other methods work smoothly because the call is not executed during definition. If you edit a method definition, previous calls are not reevaluated; the same applies to macro methods. Here’s a macro-less example:
Even with __revise_mode__ = :eval, _foo::Int = foo() is not reevaluated when foo() = 2.3 is edited because its expression was not changed; if it was, it’d fail anyway.
My preferred workaround to this is to have the implementation in a separate function which is called by the macro:
function _foo(expr)
return :(x = $expr)
end
macro foo(expr)
_foo(expr)
end
That way you can still take advantage of Revise, and in some cases it makes testing easier because you can just call the function with different inputs.
Editing _foo doesn’t seem to re-evaluate @foo calls in other methods (example below) like filchristou wanted, could you elaborate with a demo? PS I think we need esc(_foo(expr)).