How to pass an arbitrary number of macro arguments from one macro to another? (a bit like splatting)

I have a macro which does stuff depending on how many inputs there are

macro my_macro(arg1)
    println("We got one argument.")
    sum = 1
    if arg1 isa Int64
        sum = sum + arg1
    end
    sum
end
macro my_macro(arg1, arg2)
    println("We got two argument.")
    sum = 1
    if arg1 isa Int64
        sum = sum + arg1
    end
    if arg2 isa Int64
        sum = sum + arg2
    end
    sum
end
macro my_macro(arg1, arg2, arg3)
    println("We got three argument.")
    sum = 1
    if arg1 isa Int64
        sum = sum + arg1
    end
    if arg2 isa Int64
        sum = sum + arg2
    end
    if arg3 isa Int64
        sum = sum + arg3
    end
    sum
end

(just an example to demonstrate what problem I have)

I then have another macro, which basically is the first macro + some modification. If my macros were functions I could just have done:

macro my_macor_expanded(args...)
    sum = my_macor_expanded(args...)
    return sum + 1
end

Now we are dealing with macros, so that do not work. However, I am not sure how to. E.g.

macro my_macro_expanded(args...)
    sum = :(@my_macro $args... )
    return sum + 1
end
@my_macro_expanded 1 2

even if I have two arguments, the internal @my_macro only gets a single one.

I believe you just need another set of parenthesis:

macro my_macro_expanded(args...)
    sum = :(@my_macro $(args... ))
    return sum + 1
end
1 Like

That worked, tons of thanks!

You can, in fact, call a macro with parenthesis, like a function. It does need the @ sign.

1 Like

You can also call a macro like this:

var"@my_macro"(__source__, __module__, args...)

For your example:

julia> macro my_macro_expanded(args...)
           sum = var"@my_macro"(__source__, __module__, args...)
           return sum + 1
       end
@my_macro_expanded (macro with 1 method)

julia> @my_macro_expanded 1 2
We got two argument.
5
1 Like

Thanks for the additional comments with more info, that is really useful to know!

Incidentally, there are some known pitfalls for passing arguments from one macro to another, if you “escape” an argument:

2 Likes

Thanks, for mentioning that.

I think i have actually run into this problem in my application. My macro requires me to escape at times, however, this feature fails, which is unfortunate.

Right now I am working around it by implementing my two macros twice (basically identically, but with a small change in the second set, which I initially mostly wanted to re-use the code from the first set).

1 Like