# Macro only works outside of a function

**URL:** <https://discourse.julialang.org/t/macro-only-works-outside-of-a-function/14631>\
**Category:** New to Julia\
**Tags:** macros\
**Created:** [September 6, 2018, 5:23pm UTC](https://discourse.julialang.org/t/macro-only-works-outside-of-a-function/14631 "2018-09-06T17:23:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![OvidiusCicero](https://avatars.discourse-cdn.com/v4/letter/o/73ab20/32.png) [@OvidiusCicero](https://discourse.julialang.org/u/OvidiusCicero)\
**Post date:** [September 6, 2018, 5:23pm UTC](https://discourse.julialang.org/t/macro-only-works-outside-of-a-function/14631/1 "2018-09-06T17:23:38Z")

</div>

I have this example code and I do not get why it does not work in function `test`

```
macro dump(arg)
    return :(println("dump", $arg))
end

a = 1
@dump a

function test()
    b = 2
    @dump b
end

test()

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [September 6, 2018, 5:43pm UTC](https://discourse.julialang.org/t/macro-only-works-outside-of-a-function/14631/2 "2018-09-06T17:43:02Z")

</div>

This is macro hygiene at work. Macros need to be careful about what the names they use actually reference. For example, within `function test`, you could also have a variable named `println = 3`. If the macro tried to literally splice in the expression `println("dump", b)`, then it’d try to use `3` as the function and try to call it. So instead it uses “hygiene” to ensure that the `println` the macro inserted actually referenced the thing the macro wanted it to.

The way macros opt-out of this hygeine is with the `esc` function. In this case, you want the `arg` to be evaluated in the namespace of the caller, so you remove the hygiene for it:

```julia
macro dump(arg)
    return :(println("dump", $(esc(arg))))
end

```

This will now work as you expected within functions and in other modules. Hopefully you can also now see why your initial version worked at global scope — both the macro and the caller are in the same namespace!

---

<div class="post-metadata">

**Author:** ![OvidiusCicero](https://avatars.discourse-cdn.com/v4/letter/o/73ab20/32.png) [@OvidiusCicero](https://discourse.julialang.org/u/OvidiusCicero)\
**Post date:** [September 6, 2018, 6:14pm UTC](https://discourse.julialang.org/t/macro-only-works-outside-of-a-function/14631/3 "2018-09-06T18:14:34Z")

</div>

Thank you very much!
