# Call a macro within a macro

**URL:** <https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708>\
**Category:** General Usage\
**Created:** [May 14, 2017, 5:04pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708 "2017-05-14T17:04:47Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![matthieu](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@matthieu](https://discourse.julialang.org/u/matthieu)\
**Post date:** [May 14, 2017, 5:04pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/1 "2017-05-14T17:04:47Z")

</div>

I am trying to define a macro that calls another macro.

To take an example, suppose a package defines a macro `@formula` as follows:

```julia
type Formula
    lhs::Union{Symbol, Expr, Void}
    rhs::Union{Symbol, Expr, Integer}
end
macro formula(ex)
    if (ex.head === :call && ex.args[1] === :(~))
        lhs = Base.Meta.quot(ex.args[2])
        rhs = Base.Meta.quot(ex.args[3])
       return Expr(:call, :Formula, lhs, rhs)
    else
        error("expected ~, got $(ex.args[1])")
    end
end
@formula(y~x)
#> Formula(:y, :x)

```

My goal is to define a macro `@formula2` that simply calls `@formula`

```julia
macro formula2(expr)
   Expr(:macrocall, Symbol("@formula"), expr)
end
@formula2(y~x)
#> ERROR: expected ~, got $(Expr(:globalref, Main, :~))

```

This simple definition does not work: `@formula2(y~x)` does not give the same output as `@formula(y~x)`. How could I define `@formula2` to obtain exactly the same output as `@formula`?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 14, 2017, 5:22pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/2 "2017-05-14T17:22:37Z")

</div>

Perhaps:

```julia
macro formula2(expr)
    :(@formula($(esc(expr))))
end

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [May 14, 2017, 5:22pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/3 "2017-05-14T17:22:47Z")

</div>

```julia
macro formula2(expr)
    :(@formula $(esc(expr)))
end

```

---

<div class="post-metadata">

**Author:** ![matthieu](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@matthieu](https://discourse.julialang.org/u/matthieu)\
**Post date:** [May 14, 2017, 5:24pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/4 "2017-05-14T17:24:32Z")

</div>

Thanks yuyichao! Could you explain a little bit what is happening? Is there some documentation about it?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [May 14, 2017, 5:32pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/5 "2017-05-14T17:32:43Z")

</div>

All user input must be `esc`aped once and exactly once.  
[https://docs.julialang.org/en/latest/manual/metaprogramming.html#Hygiene-1](https://docs.julialang.org/en/latest/manual/metaprogramming.html#Hygiene-1)

---

<div class="post-metadata">

**Author:** ![findmyway](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/findmyway/32/4946_2.png) [@findmyway](https://discourse.julialang.org/u/findmyway)\
**Post date:** [June 23, 2018, 8:23am UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/6 "2018-06-23T08:23:24Z")

</div>

Hi @yuyichao , @kristoffer.carlsson

I just encounter a similar problem.

To make it simple:

I have a inner macro:

```julia
macro m1(ex) :(println($ex + 1)) end

```

and an outer macro:

```julia
macro m2(ex) :(@m1 $(esc(ex))) end

```

But

```julia
julia> for i in 1:3
       @m2 i
       end
ERROR: UndefVarError: i not defined
Stacktrace:
 [1] macro expansion at ./REPL[10]:2 [inlined]
 [2] top-level scope at ./<missing>:0

```

How can the inner macro access `i`?

Thanks.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 23, 2018, 11:46am UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/7 "2018-06-23T11:46:12Z")

</div>

Use `esc` in the first macro, too, eg

```julia
macro m1(ex)
    :(println($(esc(ex)) + 1))
end

macro m2(ex)
    :(@m1 $(esc(ex)))
end

```

---

<div class="post-metadata">

**Author:** ![findmyway](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/findmyway/32/4946_2.png) [@findmyway](https://discourse.julialang.org/u/findmyway)\
**Post date:** [June 23, 2018, 12:17pm UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/8 "2018-06-23T12:17:10Z")

</div>

Wow…

Thanks!

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [March 17, 2020, 5:06am UTC](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708/9 "2020-03-17T05:06:46Z")

</div>

With my usual apology to resurrecting a dormant thread, this thread came up high in a google search and I wanted to link it to the more relevant thread:

> [@Calling a macro from within a macro, revisited](https://discourse.julialang.org/t/calling-a-macro-from-within-a-macro-revisited/19680):
>
> Hi all, I have a question: am i seeing a bug in the macro expander, or am I misunderstanding its usage? I’m implementing a macro which delegates (most of) its work to another macro, and I’m running into some issues around escaping. Here is a minimal version which I think should work, based on the discussion in this [related issue](https://discourse.julialang.org/t/call-a-macro-within-a-macro/3708), but isn’t: module Retest using Test macro retestset1(args...) :(@testset($((esc(a) for a in args)...))) # should work? end macro retestset2(args...) esc…

In short, I wanted to call `@show` within a macro, and the seemingly correct macro requires an `esc` around the whole returned expression:

```julia
macro sourceshow(expr)
    si = Base.CoreLogging.@_sourceinfo
    fileline = "$(si[2]):$(si[3])"
    esc(:(begin
        println($fileline)
        @show($expr)
    end
    ))
end

function f()
    y = 4
    @sourceshow y
end

@show macroexpand(Main, :(@sourceshow y))

f()

```

```julia
macro sourceshow(expr)
    si = Base.CoreLogging.@_sourceinfo
    fileline = "$(si[2]):$(si[3])"
    esc(:(begin
        println($fileline)
        @show($expr)
    end
    ))
end

function f()
    y = 4
    @sourceshow y
end

@show macroexpand(Main, :(@sourceshow y))

f()

```

I don’t see any hygiene issues with `@sourceshow`
