Hi, I am not sure if this is the right place for meta programming questions. Please redirect me if you think there is a better place to ask this question.
My understanding is that in order to keep macro hygiene, I need to use
esc to keep global space variables seperate from local variables.
So I wrote the following macro, and expanded it to see the result.
Julia> n = 1 Julia> macro esc_example(a) quote n = 3 println(n) println($n) println($(esc(n))) println($a) println($(esc(a))) end end Julia> @esc_example(n) 3 1 1 3 1 Julia> macroexpand(:(@esc_example(n))) quote # REPL, line 3: #33#n = 3 # REPL, line 4: (Main.println)(#33#n) # REPL, line 5: (Main.println)(1) # REPL, line 6: (Main.println)(1) # REPL, line 8: (Main.println)(#43#n) # REPL, line 9: (Main.println)(n) end
n as 1 in REPL, and a local variable
n as 3.
I am not sure if esc() can be used on macro arguments, so I want to test it as well.
Let me go through it line by line, left side is the macro definition, and right side is the macro expansion .
n = 3=>
#33#n = 3 # REPL, line 4:
nis defined locally as 3, so when expanding macro, the name is reassigned with a name
#33#nto make sure it does not collide with names in global space. I think this one is straight forward.
(Main.println)(#33#n) # REPL, line 5:
Just prints out the local
(Main.println)(1) # REPL, line 6:
$nis string interpolation. Replacing
nin global space with its value 1.
This one is a little confusing because I thought I have to use $(esc(n)) to get the value of n in global space.
(Main.println)(1) # REPL, line 8:
This is the use of esc(). and it is getting the value of
nfrom global space. Understood. But I thought the macro expansion will replace it with something like
Main.n, rather than the value 1, because it should not be evaluated at macro expand time. Am I right? And if they have the same effect, what is the benefit of using
(Main.println)(#43#n) # REPL, line 9:
I think this line is a bug. Because this line should prints out the value of
a, which is
nin global space, the value 1. But instead it is replaced with the local
Like I said in the before, I don’t know if
esc()can be used on arguments so I am trying it out.
I was expecting an error, but it was replaced with
nin global space. Maybe someone can help me understand this part.
Here is the version info from Julia
julia> versioninfo() Julia Version 0.6.3 Commit d55cadc350 (2018-05-28 20:20 UTC) Platform Info: OS: macOS (x86_64-apple-darwin14.5.0) CPU: Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz WORD_SIZE: 64 BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell) LAPACK: libopenblas64_ LIBM: libopenlibm LLVM: libLLVM-3.9.1 (ORCJIT, skylake)
I apologize for the long post. I am trying my best to explain my confusion.
And thank you for reading through my question.