How to correctly refer arguments of macro in nested quote?

question
#1

Suppose I just want to do something like f(x, ind) = x[ind] = 5.0, I could write a similar macro like this:

julia> macro foo1(data, index)
           esc(quote
               $data[$index] = 5.0
           end)
       end
@foo1 (macro with 1 method)

julia> d1 = zeros(10);

julia> @foo1(d1, 3)
5.0

julia> d1[3] == 5
true

However, if I want some intermediate variable involved in it, like:

function foo2(data, index)
    newindex = index * 2 # or other types of manipulation
    data[newindex] = 5.0
end

I try to write the following:

julia> macro foo2(data, index)
           newindex = gensym(:newindex)
           esc(quote
               $(newindex) = $(index) * 2
               quote
                   $$(data)[$$(newindex)] = 5.0
               end
           end)
       end
@foo2 (macro with 1 method)

julia> d2 = zeros(10);

julia> @macroexpand @foo2(d2, 3)
quote
    #= REPL[16]:4 =#
    ##newindex#365 = 3 * 2
    #= REPL[16]:5 =#
    (Core._expr)(:block, $(QuoteNode(:(#= REPL[16]:6 =#))), (Core._expr)(:(=), (Core._expr)(:ref, d2, ##newindex#365), 5.0))
end

Notice that the final expr has d2 in it instead of :d2, which the later is what I want. This isn’t setting the d2 actually. How can I achieve this? I checked this post but it doesn’t deal with this situation.

Thanks!

#2

I just solve this by following:

julia> macro foo4(data, index)
           quote
               newindex = $index * 2
               $(data)[newindex] = 5.0
           end
       end
@foo4 (macro with 1 method)

julia> d3 = zeros(10);

julia> @foo4(d3, 3)
5.0

julia> d3[6] == 5.0
true

where I got a great help from this tutorial.

#3

I may be missing something, but you don’t need a macro for this.

#4

I was trying to implement a callback function to incrementally write the output to a hdf5 file in DifferentialEquations.jl, hence I need a macro to generate that function (binded with some static variable by using let). So this is one of the ingredients where it came from.

#5

I still don’t see why you need a macro, instead of a callable struct or closure.

#6

You are right, I seem to make the problem more complicated. Nevertheless, this “detour” actually makes me learn something else.