# [Probably] A Naive Macro Interpolation Doubt

Hellos,

All that I want to do is a basic a macro to access some arrays. Here is the working code with expressions:

``````# works
let
N = 5
a = zeros(N)
b = collect(1:N)
myexp = quote
for i = 1:\$N
\$a[i] = 2*\$b[i]
end
end
eval(myexp)
a
end
``````

Here my attempt to make a macro

``````# i wish it could work
macro myLoop(a, b, N)
quote
a, b, N = esc.((a,b,N))
for i = 1:\$N
\$a[i] = 2*\$b[i]
end
end
end
function mytest()
N = 7
a = zeros(N)
b = collect(1:N)
@myLoop a b N
a
end
mytest()
``````

I got an error that N does not exist:

``````ERROR: UndefVarError: N not defined
Stacktrace:
 mytest()
@ Main ./Untitled-1:19
 top-level scope
@ Untitled-1:31
``````

I’m sure I’m doing a very basic mistake, but I can’t figure out looking at examples on discourse.

Help please Here’s the problem–your macro is producing code which tries to call the `esc` function on some local variable named `N` which doesn’t exist. `esc` is just like any other function–it doesn’t know that you actually want to interpolate the value of `N` (that’s what the `\$` syntax is for).

Here’s one version that works:

``````julia> macro myLoop(a, b, N)
quote
for i = 1:\$(esc(N))
\$(esc(a))[i] = 2*\$(esc(b))[i]
end
end
end
``````

or, if you prefer:

``````julia> macro myLoop(a, b, N)
quote
a, b, N = (\$(esc(a)), \$(esc(b)), \$(esc(N)))
for i = 1:N
a[i] = 2*b[i]
end
end
end

``````
1 Like

A simpler change is to lift the `esc` calls out of the `quote`

``````macro myLoop(a, b, N)
a, b, N = esc.((a,b,N))
quote
for i = 1:\$N
\$a[i] = 2*\$b[i]
end
end
end
``````
2 Likes