How to produce the code "f(a...,b...)"


#1

I’m trying to generate the code f(a...,b...) from inside a macro. The following doesn’t seem to work because it adds an extra tuple around a... and b...,

julia> quote
           f($((:($i...) for i=[:a,:b])...))
       end
quote  
    f((a...,), (b...,))
end

Instead, I have to use an explicit Expr call,

julia> quote
           f($((Expr(:(...),i) for i=[:a,:b])...))
       end
quote 
    f(a..., b...)
end

Could any macro-guru’s help me out with a way to write this without resorting to using Expr (which I don’t like simply because I find it makes the code a bit harder to parse)? Thanks!


#2

Just write a helper function that accepts as argument :a and returns the nasty code you don’t want to think about again.


#3

Not sure I understand, sorry, can you elaborate? In any case, I was hoping no extra function was necessary, and it might just be a matter of getting the $'s and :'s in the right places in that first example, but maybe not…


#4

Are you sure you don’t have a stray comma somewhere? I can’t test this currently but I am surprised that the first block of code gives a tuple.


#5

The parentheses aren’t actually part of the colon syntax. They’re required because : is earlier in the order of operations than … . Because they are “real” parentheses, they make a tuple, just like (a…) does. So the answer is no.


#6

Ah thanks yea that explanation totally helps get it right in my head what’s going on.

I suppose it would be nice if the first (if any) pairs of parenthesis after a “:” could not be interpreted as a tuple, to allow you do :($i...) without making a tuple, but still give you the flexibility to make a tuple with :(($i...)) if desired. Although I can easily imagine this having some unintended consequence I haven’t thought of…