# Macro for generating @NLconstraint

**URL:** <https://discourse.julialang.org/t/macro-for-generating-nlconstraint/16535>\
**Category:** Optimization (Mathematical)\
**Created:** [October 19, 2018, 3:54pm UTC](https://discourse.julialang.org/t/macro-for-generating-nlconstraint/16535 "2018-10-19T15:54:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![chkwon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkwon/32/3632_2.png) [@chkwon](https://discourse.julialang.org/u/chkwon)\
**Post date:** [October 19, 2018, 3:54pm UTC](https://discourse.julialang.org/t/macro-for-generating-nlconstraint/16535/1 "2018-10-19T15:54:33Z")

</div>

On julia v0.7 and JuMP v0.18:

```julia
using JuMP
macro zero_constraint(m, expr)
    quote
        @NLconstraint($(esc(m)), $(esc(expr)) == 0)
    end
end

m = Model()
@variable(m, x)
@variable(m, y)
@zero_constraint(m, x) #1
@zero_constraint(m, x-y) #2
@zero_constraint(m, x^3-y) #3
print(m)

```

While #1 works, #2 generates:

```julia
ERROR: Unexpected object x - y in nonlinear expression.

```

and #3 generates:

```julia
ERROR: Only exponents of 0, 1, or 2 are currently supported. Are you trying to build a nonlinear problem? Make sure you use @NLconstraint/@NLobjective.

```

It seems that I don’t understand how macro works correctly. Could you help me to figure out what’s happening and how I should modify the `@zero_constraint` macro? Thanks for your help.

---

<div class="post-metadata">

**Author:** ![chkwon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkwon/32/3632_2.png) [@chkwon](https://discourse.julialang.org/u/chkwon)\
**Post date:** [October 19, 2018, 4:45pm UTC](https://discourse.julialang.org/t/macro-for-generating-nlconstraint/16535/2 "2018-10-19T16:45:50Z")

</div>

This reflects my situation better.

```julia
module MyModule
    import JuMP.@NLconstraint
    export @zero_constraint
    macro zero_constraint(m, expr)
        ex = quote
            @NLconstraint($(esc(m)), $(esc(expr)) == 0)
        end
    end
end
using JuMP, Main.MyModule
model = Model()
@variable(model, x)
@variable(model, y)
@zero_constraint(model, x)
@zero_constraint(model, x-y)
@zero_constraint(model, x^3-y)
print(model)

```

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [October 19, 2018, 5:02pm UTC](https://discourse.julialang.org/t/macro-for-generating-nlconstraint/16535/3 "2018-10-19T17:02:54Z")

</div>

Those error messages are what you would see if you wrote, e.g.,

```julia
model = Model()
@variable(model, x)
@variable(model, y)
expr = x^3 - y
@NLconstraint(model, expr == 0)

```

So looks like the macro isn’t generating the right code.

---

<div class="post-metadata">

**Author:** ![chkwon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkwon/32/3632_2.png) [@chkwon](https://discourse.julialang.org/u/chkwon)\
**Post date:** [October 20, 2018, 10:27pm UTC](https://discourse.julialang.org/t/macro-for-generating-nlconstraint/16535/4 "2018-10-20T22:27:55Z")

</div>

Thanks @miles.lubin. It helped me to figure out what was going on. I had some tests:

```julia
module MyModule
    import JuMP.@NLconstraint
    export @add_constraints

    macro add_constraints(m)
        ex = quote
            # works in julia v0.7+ / JuMP v0.18--0.19
            @NLconstraint($(esc(m)), $(esc(:x))^2 == 0)

            # works in julia v0.6 / JuMP v0.18; but not in julia v0.7+
            # @NLconstraint($(esc(m)), $(esc(:(x^2 == 0))))

            # below does not work
            # @NLconstraint($(esc(m)), $(esc(:(x^2))) == 0)
        end
    end
end

using JuMP, Main.MyModule
model = Model()
@variable(model, x)
@add_constraints(model)
print(model)

```

It seems that how parser works has been changed between julia v0.6 and 0.7+. Unlike in julia v0.6, `esc()` should be applied to each JuMP variable only, not to the entire expression, in v0.7+. Is there a julia or JuMP function that does this job? I ended up writing [such a function](https://github.com/chkwon/Complementarity.jl/blob/master/src/mpec.jl#L6-L37), but was wondering any other (and better) option.
