Glad to be of help :)
On Wednesday, 31 December 2014 10:15:14 UTC+1, Tomas Lycken wrote:
>
> 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
>>>
>>>
>>