Importing a package to all the submodules of a module

I want to import a common package to all the submodules inside my module. How to do this?

Example

module X1
    using Distributions
    abstract type abstract_Y end
    # How to make both 'abstract_Y' and 'Distributions' available to all 
    # the submodules of this module without explicitly mentioning it in
    # submodules?
    module Y1
        using ..abstract_Y  # How to avoid this??
        using Distributions # And this too??
        type Type1 <: abstract_Y
        end
        function func1( x::Type1 ) 
            # Do something with x of Y1.Type1
            rand( Bernoulli(0.9) )
        end
    end
    module Y2
        using ..abstract_Y
        using Distributions
        type Type1 <: abstract_Y   # I need to reuse name 'Type1' in this module
        end
        function func1( x::Type1 )
            # Do something with x of Y2.Type1
            rand( Normal(2.0,1.0) )
        end
    end
    # ...
    # module Yn
    #     ....
    # end
end

Here X1 is my parent module, and Y1 and Y2 are children. All my submodules will have definition for a type ‘Type1’ and assocsiated functions. That’s why I want to make them into multiple modules.

With Thanks,
Vishnu Raj

Why do you want to use the same type name in the submodules? It doesn’t seem like a good idea to use the same name for two different things.

Or what are you trying to do?

I’m a PhD scholar is working on a package to reproduce the results in few other papers.

I’m planning to write one module for each of the papers I want to reproduce the results and inside that I can put the methods to reproduce each of the figures.

Say I want to reproduce Fig.1 and Fig. 2 from Paper A and Fig.1, 2, 3 from Paper B. I’m planning to write it as


module ReproducibleResearch
    using Distributions
    abstract type BaseExperiment end
    
    # Module for Paper A
    module PaperA
        using ..BaseExperiment
        using Distributions   # All my papers depend on 'Distributions' package
        # but how to make them available to submodules by default
        # For Figure 1
        type Fig1 <: BaseExperiment
            # Specifics for this figure
        end
        function run( x::Fig1 )
            # Do experiment and plot the results
        end
        # For Figure 2
        type Fig2 <: BaseExperiment
            # Specifics for this figure
        end
        function run( x::Fig2 )
            # Do experiment and plot the results
        end
    end

    # Module for Paper B
    module PaperB
        using ..BaseExperiment
        using Distributions   # All my papers depend on 'Distributions' package, 
        type Fig1 <: BaseExperiment
            # Specifics for this figure
        end
        function run( x::Fig1 )
            # Do experiment and plot the results
        end
        
        type Fig2 <: BaseExperiment
             # Specifics for this figure
        end
        function run( x::Fig2 )
            # Do experiment and plot the results
        end

       type Fig3 <: BaseExperiment
             # Specifics for this figure
        end
        function run( x::Fig3 )
            # Do experiment and plot the results
        end
    end
end

Now you see why I need to reuse the Type names.
When I want to run, I can do

julia> x1 = Paper1.Fig1( args )
julia> x2 = Paper2.Fig1( args )
julia> p1 = run( x1 )  # This will return handles for plots of the results
julia> p2 = run( x2 )  # Again, handle for plots the results

This is the reason why I need to reuse type names.

This is one method I thought out to solve my problem.
Is there any other solutions to solve this reusing FigX problem?

Perhaps I am missing something about the setup, but the way I would do this is

  1. factor shared code and dependencies into a single module

  2. make other packages use this.

I would avoid making any submodules at all. The cost is this is a using CommonModule in each module. The benefit is a much more modular setup.

1 Like

Thanks @Tamas_Papp.
But here, my submodules have different codes. I just need few packages to be automatically available for the sub-module (instead of using Distributions inside every submodule).

As far as I know, the answer is: you can’t. Modules in Julia (unlike e.g. Python) intentionally do not contain symbols from an outer module that contains them. That’s inconvenient in your current case but has the nice property of making module namespaces easier to reason about.

If you want, you could write a macro that inserts the appropriate set of using declarations. But the standard syntax of using Foo, Bar is already pretty terse. How many packages do you actually want to be using inside each submodule?

2 Likes

Thanks @rdeits.
My submodules are also split into multiple files and I have to use 5-6 packages inside each submodule module. I put those common packages inside a common.jl file and uses include("common.jl") inside each of the submodule.