I appear not to be understanding macros.
Question: Why is my variable not being resolved when it’s called from within a macro?
Thanks in advance
Here is my macro:
return println(""" "$criteria," """)
If I simply run the return statement, I get the desired result, which is a quoted string with comma. See below:
julia> x = "ABC"
julia> println(""" "$x," """)
But if I use my macro, I get this:
julia> @SW1 x
Question: Why is my variable not being resolved?
Macros transform syntax to syntax. Normally you return syntax in the form of a quoted expression from a macro, but if you leave out the quotes, what you return is just treated as a constant. Inside the macro body,
:x, i.e. a symbol named
x (the syntax that constitutes the macro’s input); the macro body never sees the value bound to
x. Once you understand that, it follows that e.g.
"$(:x)" is just the string
"x" (which you can test at the REPL as well), and that’s why you get this result.
What you want instead is to have the macro create code (in the form of a quoted expression) that references
x. This is made a little bit more confusing in this case by the fact that
$ is used both to interpolate into quoted expressions, as well as to interpolate into strings. To avoid this confusion, I’d propose doing the string interpolation in a separate function, called in the code generated by the macro. Furthermore, you’ll should escape the input using
criteria_string(criteria) = """ "$criteria," """ # *string* interpolation
println(criteria_string($(esc(criteria)))) # *expression* interpolation
If you’re wondering what happens when you don’t use
esc, here’s an example:
x = 1
criteria_string(criteria) = """ "$criteria," """
x = 2
"1,"! This is because without
x will be resolved in the macro definition environment (i.e. module
M), while you want it to refer to the
x that’s in the macro call environment (the one outside