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
>> ​
>>
>

Reply via email to