I would like to define a macro such that @mymacro expression
is the same as @tturbo @. expression
. Is there any way to do this? I have read the documentation and made several attempts, but I am completely new to macros and I cannot figure it out.
I have personally never done this, but looking at code from Trixi.jl (Trixi.jl/src/auxiliary/auxiliary.jl at dd051566a9079e22dfa792b145c0b50eaafa37fd · trixi-framework/Trixi.jl · GitHub), they defined their own @threaded
macro using Polyester.@batch
as follows:
macro threaded(expr)
#=.... comments .... =#
return esc(quote
Trixi.@batch $(expr)
end)
end
Composing macros — creating macros that call macros — is surprisingly (and unfortunately) challenging. AFAIK there’s not a general solution because you need to know each macro’s particular escaping and interpolating and syntax rules. There’s definitely ways to do this — hopefully someone here can help you with this particular use case — but it is generally not obvious.
Yes, macros can interact in unexpected way when each of them transforms the expression in some way (see here for an example).
Yet, when inserting another macro into its expansion, the outer macro has control over the syntax and just needs to ensure that its valid for the inner one, i.e., that the generated code makes sense and works as expected. In this case, it should be rather straight-forward as the expression is just passed as is:
macro ha(expr)
esc(:(LoopVectorization.@tturbo Base.@. $expr))
end
The only difficulty seems to be that macro names in the expansion are not automatically namespaced like function names, i.e., hygienic. Hence, the need to do this by hand and escaping the expression.
This macro escapes everything. If a user has imported his own package which is accidentally also named LoopVectorization
and contains a macro @tturbo
, then the user-defined @tturbo
will be called by the outer macro, even if the outer macro ha
is defined in a module in which the original (registered package) LoopVectorization
is imported.
Right, and I had warned about escaping everything myself in another thread.
Somehow, I got the impression that macro calls are resolved differently than function calls in quoted expressions. The following seems to work as expected though:
macro ha(expr)
:(@tturbo @. $expr)
end
assuming that @tturbo
has been imported into the module defining the macro.
This worked. Thank you very much!