Problems with signature changes of imported local modules on include

hijit
Wed, 11 Oct 2023 10:26:27 +0000
General Usage

Hi I realized during the development of a Julia package that one of the big drawbacks of importing/using local modules is that the signatures of all functions tied to a Modules namespace are changed to be nested in the including Modules namespace when include is called. Which makes sense, because that is exactly what include does; evaluating the included file in the enclosing Module. This creates issues however when you want to construct objects in one module and then evaluate them in another based on a variable known only at runtime because the method signatures tied to the type definition in the evaluating module don’t match those of the module where the object was constructed. I’ll try to construct a simple example below:

config.toml

runtimevars=["Evaluate in ModuleA.", "Evaluate in ModuleB."]

MyModel.jl

module MyModel
struct Model
data::String
end

function getdata(model::Model) = model.data
end

MyEntryPoint.jl

module MyEntryPoint
include("MyModel.jl")
import TOML
using .MyModal
configs = TOML.parsefile("config.toml")
runtimevars = configs["runtimevar"]

for var in runtimevars
    model = Model(var)
    if var == "Evaluate in ModuleA."
        include("ModuleA.jl")
    elseif var == "Evaluate in ModuleB."
        include("ModuleB.jl")
    end
end
end

ModuleA.jl

include("MyModel.jl")
using .MyModal
processdataA(model::Model) = println(getdata(model))

#=
SOME CONDITIONAL TO ENSURE THAT THIS ONLY OCCURS
IF IT IS INCLUDED IN THE ENTRY POINT.
=#
using ..MyEntryPoint: model
println(getdata(model))
println("We are evaluating in ModuleA.")

ModuleB.jl

include("MyModel.jl")
using .MyModal
processdataB(model::Model) = println(getdata(model))

#=
SOME CONDITIONAL TO ENSURE THAT THIS ONLY OCCURS
IF IT IS INCLUDED IN THE ENTRY POINT.
=#
using ..MyEntryPoint: model
processdataB(model)
println("We are evaluating in ModuleB.")

I know there is/must be a way to simply import/use the method definitions tied to the Model type as they would be identified in the MyEntryPoint.jl in both Modules A and B. But I don’t like this solution because I lose the modularity of my Modules by enforcing that Modules A & B only make sense so long as they are included in MyEntryPoint. At the moment my workaround is FromFile.jl because methods imported using this macro all have the same signature, which keeps my Modules “modular”. I was prompted to look for a Julia native solution however because the Julia LSP doesn’t work with FromFile imports, and sufficiently large projects get difficult to keep all in my head. Thanks for taking time to figure out what I mean here, hope I was able to be clear

27 posts - 3 participants