Инструктирование компилятора (механизм :meta)
Иногда может быть необходимо дать указание, что данный блок кода обладает особыми свойствами: вам может требоваться всегда встраивать его или включать специальные проходы оптимизации компилятора. Начиная с версии 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) сканирует выражение тела функции (без сигнатуры функции) на предмет первого выражения :meta, содержащего :symbol, извлечет все аргументы и возвратит кортеж (found::Bool, args::Array{Any}). Если метаданные не содержат аргументы или :symbol не был найден, массив args будет пустым.
Эффективная инфраструктура для разбора выражений :meta из C++ пока отсутствует.