No problem – glad we got to the bottom of it!

On Wed, Mar 11, 2015 at 4:39 PM, Kaj Wiik <[email protected]> wrote:

> 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 <[email protected]> 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
>>>>>
>>>>>
>>

Reply via email to