Странная гигиена в макросах

Предположим, у меня есть это макроопределение в модуле:

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) имеют префикс с именем модуля. Я понимаю, что это необходимо для того, чтобы макрос был гигиеничным - если, скажем, fetch был переопределен в модуле, в котором @example_macro называется, и fetch был вставлен в расширение как есть, он не будет работать правильно.

Однако это также требует Example модуль должен быть доступен не только в основном процессе, но и на втором работнике (так как remotecall_fetch должен выполнить Example.fetch в теме). Я не хочу этого - в конце концов, fetch это базовая функция, доступная по умолчанию для всех работников.

Итак, есть ли способ отключить префикс всех идентификаторов с именем текущего модуля? Я думаю, что это означало бы превращение макроса в негигиеничный, так как невозможно решить, где какой-то идентификатор (например, fetch) определяется на этапе расширения макроса, и это нормально для меня.

1 ответ

Поскольку это довольно глубокий вопрос, я думаю, что вы должны дать самим разработчикам Julia возможность ответить на него, спросив пользователей julia.

В настоящее время вы можете полностью обойти макро гигиену, обернув quote блок в вашем макросе в esc(...) (не забудьте забрать esc вокруг a), но я бы вообще советовал против этого - тогда ты сам по себе.

Другие вопросы по тегам