Search code examples
importjuliarandom-seed

Re-importing modules already imported in included files in Julia


In my Julia code I use functions from other files, added via include. E.g., I may have something like

using DataFrames, CSV
import Random: shuffle, seed
using Base.Filesystem: mkpath

include("existing_code.jl")

seed!(2025)

The code in existing_code.jl might however already include something like

using DataFrames, CSV, Random
using Base.Filesystem: mkpath

Random.seed!(1984)

However, my impression is that, since the modules (like DataFrames, CSV, Random are already imported in the other file, there is no need to re-import them. I wonder, what is a good practice here ? And what are the possible dangers of not following good practices?


Solution

  • The include(...) function runs a given file, as if the content of the file were simply copy-and-pasted where the include call is. From this angle, its clear to see that you are running those using calls multiple times, and I agree that you don't need to re-import the modules the second time.

    In the event where you know that the necessary modules will be loaded in existing_code.jl , then it is best to avoid the repeated import and simply omit the first three lines of your file. The benefit being that the unnecessary checks take time (although, not very much time). If documentation is a worry, consider leave a comment on what modules are imported in the include call.

    include("existing_code.jl")
    # existing_code.jl imports: 
    # DataFrames, CSV, Random: [shuffle, seed], Base.filesystem: [mkpath]
    
    seed!(2025)
    

    It seems, based on your usage of "may" and "might", that it's possible that the imported file may not include necessary modules. In this case, the usings are needed. With this expectation, there are two options. One is to do what you have done: attempt to import the modules again, always. The drawback being that it is sometimes unnecessary. The second option is to check each import to decide whether to import or not. This could look something like:

    include("existing_code.jl")
    
    !(@isdefined DataFrames) ? using(DataFrames) : nothing
    !(@isdefined CSV) ? using(CSV) : nothing
    # etc. for all of your imports...
    
    seed!(2025)
    

    If you are willing to overhaul your project a bit, many would consider the best practice to be creating a new module, in which the namesake file could import all necessary modules, which would then be usable by its various methods. Good summary here: https://discourse.julialang.org/t/best-practise-organising-code-in-julia/74362/2