# Optionally loading a module

**URL:** <https://discourse.julialang.org/t/optionally-loading-a-module/5579>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 26, 2017, 7:06pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579 "2017-08-26T19:06:26Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mforets](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mforets/32/298_2.png) [@mforets](https://discourse.julialang.org/u/mforets)\
**Post date:** [August 26, 2017, 7:06pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/1 "2017-08-26T19:06:26Z")

</div>

suppose that a module `foo.jl` depends on external packages which take several seconds to load, e.g.

```julia
julia> tic(); using JuMP, GLPKMathProgInterface; toc()
elapsed time: 4.929913064 seconds

```

in my case, `foo.jl` only eventually uses JuMP, thus it seems more convenient to load it only when needed.

the strategy that i’ve used successfully with `PyPlot` is to evaluate the `using` command at run-time. however, it fails here. the problem appears with the `@variable` macro.

for example:

```julia
module foo

function my_fun(...)
    ...
    if isdefined(:JuMP)
        eval(Expr(:using, :JuMP))
        model = JuMP.Model(solver=GLPKSolverLP())
        JuMP.@variable(model, x[1:p.dim]) # << triggers: LoadError: UndefVarError: JuMP not defined
        ...
    else
        error("...")
    end
end 
end #module foo

```

is there a way to “avoid expanding the macro”? or, is there another workaround for optionally loading a package? Thanks

_EDIT_. here’s a MWE:

```julia
module foo

using JuMP
using GLPKMathProgInterface

function my_fun(C::Float64)::Float64
    m = Model(solver = GLPKSolverLP())
    @variable(m, 0 <= x <= 2)
    @variable(m, 0 <= y <= 30)

    @objective(m, Max, 5x + 3*y)
    @constraint(m, 1x + 5y <= C)

    print(m)

    status = solve(m)

    println("Objective value: ", getobjectivevalue(m))
    println("x = ", getvalue(x))
    println("y = ", getvalue(y))
    return getobjectivevalue(m)
end
export my_fun
end # module foo.jl

```

and:

```julia
julia> tic(); include("foo.jl"); using foo; toc()
elapsed time: 6.753355159 seconds
6.753355159
 
julia> my_fun(3.0)
Max 5 x + 3 y
Subject to

 x + 5 y ≤ 3
 0 ≤ x ≤ 2
 0 ≤ y ≤ 30
Objective value: 10.6
x = 2.0
y = 0.2
10.6

```

now let’s try the package Requires.jl :

```julia
module bar
using Requires

function my_fun(C::Float64)::Float64
    !isdefined(:JuMP) ? eval(:(using JuMP)) : nothing
    !isdefined(:GLPKMathProgInterface) ? eval(:(using GLPKMathProgInterface)) : nothing
    @require JuMP begin
        @require GLPKMathProgInterface begin
            m = Model(solver = GLPKSolverLP())
        end
    @variable(m, 0 <= x <= 2)
    @variable(m, 0 <= y <= 30)

    @objective(m, Max, 5x + 3*y)
    @constraint(m, 1x + 5y <= C)

    print(m)

    status = solve(m)

    println("Objective value: ", getobjectivevalue(m))
    println("x = ", getvalue(x))
    println("y = ", getvalue(y))
    return getobjectivevalue(m)
    end
end
export my_fun
end # module bar.jl

```

then

```julia
julia> tic(); include("bar.jl"); using bar; toc()
elapsed time: 0.087633098 seconds
0.087633098

julia> my_fun(3.0)
WARNING: Error requiring JuMP from bar:
UndefVarError: C not defined

Stacktrace:
 [1] err(::bar.##7#15, ::Module, ::String) at /Users/forets/.julia/v0.6/Requires/src/require.jl:42
 [2] withpath(::bar.##6#14, ::String) at /Users/forets/.julia/v0.6/Requires/src/require.jl:32
 [3] listenmod(::bar.##5#13, ::Symbol) at /Users/forets/.julia/v0.6/Requires/src/require.jl:13
 [4] macro expansion at /Users/forets/.julia/v0.6/Requires/src/require.jl:52 [inlined]
 [5] my_fun(::Float64) at /Users/forets/Projects/Compositional/CompositionalHA.jl/test/Sets/bar.jl:7
 [6] eval(::Module, ::Any) at ./boot.jl:235
 [7] eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:66
 [8] macro expansion at ./REPL.jl:97 [inlined]
 [9] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73
ERROR: MethodError: Cannot `convert` an object of type Void to an object of type Float64
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] macro expansion at /Users/forets/.julia/v0.6/Requires/src/require.jl:52 [inlined]
 [2] my_fun(::Float64) at /Users/forets/Projects/Compositional/CompositionalHA.jl/test/Sets/bar.jl:4774:

```

why’s that? (without passing the C as argument, it works).

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [August 26, 2017, 10:15pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/2 "2017-08-26T22:15:00Z")

</div>

There’s [Requires.jl](https://github.com/MikeInnes/Requires.jl).

---

<div class="post-metadata">

**Author:** ![mforets](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mforets/32/298_2.png) [@mforets](https://discourse.julialang.org/u/mforets)\
**Post date:** [August 27, 2017, 7:49am UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/3 "2017-08-27T07:49:05Z")

</div>

@tkoolen : Thank you.

I’ve edited the question with a minimal working example. I haven’t been able to get it work yet when the problem depends on some arguments that are defined at run-time 😕

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [August 27, 2017, 2:00pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/4 "2017-08-27T14:00:48Z")

</div>

Can you do something like (untested):

```julia
my_fun(args...) = error("this function requires the JuMP module")

@require JuMP begin
  using GLPKMathProgInterface
  function my_fun(C::Float64)::Float64
    m = Model(...)
    # etc...
  end
end

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 27, 2017, 5:29pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/5 "2017-08-27T17:29:47Z")

</div>

> [@mforets](#):
>
> rror: UndefVarError: JuMP not defined

Last time I checked Requires.jl didn’t work well with macros, specifically with JuMP. @anon94023334 had an issue tracking this in LightGraphs.jl awhile back. I don’t know if that changed.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 27, 2017, 5:36pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/6 "2017-08-27T17:36:35Z")

</div>

The issue, as I recall, had to do with the fact that macros are evaluated at compile-time, which means Requires.jl isn’t available.

---

<div class="post-metadata">

**Author:** ![mforets](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mforets/32/298_2.png) [@mforets](https://discourse.julialang.org/u/mforets)\
**Post date:** [August 28, 2017, 7:11pm UTC](https://discourse.julialang.org/t/optionally-loading-a-module/5579/7 "2017-08-28T19:11:09Z")

</div>

i get `UndefVarError: @variable not defined`

(changing the first line to `function my_fun(C::Float64) error("this function requires the JuMP module") end`)
