A macro's role is to take some expressions, symbols and literals and
produce a single expression that will be what is actually evaluated. This
expansion occurs when the macro is *parsed* not when the code runs.
Therefore, if you call eval on something inside of a macro body, you are
most likely evaluating it before it runs and at a point where the variables
you're evaluating don't even exist. If your macro is used at the top-level
global scope, these happen to be the same thing, but your macro is still
broken and it won't work inside of a function, for example since the eval
occurs when the function is defined, not when the function is called.


On Sat, Aug 30, 2014 at 5:27 PM, Don MacMillen <[email protected]>
wrote:

> There you have it... Zen was never my thing.  So I find the previous two
> comments cryptic.
> The macro _seemed_ to be doing what I wanted it to.  Is there some
> documentation that
> speaks to calling (or rather not calling) eval from inside a macro?
>
>
> On Saturday, August 30, 2014 2:15:54 PM UTC-7, John Myles White wrote:
>
>> This might need to be part of the Zen of Julia.
>>
>>  — John
>>
>> On Aug 30, 2014, at 2:11 PM, Jameson Nash <[email protected]> wrote:
>>
>> calling eval in a macro doesn't do what you think it does, so it doesn't
>> do what you want
>>
>>
>> On Sat, Aug 30, 2014 at 5:05 PM, Don MacMillen <[email protected]>
>> wrote:
>>
>>> Perfect Steve, many thanks for the explanation.  But just to be sure I
>>> understand,
>>> the multiple eval of input expression, your begin println("hello"); 3
>>> end  would only
>>> occur during macro expansion?
>>>
>>> Also, just to beat this poor dead horse into the ground, to get the
>>> behavior I wanted,
>>> get rid of the splice, get rid of the splat and pass a single vector
>>> parameter to the
>>> macro and then eval it there.  Now that's the behavior I wanted but
>>> performance is
>>> another issue.  How would I reason about the relative performance here?
>>>
>>> macro hornervec(x, c)
>>>     p = eval(c)
>>>     ex = esc(p[end])
>>>     for i = length(p)-1:-1:1
>>>         ex = :($(esc(p[i])) + t * $ex)
>>>     end
>>>     Expr(:block, :(t = $(esc(x))), ex)
>>> end
>>>
>>>
>>> On Saturday, August 30, 2014 12:42:11 AM UTC-7, Steven G. Johnson wrote:
>>>>
>>>> The answer is related to your splicing questions.  What gets passed to
>>>> the macro is not the value of the argument, but rather the symbolic
>>>> expression of the argument.  If I didn't use a temporary variable, that
>>>> symbolic expression would get inserted multiple times into the polynomial
>>>> evaluation.  This is not what you want because it means the expression
>>>> could be evaluated multiple times.
>>>>
>>>>>
>>>>> Try passing an expression with a side effect and you'll see what I
>>>>> mean:
>>>>>
>>>>> @horner(begin
>>>>>                    printf("hello")
>>>>>                    3
>>>>>                end, 4,5,6,7)
>>>>>
>>>>
>>>> Whoops, I mean println, not printf.  And I mean, try passing it to a
>>>> version of horner that does not use a temporary variable.
>>>>
>>>
>>
>>

Reply via email to