Organisation of a diverse library in submodules using Reexport and ForceImport

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 Reexport and 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)