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