I have a Machine Learning library with different stuff that I am keeping organised in submodules. I use submodules because (1) They actually make “logical” sense to classify them in submodules; (2) They integrate nicely with Documenter, e.g. I can docstring the module and create a documentation page for each module, (3) They “share” the same “Utils” set of functions and have a common api; (4) I don’t want the burden to maintain several small packages. Using multiple packages also increases complexity for the user, at least initially.
The fact the different algorithms (partially) share the same API is however a problem, as Multiple Dispatch doesn’t “merge” functions from different modules, so if one want to use several submodules has to use a fully qualified name in order to call the different algorithms.
A solution is to use the
ForceImport packages as in the example below. It seems to work, but I am asking if there could be performances penalties of hidden tricks that could coming back later in using this approach.
module BaseModule module Utils export predict, mysum predict(x::Int64) = x +10 mysum(x,y) = x+y end module AMod using ForceImport @force using ..Utils export AType, predict struct AType x::Int64 end predict(x::AType,y) = mysum(x.x , y) end module BMod using ForceImport @force using ..Utils export BType, predict struct BType x::Int64 end predict(x::BType) = x.x end using ForceImport, Reexport @force using .Utils @reexport using .Utils @force using .AMod @reexport using .AMod @force using .BMod @reexport using .BMod end using ..BaseModule bobj = BType(2) predict(bobj) mysum(1,2) aobj = AType(1) predict(aobj,2) predict(bobj)