Macros 宏中的奇怪卫生

Macros 宏中的奇怪卫生,macros,julia,hygiene,Macros,Julia,Hygiene,假设我在一个模块中有这个宏定义: module Example export @example_macro macro example_macro(a) quote local r = RemoteRef() put!(r, $(esc(a))) remotecall_fetch(2, (r) -> fetch(r), r) end end end 以下是它的扩展: julia> include("Example

假设我在一个模块中有这个宏定义:

module Example

export @example_macro

macro example_macro(a)
    quote
        local r = RemoteRef()
        put!(r, $(esc(a)))
        remotecall_fetch(2, (r) -> fetch(r), r)
    end
end

end
以下是它的扩展:

julia> include("Example.jl")

julia> using Example

julia> macroexpand(quote @example_macro a end)
quote  # none, line 1:
    begin  # /.../Example.jl, line 7:
        local #121#r = Example.RemoteRef() # line 8:
        Example.put!(#121#r,a) # line 9:
        Example.remotecall_fetch(2,(r) -> Example.fetch(r),#121#r)
    end
end
每个全局可用函数(如
put!
fetch
)都以模块名称作为前缀。我理解宏需要这样做才能保持卫生-如果在调用
@example\u macro
的模块中重新定义了
fetch
,并且将
fetch
按原样插入扩展中,它将无法正常工作

但是,这也要求
Example
模块不仅在主进程中可用,而且在第二个工作进程中也可用(因为
remotecall\u fetch
需要在其上执行
Example.fetch
)。我不想要它——毕竟,
fetch
是默认情况下所有工人都可以使用的基本功能


那么,有没有办法禁用在所有标识符前加上当前模块的名称?我认为这意味着将宏变成非卫生的,因为在宏扩展阶段无法确定某个标识符(如
fetch
)的定义位置,这对我来说很好。

因为这是一个非常深刻的问题,我认为您应该给Julia开发者自己一个机会,通过提问来回答这个问题


目前,您可以通过将宏中的整个
quote
块包装在
esc(…)
(不要忘记在
a
周围取下
esc
)来完全避免宏卫生问题,但我通常会建议您不要这样做,这样您就只能靠自己了

很好,我不知道
esc()
是“递归的”!其他语言(如Clojure)中类似的宏功能不能像这样工作。我会等待更多的答案,如果没有,我会接受你的答案。谢谢