Technically, I agree with @rdeits. However, I’m not sure that’s really the solution you are looking for.
My experience
I have experienced the same confusion myself, and I have noticed that others seem to be stuck in the same mindset. I think it might stem from our ingrained C/C++'s include/header file methodology (assuming that’s your background).
In most cases, I don’t really want to break things up into different modules - especially inside a single package. Typically, when I need to break things up into separate modules, I really end up making one package per module.
If I’m not mistaken, there is a good chance that what you consider to be a package might actually be some sort of repository that collects somewhat related import-able modules (called “packages” in julia). Don’t get me wrong, Module
s still exist in Julia, but they seem to correspond more to namespaces in C++.
Suggested structure, given your MWE
I tend use my .jl files (as you showed) just to separate out different functional blocks, and keep my files to a more (mentally) manageable size.
So yes, I would define files a.jl, b.jl, c.jl, and d.jl as follows:
a.jl:
struct Astruct
#...
end
#more related code ...
b.jl:
bfunc(a::Astruct) = dosomething(a)
#more related code ...
c.jl:
cfunc(a::Astruct) = dosomethingelse(a)
#more related code ...
d.jl:
function dfunc()
a = Astruct()
bresult = bfunc(a)
cresult = cfunc(a)
return dosomethingwith_bandc_result(bresult, cresult)
end
#more related code ...
Finally, I would include
all these files in the master M.jl file.
Note that [pkg_loadpath]/[PkgName]/src/[PkgName].jl
is the file Julia automatically loads when the caller imports your module with either import PkgName
or using PkgName
.
See Code Loading · The Julia Language for more details on how packages are loaded.
Well, that’s at least true if you add [pkg_loadpath]
to Julia’s LOAD_PATH
variable, or if your CWD is in [pkg_loadpath]
. See Constants · The Julia Language for more details on LOAD_PATH
.
In any case, this is what my M.jl would look like:
#But yes, your "Julia package" code needs to be wrapped inside
#a Module of the same name:
module M
#Import some "Julia packages":
#(Which you probably typically think of as "modules")
using FFTW
using SomeOtherPackage1
using SomeOtherPackage2
#include the all the functionality broken up in separate files:
include("a.jl")
include("b.jl")
include("c.jl")
include("d.jl")
function run_the_fancy_calculation
#setup constants
result = dfunc()
#more computations
return result
end
#more related code ...
end