Actually, I do know `d` at compile time - I just hadn't grok-ed quoting and
interpolation well enough to understand how to convey that in code. As it
turns out, what I needed was to create a *symbol* for `d`, so that the
interpolation would get back its *value*: `$(matching(:d))` does the trick.
Thanks for kicking me in the right direction =)
// T
On Tuesday, December 30, 2014 10:09:01 PM UTC+1, Valentin Churavy wrote:
>
> So I do not totally understand the goal of what you are trying to achieve,
> but could you try to do this with a macro?
>
> macro value(d)
> @show d
> quote
> println("d at runtime ", $d)
> end
> end
>
> @ngenerate N T function example{T,N}(A::Array{T,N}, xs::NTuple{N,Real}...)
> @nexprs N dim->begin
> @nexprs N d->begin
> @value(d)
> end
> end
> end
>
> example(rand(2,2), 1.5, 0.7)
>
> So at least the value of d is know at the time when the macro value is run
> and you could then call expression generating code based on that value.
>
> dispatching on types of some additional arguments
>>
>
> That sounds like you should/could use staged functions for that.
>
> On Tuesday, 30 December 2014 17:59:37 UTC+1, Tomas Lycken wrote:
>>
>> 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
>>
>>
>