Julia Circular Inclusion

Viewed 362

My goal: For a project, be able to include local files (part of the same project, same exact directory), trivially, possibly circularly.

In Julia, say I have the files:

FILE1.jl

module A

include("FILE2.jl")
using B

# Type annotations that need types from B

end

FILE2.jl

module B

include("FILE1.jl")
using A

# Type annotations that need types from A

end

In Julia (>v1), this results in an infinite loop. I have tried adding files to my loadpath so that I may directly use using or import, but it still can't find them.

What is the "Julian" way to include files within the same directory assuming circular dependencies, and are part of the same project? I see many posts saying something like, "if this is the case, your code is probably wrong", and I think that's just a silly claim to make.

1 Answers

A common structure is to put all includes in one place, at the root of your project. Flux.jl is a good example.

People use module to subdivide their project if it is very large, but you don't need to! A large project can consist of a single module. I would suggest to only split a chunk of code into its own module if it makes sense as an isolated whole. (Others might have a different view on this!) But since you asked about circular references, it sounds like a single module better suits your situation.

Modules cannot contain circular references:

# will not work
module A
    import ..B: y
    x = 1
end
module B
    import ..A: x
    y = 1
end

This is not a problem with functions:

function a(x)
    if x < 1
        1
    else
        b(x-1) * 2
    end
end

function b(x)
    a(x)
end

b(10)

Functions can use types, functions, constants, modules that are defined after its own definition.

Related