# Is there a mechanism in Julia to load modules on demand?

**URL:** https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784
**Category:** General Usage
**Tags:** module
**Created:** [January 25, 2020, 6:07pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784 "2020-01-25T18:07:36Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![nxtruong](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nxtruong/32/7991_2.png) [@nxtruong](https://discourse.julialang.org/u/nxtruong)
#### Post date: [January 25, 2020, 6:07pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/1 "2020-01-25T18:07:37Z")

</div>

As I understand, `using` and `import` statements must be at the top level. However, sometimes I just want to import a module on-demand, in a function that uses that module. For example, a large module X contains both functions for computation and functions for plotting in a certain scientific domain. So X imports a bunch of other modules, including `Plots.jl`, at the top level, which slows down the import of X significantly (via `using X` or `import X`), even though I usually only need its computation functions, not its plotting functions. Is there a canonical way in Julia to import `Plots.jl` only when the first plotting function is called, but not before? Certainly one way is to split X into, e.g., X and Xplots, where all the plotting functions are in Xplots. But apparently the developers of X may find this method undesirable and potentially break a lot of existing code that uses X.

I’ve tried a few things. The following caused an error because `using` must be at the top level.

```julia
test1(x, y) = x*y

function test2(x, y)
		 using Plots
		 plot(x, y)
end

```

The following didn’t cause an error at first, but a run-time error:

```julia
test1(x, y) = x*y

function test2(x, y)
		 @eval Main begin
		 	   using Plots
		 end
		 plot(x, y)
end

```

Calling `test2(0:0.1:1, sin)` resulted in an error:

```julia
ERROR: MethodError: no method matching plot(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::typeof(sin))
The applicable method may be too new: running in world age 26765, while current world is 26789.

```

I guess `Plots.jl` may implement some tricks that allow it to load backend modules on demand, so there may be a way. However, is it cleaner to allow importing modules at levels other than the top level, says in a function’s scope? Or will there be problems if this is allowed?

---

<div class="post-metadata">

### Author: ![Jakub\_Wronowski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakub_wronowski/32/204030_2.png) [@Jakub\_Wronowski](https://discourse.julialang.org/u/Jakub_Wronowski)
#### Post date: [January 25, 2020, 6:20pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/2 "2020-01-25T18:20:52Z")

</div>

Probably someone with more expertise will give you better answer to your exact question. From my point of view problem is somewhere else: you should move your calculation functions to a separate module that does not depend on Plots.jl. Then you may ship plotting functions as other module that depends on your module, or maybe as just .jl script.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [January 25, 2020, 6:31pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/3 "2020-01-25T18:31:58Z")

</div>

This doesn’t really save you any time though right? Conditional on plotting something, you still face the same amount of “waiting”. You are just shifting when some of that waiting happens, and also it seems making the code more fragile.

---

<div class="post-metadata">

### Author: ![Jakub\_Wronowski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakub_wronowski/32/204030_2.png) [@Jakub\_Wronowski](https://discourse.julialang.org/u/Jakub_Wronowski)
#### Post date: [January 25, 2020, 6:35pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/4 "2020-01-25T18:35:30Z")

</div>

> [@nxtruong](#):
>
> I usually only need its computation functions, not its plotting functions. Is

@tbeason I think plotting is not used in most of the cases

---

<div class="post-metadata">

### Author: ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)
#### Post date: [January 25, 2020, 6:39pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/5 "2020-01-25T18:39:32Z")

</div>

The Requires package effectively addresses this. You would need to refactor things to put the optional logic at the top level (see the docs).

> **[GitHub - JuliaPackaging/Requires.jl: Lazy code loading for Julia](https://github.com/JuliaPackaging/Requires.jl)**
>
> Lazy code loading for Julia. Contribute to JuliaPackaging/Requires.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [January 25, 2020, 6:41pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/6 "2020-01-25T18:41:23Z")

</div>

`eval` executes in global scope, not in the local scope of your function. The scope of `test2` was created before you imported the `Plot` module into global scope. Thus it does not know the method.

You could use then [`Base.invokelatest`](https://docs.julialang.org/en/v1/base/base/#Base.invokelatest) to call the plot function like that:

```julia
function test2(x, y)
		 @eval Main begin
		 	   using Plots
		 end
		 Base.invokelatest(plot, x, y)
end

```

and it will do what you want.

---

<div class="post-metadata">

### Author: ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)
#### Post date: [January 25, 2020, 6:56pm UTC](https://discourse.julialang.org/t/is-there-a-mechanism-in-julia-to-load-modules-on-demand/33784/7 "2020-01-25T18:56:21Z")

</div>

The package Requires.jl mentioned above is one way.

For Plots specifically, you can investigate plot recipes, where your package depens only on [RecipesBase.jl](https://github.com/JuliaPlots/RecipesBase.jl).
