# Confused about metaprogramming: macros

**URL:** <https://discourse.julialang.org/t/confused-about-metaprogramming-macros/50480>\
**Category:** New to Julia\
**Created:** [November 20, 2020, 7:39am UTC](https://discourse.julialang.org/t/confused-about-metaprogramming-macros/50480 "2020-11-20T07:39:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hsvdg](https://avatars.discourse-cdn.com/v4/letter/h/a6a055/32.png) [@hsvdg](https://discourse.julialang.org/u/hsvdg)\
**Post date:** [November 20, 2020, 7:39am UTC](https://discourse.julialang.org/t/confused-about-metaprogramming-macros/50480/1 "2020-11-20T07:39:34Z")

</div>

I have started to use Metaprogramming now. While my code is running, I noticed that there are some things that I do not understand. My understanding is that at the simplest level macros return an expression which is then evaluated. So, I tried to define a variable b and set its value to one using a macro:

macro test(x)  
quote  
b=1  
end  
end

When I then run in REPL:

b

Then I get an error message:

ERROR: UndefVarError: b not defined

The macro seems to return 1.

On the other hand if I type,

eval(Meta.parse(“b=1”))

Then b is defined in the REPL.

I would have expected the macro and the eval call to have the same effect. Apparently, there is something I am not understanding here…

Thanks!

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [November 20, 2020, 7:46am UTC](https://discourse.julialang.org/t/confused-about-metaprogramming-macros/50480/2 "2020-11-20T07:46:54Z")

</div>

Variables defined through macro get mangled so that they don’t accidentally overwrite other variables in the same context. You may use escaping with `esc(b)` within macro if you want to expose the name(s).

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [November 20, 2020, 7:50am UTC](https://discourse.julialang.org/t/confused-about-metaprogramming-macros/50480/3 "2020-11-20T07:50:05Z")

</div>

You can use `esc` to avoid the hygiene pass for certain variables or the entire expression.

```julia
julia> macro test()
           quote
               $(esc(:b))=1; nothing
           end
       end
@test (macro with 1 method)

julia> b
ERROR: UndefVarError: b not defined

julia> @test

julia> b
1

```

When working with macros, `@macroexpand` is your friend:

```julia
julia> @macroexpand @test
quote
    #= REPL[1]:3 =#
    b = 1
    #= REPL[1]:3 =#
    Main.nothing
end

julia> macro test2()
           quote
               b=1; nothing
           end
       end
@test2 (macro with 1 method)

julia> @macroexpand @test2
quote
    #= REPL[6]:3 =#
    var"#17#b" = 1
    #= REPL[6]:3 =#
    Main.nothing
end

```

Notice the mangled name of `b` in `@test2`.

Note that the number in the `gensym`ed variable increases each time. Seeing 17 above, we can infer that it’ll be 18 next time:

```julia
julia> @test2

julia> var"#18#b"
1

```

---

<div class="post-metadata">

**Author:** ![hsvdg](https://avatars.discourse-cdn.com/v4/letter/h/a6a055/32.png) [@hsvdg](https://discourse.julialang.org/u/hsvdg)\
**Post date:** [November 20, 2020, 7:59am UTC](https://discourse.julialang.org/t/confused-about-metaprogramming-macros/50480/4 "2020-11-20T07:59:18Z")

</div>

Oh, thank you!

I actually had suspected this before and tried the esc… but not the correct way, which is why it did not work!

I start to understand this now!
