Canonical way on how to use something that is defined later in the code?

I have a package that is divided in several modules, says Utils and 'Algos`, each on his file:

MyPackage.jl:

include("Utils.jl")
include("Algos.jl")

Up to now Algos was using something defined in Utils, and there were no problems, but now also Utils needs to use some funcionality provided by Algos.

Which is the “canonical” way to deal for situations like this? In C++ there was a way to declare empty classes and then implement them later, maybe something similar?

Personally, I would try to separate the Algos functionality that is required by Utils and incorporate that into Utils itself, to prevent this kinda of circular dependency.

Another option is collapsing both files into one or separating shared functionality between both into a third file.

There may be a better way of handling this situation that I am not aware of however.

This problem was occurring also for me for a specific project. In the end I decided to put all the struct, type, enums definitions in a specific subfolder ./src/Types/, which I included from the main file first. Then I could define all possible functions in the files to follow without problems.

# type, structs, enums, etc. definitions
./src/Types/regardingAtypes.jl
./src/Types/regardingBtypes.jl
./src/Types/regardingCtypes.jl
# funcionality
./src/AB.jl
./src/A.jl
./src/ABC.jl
# ...
# my main file
module MyModule
# include type definition
include("Types/regardingATypes.jl")
include("Types/regardingBTypes.jl")
include("Types/regardingCTypes.jl")
# functionality
include("AB.jl")
include("A.jl")
include("ABC.jl")
# ...
end

Ofc as long as you don’t have this issue handle mutually-circular type declarations · Issue #269 · JuliaLang/julia · GitHub.

1 Like