Странная гигиена в макросах
Предположим, у меня есть это макроопределение в модуле:
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
), но я бы вообще советовал против этого - тогда ты сам по себе.