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