Alias two macros

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
1 Like

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.

2 Likes

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.

1 Like

This worked. Thank you very much! :grinning: