I want to define a macro similar to those in the code below, where the function
f is evaluated in the scope where the macro is expanded, but
default is evaluated in module
_ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.5.3 (2020-11-09) _/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release |__/ | julia> module A macro p() quote $(esc(:f))(x=default) = 1 end end macro q() quote function $(esc(:f)) end end end macro r() quote function $(:f) end end end macro s() quote f(x=default) = 1 end end macro t() :( f(x=default) = 1 ) end end Main.A julia> using .A: @p, @q, @r, @s, @t julia> @macroexpand @p quote #= none:2 =# f(var"#1#x" = Main.A.default) = begin #= none:2 =# 1 end end julia> @macroexpand @s quote #= none:5 =# var"#2#f"(var"#3#x" = Main.A.default) = begin #= none:5 =# 1 end end
This is consistent with the manual. Defining
f as a function is like assigning to it, so it’s a local variable. (It would be nice if the manual said that explicitly.) Unless it is escaped, it is replaced by a gensym.
julia> @macroexpand @q :($(Expr(:error, "malformed expression"))) julia> @macroexpand @r quote #= none:4 =# function var"#4#f" end end
esc(:f) works in some contexts, but not in others. Is there a way to do what
@q is trying to do?
julia> @macroexpand @t :(Main.A.f(var"#5#x" = Main.A.default) = begin #= none:6 =# 1 end)
That’s also odd. By my reading of the manual,
f should refer to the same thing in
@t as it does in