# Dynamic Code Loading to Use Packages on Demand

**URL:** <https://discourse.julialang.org/t/dynamic-code-loading-to-use-packages-on-demand/48655>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 19, 2020, 9:27pm UTC](https://discourse.julialang.org/t/dynamic-code-loading-to-use-packages-on-demand/48655 "2020-10-19T21:27:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![TheCedarPrince](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thecedarprince/32/17323_2.png) [@TheCedarPrince](https://discourse.julialang.org/u/TheCedarPrince)\
**Post date:** [October 19, 2020, 9:27pm UTC](https://discourse.julialang.org/t/dynamic-code-loading-to-use-packages-on-demand/48655/1 "2020-10-19T21:27:20Z")

</div>

I ran into an interesting problem today that I am trying to figure out (along with @Wikunia and @arsh). Basically, it stems from the idea of trying to load specific packages by user demand. The specific issue we are working on is this: [https://github.com/Wikunia/Javis.jl/pull/236](https://github.com/Wikunia/Javis.jl/pull/236)

Here is what we are trying to achieve:

> Package `A` has function `main()` which can call function `extra()` which resides in script `extra_file.jl`. The functions that are in `extra_file.jl` rely on package `B`. Package `B` however, is quite large and we desire to not use it each time a user runs `A.main()` as they may not always need `main()` to call function `extra()`.

Some pseudo code could be thought of as follows (NOTE: ignore the fact that each time the user executes `main(true)` it uses `B` and includes `extra_file.jl` repeatedly. In practice, we only want to execute these commands once):

```julia
module A
    ...
    function main(call_extra = false)
        ...
        if call_extra == true
            using B
            include("extra_file.jl")
            extra()
        end
    end
    ...
end

```

We attempted to use Requires.jl to handle this problem but, to carry from the example, `extra()` was not able to be called. Then, we tried the exact same solution in the preceding example and ran into the notorious “world age” problem.

We feel like we are getting close to a solution but are not sure of how to move forward. We looked at `Base.invokelatest()` to address the problem, but not sure whether that is the solution nor to exactly implement it. Any thoughts? Thank you! ~tcp

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [October 19, 2020, 9:54pm UTC](https://discourse.julialang.org/t/dynamic-code-loading-to-use-packages-on-demand/48655/2 "2020-10-19T21:54:19Z")

</div>

Requires.jl likes to be used in ` __init__ `, where it setups up a callback to run when a package is loaded to see if it was the one it wanted.

I think typical would be something like:

```julia
using Requires

function __init__ ()
    @require GTK="12345-2323..." begin
        using .GTK
        include("extra_file.jl")
    end
end

function main(call_extra=false)
    # ...
    if call_extra
        if isdefined(@ __MODULE__ , :GTK)
            extra()
        else
            error("GTK not loaded. To support extra mode first run using GTK, before calling main(true")
        end
    end
    #...
end

```

If you really want to do it in response to the argument i _think_ the following work.

```julia
using Requires

function __init__ ()
    @require GTK="12345-2323..." begin
        using .GTK
        include("extra_file.jl")
    end
end

function main(call_extra=false)
    if call_extra && !isdefined(@ __MODULE__ , :GTK)
        @eval(:(using GTK))
        Base.invokelatest(inner_main, call_extra)
    else
        inner_main(call_extra)
    end
end

function inner_main(call_extra)
...
end

```

Might need to/want to use `Base.requre` instead of `@eval(:using GTK))`

Requires.jl doesn’t do great things to your net load time if it is needed though.  
It causues the main task to block, when you load the package IIRC.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 19, 2020, 9:58pm UTC](https://discourse.julialang.org/t/dynamic-code-loading-to-use-packages-on-demand/48655/3 "2020-10-19T21:58:18Z")

</div>

`include` ends up calling `eval`, so you are right, if you want to call `extra` in the same function its definition is `includ`ed in, you need to make sure, you call it from the correct world age. In this case, just `Base.invokelatest(extra)` should do the trick.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 19, 2020, 10:02pm UTC](https://discourse.julialang.org/t/dynamic-code-loading-to-use-packages-on-demand/48655/4 "2020-10-19T22:02:23Z")

</div>

> [@oxinabox](#):
>
> `Base.invokelatest(inner_main)`

(I think you meant `Base.invokelatest(inner_main, call_extra)` here)
