That was it! This is a great community, many thanks for your time all!
Cheers. Kaj On Wednesday, March 11, 2015 at 8:56:26 PM UTC+2, Stefan Karpinski wrote: > > The way to do this is by wrapping an @eval around the macro invocation and > splicing $n: > > @eval @gentype $n UInt8 > > > This might be necessary, e.g. if you're looping over various values of n: > > for n = 1:10 > @eval @gentype $n UInt8 > end > > > > > On Wed, Mar 11, 2015 at 2:52 PM, Kaj Wiik <kaj....@gmail.com <javascript:> > > wrote: > >> >> Of course this was a simplified example to show the problem. A bad one, I >> admit. >> >> My question relates to the problem you (Simon) provided one answer >> already. I certainly have read Metaprogramming chapter and tried everything >> I could think of without luck. However, it could well be that I am just too >> thick... >> >> Returning to the real problem: >> >> julia> macro gentype(N, typename) >> fields = [:($(symbol("I_$i"))::T) for i=1:N] >> quote >> immutable $(typename){T} >> $(fields...) >> end >> end >> end >> >> julia> n = 3 >> julia> @gentype n Uint8 >> ERROR: `colon` has no method matching colon(::Int64, ::Symbol) >> >> julia> macroexpand(:(@gentype n Uint8)) >> :($(Expr(:error, MethodError(colon,(1,:n))))) >> >> >> So, the problem seems to be that variable argument is treated as a symbol >> and is not interpolated in parse time, that lead me to try eval(), which is >> a no-no. >> >> If I replace N -> $N, i get "ERROR: error compiling anonymous: syntax: >> prefix $ in non-quoted expression" >> >> Any suggestions are appreciated, there must be a way.... >> >> Thanks, >> Kaj >> >> On Wednesday, March 11, 2015 at 3:40:38 PM UTC+2, Simon Danisch wrote: >>> >>> This is most likely not the right place to use eval! >>> You need to define your problem better. What you describe here doesn't >>> need a macro whatsoever. >>> Macros are for manipulating the syntax tree, which is why the arguments >>> are not the values, but expressions. >>> What a macro is intended to do is more something like this: >>> >>> macro testmacro(N) >>> quote >>> for i = 1:$N >>> println("Hello!") >>> end >>> end >>> end >>> n = 10 >>> >>> @testmacro n >>> >>> So all the code inside a macro should be used to transform an >>> expression, which than replaces the original expression that you gave the >>> macro via its arguments >>> >>> Am Mittwoch, 11. März 2015 13:37:55 UTC+1 schrieb Kaj Wiik: >>>> >>>> I have a problem in using variables as argument for macros. Consider a >>>> simple macro: >>>> >>>> macro testmacro(N) >>>> for i = 1:N >>>> println("Hello!") >>>> end >>>> end >>>> >>>> @testmacro 2 >>>> >>>> Hello! >>>> Hello! >>>> >>>> >>>> So, all is good. But if I use a variable as an argument, >>>> >>>> n = 2 >>>> @testmacro n >>>> >>>> >>>> I get an (understandable) error message "ERROR: `colon` has no method >>>> matching colon(::Int64, ::Symbol)". >>>> >>>> Is this the correct place to use eval() in macros, like >>>> >>>> macro testmacro(N) >>>> for i = 1:eval(N) >>>> println("Hello!") >>>> end >>>> end >>>> >>>> This seems to work as expected. I tried multitude of combinations of >>>> dollar signs, esc, quotes and brackets, none of them worked :-), got >>>> "ERROR: error compiling anonymous: syntax: prefix $ in non-quoted >>>> expression"... >>>> >>>> Are there better ways to do this, is it OK to use eval() in this >>>> context? >>>> >>>> Thanks, >>>> Kaj >>>> >>>> >