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

Reply via email to