# Help with macros and calling a macro from a different module

**URL:** <https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715>\
**Category:** New to Julia\
**Created:** [June 19, 2020, 9:03am UTC](https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715 "2020-06-19T09:03:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [June 19, 2020, 9:03am UTC](https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715/1 "2020-06-19T09:03:45Z")

</div>

I’m very new to macros so any help is appreciated.  
Currently I want to extend JuMP and there inside a macro this line exists:

```julia
buildcall = :(_build_indicator_constraint($_error, $(esc(variable)), $rhs_buildcall, $S))

```

where `_build_indicator_constraint` exists in `JuMP` but if I change it to `_build_my_constraint` and write the function in my module it seems like that JuMP when actually calling `buildcall` does not know about the function because it is in my module.

Hope that makes sense. Is there any way around this problem?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 19, 2020, 11:49am UTC](https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715/3 "2020-06-19T11:49:00Z")

</div>

You can try to use `@macroexpand` to find out what the final representation of all these variables is in the generated expression. I’ve had problems with proper escaping before and this helped me to track down which variables needed module namespacing and which didn’t.

I think the rule is that any function used in a macro is namespaced to the module where the macro was defined. So if you write `do_this(x)` in a macro that’s defined in `MyModule` it’s as if you had written `MyModule.do_this` wherever you run this macro.

If you don’t want that, but want whatever `do_this` to be called that happens to be valid in the place where the macro is called, you need to escape `do_this`.

In your case, it might be that you want the opposite behavior? I’m not sure if I understand correctly what your precise issue is. There are two options:

Either the name that is not found is in your module but it was used escaped in the macro. Then unescape it.

Or the name that is not found is in the calling module but is being looked for in your module because it’s not escaped. Then escape it.

I hope that made sense, macros are tricky!

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [June 19, 2020, 12:43pm UTC](https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715/4 "2020-06-19T12:43:18Z")

</div>

Thanks for the answer. I’m not entirely sure how to do what you propose but using `@macroexpand` seems to help me.

Currently the last line of `@macroexpand` reads something like this:

```julia
 JuMP.add_constraint(m, JuMP._build_my_constraint(JuMP.var"#_error#68"{Symbol}(Core.Box(Any[:m, :($(Expr(:(:=), :a, :({x + y <= 1}))))]), :constraint), a, JuMP.build_constraint(JuMP.var"#_error#68"{Symbol}(Core.Box(Any[:m, :($(Expr(:(:=), :a, :({x + y <= 1}))))]), :constraint), JuMP._functionize(var"#220###418"), MathOptInterface.LessThan{Float64}(0.0)), ..., "")

```

So the problem is the `JuMP._build_my_constraint` it should be `_build_my_constraint` as far as I understand.

I’m struggling with using `esc` in a way that only the function name gets escaped and not the function arguments.

i.e I can produce:

```julia
JuMP.add_constraint(m, _build_my_constraint(JuMP.var"#_error#68"{Symbol}(Core.Box(Any[:m, :($(Expr(:(:=), :a, :({x + y <= 1}))))]), :constraint), $(Expr(:escape, :a)), build_constraint(JuMP.var"#_error#68"{Symbol}(Core.Box(Any[:m, :($(Expr(:(:=), :a, :({x + y <= 1}))))]), :constraint), _functionize(var"##510"), $(Expr(:escape, MathOptInterface.LessThan{Float64}(0.0)))), ..., "")

```

but there everything is escaped because I do escape everything 😆

```julia
esc(:(_build_my_constraint($_error, $(esc(variable)), $rhs_buildcall, $S)))

```

I need to unescape the arguments now? If so how to do that?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 19, 2020, 12:51pm UTC](https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715/5 "2020-06-19T12:51:23Z")

</div>

Does this explain it? Here is a function called in a macro, where only the function symbol is escaped (I left out all arguments for clarity):

```julia
macro test()
    quote
        $(esc(:dothis))()
    end
end

julia> @macroexpand @test()
quote
    dothis()
end

```

The resulting expression just calls `dothis` wherever it is used.

On the other hand, if we don’t escape the function symbol, it’s scoped to Main, where I defined the macro:

```julia
macro test2()
    quote
        $(:dothis)()
    end
end

julia> @macroexpand @test2()
quote
    Main.dothis()
end

```

The second version is a convoluted way of writing `dothis()` directly, but I hope it makes the contrast to the first version clearer.

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [June 19, 2020, 1:00pm UTC](https://discourse.julialang.org/t/help-with-macros-and-calling-a-macro-from-a-different-module/41715/6 "2020-06-19T13:00:37Z")

</div>

Thanks I think it works now. This is the version now:

```julia
buildcall = :($(esc(:(CS._build_my_constraint)))($_error, $(esc(variable)), $rhs_buildcall, $S))

```

So I also had to add `CS.` for my module because otherwise it’s probably looking in the current scope which is the global one where that is not defined.

I messed up my parenthesis before which caused errors but your solution works and makes sense. Thanks again!
