# Call macro inside a macro with external variables escaped

**URL:** <https://discourse.julialang.org/t/call-macro-inside-a-macro-with-external-variables-escaped/85650>\
**Category:** General Usage\
**Tags:** macros\
**Created:** [August 12, 2022, 4:01am UTC](https://discourse.julialang.org/t/call-macro-inside-a-macro-with-external-variables-escaped/85650 "2022-08-12T04:01:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [August 12, 2022, 4:01am UTC](https://discourse.julialang.org/t/call-macro-inside-a-macro-with-external-variables-escaped/85650/1 "2022-08-12T04:01:23Z")

</div>

I have a problem making the following example work, it tells me `@option` & `VectorOption` are not defined:

```julia
module MWE

using Configurations: @option

export @vopt, vopt

abstract type VectorOption end

macro vopt(type, alias)
    return esc(vopt(type, alias))
end

function vopt(type, alias)
    return quote
        @option $alias struct $type <: VectorOption
            values::Vector{Float64}
        end
    end
end

end

```

```julia
julia> Main.MWE.@vopt Pr "pr"
ERROR: UndefVarError: @option not defined

julia> Main.MWE.@vopt Pr "pr"
ERROR: UndefVarError: VectorOption not defined
Stacktrace:
 [1] macro expansion
   @ ~/.julia/packages/ExproniconLite/5zV9Q/src/codegen.jl:101 [inlined]
 [2] macro expansion
   @ ~/.julia/packages/Configurations/1TQp9/src/codegen.jl:121 [inlined]
 [3] top-level scope
   @ REPL[1]:15

```

I have tried several different ways of rewriting `vopt` and `@vopt`, but none of them work.

* * *

To run this example, you may need to install [Configurations.jl](https://github.com/Roger-luo/Configurations.jl).

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [August 12, 2022, 4:22am UTC](https://discourse.julialang.org/t/call-macro-inside-a-macro-with-external-variables-escaped/85650/2 "2022-08-12T04:22:34Z")

</div>

Since you’re `esc`aping the whole thing, `@option` and `VectorOption` get evaluated as `Main.@option` and `Main.VectorOption` respectively. Writing them explicitly as being from `MWE` i.e.

```
 MWE.@option $alias struct $type <: MWE.VectorOption

```

works for this minimal example, would that work for your real use case too? (For `MWE.VectorOption` you can also write `$VectorOption` instead, but I don’t know how to interpolate a macro invocation like `@option` with a `$`.)

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [August 12, 2022, 4:32am UTC](https://discourse.julialang.org/t/call-macro-inside-a-macro-with-external-variables-escaped/85650/3 "2022-08-12T04:32:19Z")

</div>

Thank you @digital_carver, adding `MWE` to both of them works. However, since `@option` is defined in `Configurations.jl` and `VectorOption` is already defined in `MWE`, it feels strange to invoke them as `MWE.@option` and `MWE.VectorOption` to me.

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [August 12, 2022, 9:43am UTC](https://discourse.julialang.org/t/call-macro-inside-a-macro-with-external-variables-escaped/85650/4 "2022-08-12T09:43:33Z")

</div>

If you want to avoid spelling the module name, you _can_ interpolate non-macro objects into the expressions directly, like so:

```julia
quote
    @option $alias struct $type <: $VectorOption
        values::Vector{Float64}
    end
end

```

The `$VectorOption` becomes `Main.MWE.VectorOption`.

Macros are more annoying to specify dynamically, because they have special syntax. If you really _really_ want to avoid writing

```julia
quote
    MWE.@option $alias struct $type <: $VectorOption
        values::Vector{Float64}
    end
end

```

like you should, you could do

```julia
quote
    $( __MODULE__ ).@option $alias struct $type <: $VectorOption
        values::Vector{Float64}
    end
end

```
