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