Talking to the compiler (the :meta
mechanism)
В некоторых случаях может возникнуть желание предоставить подсказки или инструкции о том, что данный блок кода имеет специальные свойства: вы можете всегда хотеть встроить его, или вы можете захотеть включить специальные оптимизации компилятора. Начиная с версии 0.4, Julia имеет соглашение, что эти инструкции могут быть помещены внутри выражения :meta
, которое обычно (но не обязательно) является первым выражением в теле функции.
:meta
выражения создаются с помощью макросов. В качестве примера рассмотрим реализацию макроса @inline
:
macro inline(ex)
esc(isa(ex, Expr) ? pushmeta!(ex, :inline) : ex)
end
Здесь ex
ожидается как выражение, определяющее функцию. Утверждение, подобное этому:
@inline function myfunction(x)
x*(x+3)
end
превращается в выражение, подобное этому:
quote
function myfunction(x)
Expr(:meta, :inline)
x*(x+3)
end
end
Base.pushmeta!(ex, tag::Union{Symbol,Expr})
добавляет :tag
в конец выражения :meta
, создавая новое выражение :meta
, если это необходимо.
Чтобы использовать метаданные, вам нужно разобрать эти :meta
выражения. Если ваша реализация может быть выполнена в Julia, Base.popmeta!
очень полезен: Base.popmeta!(body, :symbol)
просканирует выражение body функции (без сигнатуры функции) на наличие первого :meta
выражения, содержащего :symbol
, извлечет любые аргументы и вернет кортеж (found::Bool, args::Array{Any})
. Если в метаданных не было аргументов или :symbol
не был найден, массив args
будет пустым.
Пока не предоставлена удобная инфраструктура для разбора :meta
выражений из C++.