For some reason, I had to put quote
...end
block in the macro and ex
is generated programmatically. This code works.
macro addsum_out()
quote
ex = :(x+y)
sum(eval(ex))
end
end
x = [1 1 1]
y = [2 2 2]
z2 = @addsum_out
When the macro is put inside a module, it no longer works:
module MyModule
export @addsum
macro addsum()
quote
ex = :(x+y)
sum(eval(ex))
end
end
end
using MyModule
x = [1 1 1]
y = [2 2 2]
z = @addsum
It says:
ERROR: LoadError: UndefVarError: x not defined
I think I should put esc
somewhere, to evaluate the expression ex
in the main scope outside the module. What should I handle this?
In simple terms, scope of a variable is its lifetime in the program. This means that the scope of a variable is the block of code in the entire program where the variable is declared, used, and can be modified.
Meta-programming is when you write Julia code to process and modify Julia code. With the meta-programming tools, you can write Julia code that modifies other parts of your source files, and even control if and when the modified code runs. In Julia, the execution of raw source code takes place in two stages.
Answer: Macros are sort of functions which take as input unevaluated expressions. ( Expr ) and return as output. another expression, whose code is then regularly evaluated at runtime. This post isn't a. substitute for reading the section about macros in the Julia.
This is referred to as quoting. The : character, followed by paired parentheses around a single statement of Julia code, produces an Expr object based on the enclosed code. Here is an example of the short form used to quote an arithmetic expression: julia> ex = :(a+b*c+1) :(a + b * c + 1) julia> typeof(ex) Expr.
The problem here is that a macro (inside a module) referencing x
will look for x
in that module, e.g. MyModule.x
This is part of macro hygiene.
To prevent macro hygiene from happening, you need to esc(x)
-- that means it will use whatever x is in-scope at the call-site.
Your complete solution might look like:
macro addsum_out()
quote
esc(x) + esc(y)
end
end
or more concisely:
macro addsum_out()
:( esc(x) + esc(y) )
end
Note that this is slightly different from doing esc( :(x+y) )
which would be a escaping the +
function also. i.e. the module containing this macro might contain an overload for +
, and if you want to use this then don't escape the +
, otherwise do!
There is a little discussion about this subject in a guide I put together:
https://github.com/p-i-/MetaGuideJulia/wiki#example-swap-macro-to-illustrate-esc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With