# \`JuMP\` macros with \`RuntimeGeneratedFunctions\`

**URL:** https://discourse.julialang.org/t/jump-macros-with-runtimegeneratedfunctions/127815
**Category:** Optimization (Mathematical)
**Created:** [April 7, 2025, 7:47pm UTC](https://discourse.julialang.org/t/jump-macros-with-runtimegeneratedfunctions/127815 "2025-04-07T19:47:48Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![sstroemer](https://avatars.discourse-cdn.com/v4/letter/s/a88e4f/32.png) [@sstroemer](https://discourse.julialang.org/u/sstroemer)
#### Post date: [April 7, 2025, 7:47pm UTC](https://discourse.julialang.org/t/jump-macros-with-runtimegeneratedfunctions/127815/1 "2025-04-07T19:47:48Z")

</div>

The following MWE

```julia
import JuMP, RuntimeGeneratedFunctions

RuntimeGeneratedFunctions.init(@ __MODULE__ )

code = """
model = JuMP.owner_model(x[1])
JuMP.@constraint(model, [t = 1:10], x[t] >= 0)
"""

code_ex = Meta.parse("""begin\n$(code)\nend""")

rgf = RuntimeGeneratedFunctions.@RuntimeGeneratedFunction(
    :(function (x)
        $code_ex
    end)
)

rgf(JuMP.@variable(JuMP.Model(), [1:10]))

```

fails with

```console
ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.

```

whereas it works when manually creating each constraint using

```julia
code = """
for t = 1:10
    JuMP.@constraint(JuMP.owner_model(x[t]), x[t] >= 0)
end
"""

```

Am I misusing `RuntimeGeneratedFunctions`? Or is there something else I can do to work around this?

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [April 7, 2025, 10:36pm UTC](https://discourse.julialang.org/t/jump-macros-with-runtimegeneratedfunctions/127815/2 "2025-04-07T22:36:01Z")

</div>

The error seems pretty reasonable.

The expanded code from `@constraint` contains a bunch of stuff that `RuntimeGeneratedFunctions` might find troublesome:

```Julia
julia> using JuMP

julia> begin
           model = Model()
           @variable(model, x[1:10])
           @macroexpand @constraint(model, [t = 1:10], x[t] >= 0)
       end
quote
    #= REPL[6]:4 =#
    JuMP._valid_model(model, :model)
    begin
        #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:399 =#
        let model = model
            #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:400 =#
            (JuMP.Containers.container)(((t,)->begin
                        #= /Users/oscar/.julia/dev/JuMP/src/Containers/macro.jl:550 =#
                        begin
                            #= /Users/oscar/.julia/dev/JuMP/src/macros/@constraint.jl:171 =#
                            begin
                                #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:264 =#
                                var"#18###233" = begin
                                        #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:374 =#
                                        let
                                            #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:375 =#
                                            begin
                                                #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:371 =#
                                                var"#19###234" = (MutableArithmetics.copy_if_mutable)(x[t])
                                                var"#20###235" = (MutableArithmetics.operate!!)(MutableArithmetics.sub_mul, var"#19###234", 0)
                                            end
                                            #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:376 =#
                                            var"#20###235"
                                        end
                                    end
                                #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:265 =#
                                var"#21###236" = (JuMP.flatten!)(var"#18###233")
                            end
                            #= /Users/oscar/.julia/dev/JuMP/src/macros/@constraint.jl:172 =#
                            var"#22#build" = JuMP.model_convert(model, JuMP.build_constraint(JuMP.Containers.var"#error_fn#98"{String}("At REPL[6]:4: `@constraint(model, [t = 1:10], x[t] >= 0)`: "), JuMP._functionize(var"#21###236"), GreaterThanZero()))
                            #= /Users/oscar/.julia/dev/JuMP/src/macros/@constraint.jl:173 =#
                            JuMP.add_constraint(model, var"#22#build", "")
                        end
                    end), (JuMP.Containers).vectorized_product((JuMP.Base).OneTo(begin
                            #= /Users/oscar/.julia/dev/JuMP/src/Containers/macro.jl:95 =#
                            try
                                #= /Users/oscar/.julia/dev/JuMP/src/Containers/macro.jl:96 =#
                                1:10
                            catch
                                #= /Users/oscar/.julia/dev/JuMP/src/Containers/macro.jl:98 =#
                                (JuMP.Containers.var"#error_fn#98"{String}("At REPL[6]:4: `@constraint(model, [t = 1:10], x[t] >= 0)`: "))("unexpected error parsing reference set: ", $(Expr(:copyast, :($(QuoteNode(:(1:10)))))))
                            end
                        end)), JuMP.Containers.AutoContainerType, Any[:t])
        end
    end
end

```

If you compare it to

```julia
julia> using JuMP

julia> begin
           model = Model()
           @variable(model, x[1:10])
           t = 1
           @macroexpand @constraint(model, x[t] >= 0)
       end
quote
    #= REPL[8]:5 =#
    JuMP._valid_model(model, :model)
    begin
        #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:399 =#
        let model = model
            #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:400 =#
            begin
                #= /Users/oscar/.julia/dev/JuMP/src/macros/@constraint.jl:171 =#
                begin
                    #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:264 =#
                    var"#28###238" = begin
                            #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:374 =#
                            let
                                #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:375 =#
                                begin
                                    #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:371 =#
                                    var"#29###239" = (MutableArithmetics.copy_if_mutable)(x[t])
                                    var"#30###240" = (MutableArithmetics.operate!!)(MutableArithmetics.sub_mul, var"#29###239", 0)
                                end
                                #= /Users/oscar/.julia/packages/MutableArithmetics/tNSBd/src/rewrite.jl:376 =#
                                var"#30###240"
                            end
                        end
                    #= /Users/oscar/.julia/dev/JuMP/src/macros.jl:265 =#
                    var"#31###241" = (JuMP.flatten!)(var"#28###238")
                end
                #= /Users/oscar/.julia/dev/JuMP/src/macros/@constraint.jl:172 =#
                var"#32#build" = JuMP.model_convert(model, JuMP.build_constraint(JuMP.Containers.var"#error_fn#98"{String}("At REPL[8]:5: `@constraint(model, x[t] >= 0)`: "), JuMP._functionize(var"#31###241"), GreaterThanZero()))
                #= /Users/oscar/.julia/dev/JuMP/src/macros/@constraint.jl:173 =#
                JuMP.add_constraint(model, var"#32#build", "")
            end
        end
    end
end

```

you’ll see no closure.
