Splatting symbols from tuple into expression

metaprogramming

#1

I’m trying to construct a macro that outputs a for-loop like this one

for (i,val) in [(i,2i) for i = 1:4]
    println(i, " ", val)
end

but where the tuple (i,val) is available inside the macro as a tuple of symbols that may vary in length, like below. How do one splice this tuple into the expression in the correct way? I have tried the two variants below without success.

macro foo(ex)
    a = (:i, :val) # In real use case this is created from ex
    quote
        for $(a) in enumerate(randn(2))
            println(i,val)
        end
    end
end

macro foo(ex)
    a = (:i, :val)
    quote
        for $(ntuple(i->(a[i]), length(a))) in enumerate(randn(2))
            println(i,val)
        end
    end
end

@foo 1+1

syntax: invalid assignment location "(:i, :val)"
include_string(::String, ::String) at loading.jl:522
include_string(::String, ::String, ::Int64) at eval.jl:30
include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N} where N) at eval.jl:34
(::Atom.##102#107{String,Int64,String})() at eval.jl:82
withpath(::Atom.##102#107{String,Int64,String}, ::String) at utils.jl:30
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##101#106{String,Int64,String}) at repl.jl:67
macro expansion at eval.jl:80 [inlined]
(::Atom.##100#105{Dict{String,Any}})() at task.jl:80


#2

It seems

macro foo(ex)
    a = (:i, :val)
    quote
        for $(Expr(:tuple, a...)) in enumerate(randn(2))
            println(i,val)
        end
    end
end

is kind of working, possibly missing some esc to work as intended in all cases.