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.
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:
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:
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?