What does `include` do?

In fact, it was the second post on this thread

Yes, this is exactly the point - by putting function definitions rather than declarations in header files, it becomes possible (easy) to create a multiple definition conflict in the linker stage - because there will be two identical function names with defined function body (code implementation) coming from two translation units. (Or more accurately, two or more translation units.)

Reading the linked post here for a second time caused me to pick up on a couple of things.

  • include from the top level only

While that seems like advice rather than an exact rule which has to be followed, that would make a lot of sense given what you said about include acting like Makefile statements. I’m starting to see where this is heading…

I suppose in some sense, not include’ing a file more than once comes down to author discipline rather than something the language/JIT compiler enforces?

Regarding modules specifically, I suppose in some sense the advantage of Julia is it is very flexible. You can write some code and then wrap it in a module statement to give it a namespace/sub-namespace.

On the other hand, the disadvantage of Julia is it is very flexible, and allows you to do this while having no regard for directory structure, etc, which potentially could result in a very difficult to comprehend project structure. Spaghetti.

Would saying that this has advantages and disadvantages, if not used in a considerate way, be an accurate assessment? I find it difficult to comprehend why someone would create a package consisting of multiple levels of directories and then not name their modules the same as the directories, but in principle it seems possible.

1 Like

Very much so. Reasoning about a Julia code base can be hard if the authors don’t show some organizational discipline.

Directories and submodules are not that common in Julia packages, and are often recommended against. However, it is extremely common (and recommended) to have one module be split up into separate files, which then all come together by being included in the main module / package file.

2 Likes

I suspected someone might be about to say this, and I must say I do sort of agree with this sentiment despite my very strong personal urge to define a hierarchy of dependencies using directories. In other languages this really is valuable but I can see how it might work against you in Julia.

Thank you for your comments by the way this is valuable information.

It depends a little on the package, too. In QuantumControl.jl, I use submodules extensively to organize the API. It makes sense to me to group all the functions implementing different optimization functionals into a QuantumControl.Functionals submodule. If everything was in the top module, that would be far too many functions, and it wouldn’t give any indication about how the functions are related.

On the other hand, in something simpler like DocumenterCitations.jl, I use a flat hierarchy, despite this being split into quite a large number of .jl files.

Most Julia packages are on the smallish side in terms of their API, and thus prefer a flat hierarchy, especially since submodules definitely add some mental overhead for development workflows.

1 Like

That was an analogy of its usage in a particular context, not exactly what it does. A counterexample is that include is the go-to way to interactively run a script in an active REPL, which is nothing like C++'s #include. Yes, you’re technically evaluating in a module Main, but you’re not trying to develop and compile Main. Languages with different philosophies won’t have one-to-one correspondences.

2 Likes