[julia-users] Re: Macro scoping (or hygiene?) problems
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 >>> >>> >>
[julia-users] Re: Macro scoping (or hygiene?) problems
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 >> >> >
[julia-users] Re: Macro scoping (or hygiene?) problems
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 > >