I’m doing some metaprogramming for Interpolations.jl, and I’m getting stuck 
at an error that I think is due to scoping issues in my nested quotes, and 
I’ve stared at this for so long now I’m not getting anywhere.

I can do the following

matching(d) = quote
    println("Matching: ", $d)
end

nonmatching(d) = quote
    println("Not matching: ", $d)
end

@ngenerate N T function example{T,N}(A::Array{T,N}, xs::NTuple{N,Real}...)
    @nexprs N dim->begin
        @nexprs N d->begin
            if d==dim
                eval(matching(d))
            else
                eval(nonmatching(d))
            end
        end
    end
end

example(rand(2,2), 1.5, 0.7)

and get the expected output:

Matching: 1
Not matching: 2
Not matching: 1
Matching: 2

Examining with macroexpand, I see that the eval calls are still there, but 
for performance reasons I want to avoid them, so I try to rewrite it to use 
eval(ngenerate(...)) instead of @ngenerate ...:

#matching and nonmatching defined as before

ex = ngenerate(
    :N,
    :T,
    :(example{T,N}(A::Array{T,N}, xs::NTuple{N,Real}...)),
    N->quote
        @nexprs $N dim->begin
            @nexprs $N d->begin
                if d==dim
                    $(matching(d))
                else
                    $(notmatching(d))
                end
            end
        end
    end
)

eval(ex)

example(rand(2,2), 1.5, 0.7)

But this doesn’t work: I get ERROR: d not defined on $(matching(d)) (and, 
if I comment that one out, $(nonmatching(d))). I’ve tried $(matching($d)) 
(ERROR: 
error compiling anonymous: syntax: prefix $ in non-quoted expression) as 
well as $(matching(esc(d))) and $(esc(matching(d))) (both ERROR: d not 
defined), and I’m at a loss for what to try (these errors are all thrown at 
the stage of *defining* the quoted expression, so macroexpand hasn’t helped 
me here either, as I don’t get any expression to call it on…).

Eventually, this will be used to do different things for different array 
dimensions like here, but with both matching and nonmatching also 
dispatching on types of some additional arguments that I left out for 
simplicity, and choosing expressions by means of multiple dispatch this way 
is really at the core of Interpolations.jl, so I can’t move the contents of 
matching and nonmatching out of their respective functions.

Thanks in advance for any ideas that get me forward,

// Tomas
​

Reply via email to