Passing constant configuration values to modules

I am working on a numerical optimisation project with Julia in a Jupyter notebook. My current workflow is to define the problem size with some global constants at the top of the notebook (eg. const N = 20), which are then used throughout my code.

In trying to organise my code better (and to avoid conflicts between variables in different files), I came across this article, and am now trying to move the majority of my code into a Julia module which would be imported by the notebook. I would still like to define my problem with global constants at the top of the notebook. Is this possible, and is it a good idea?

My instinct for passing these values into the module would be with an initialisation function, which could set global values in the module. However, I don’t believe this allows the values to be const, which I believe has performance impacts. An alternative would be to specify the constants directly in the module - would this be better? Is this necessary due to Julia’s precompilation of modules (which I have a limited understanding of)?

Well, it is possible but not really a good idea. Why not pass your problem properties to the optimization functions?

So instead of

N = 20
iterations = 10
savepath = "myfile"

solve()

you can do

solve(N = 20, iterations = 10, savepath = "myfile")

Or have a struct that holds the options:

opts = OptimizationOptions(N=20, iterations=10, savepath="myfile")
solve(opts)
1 Like

In such cases I tend to use Parameters.jl

then I simply create some file vars.jl in which i define all the needed parameters and simply include it my project.

vars.jl

 using Parameters

julia> @with_kw struct A
           a::Int = 6
           b::Float64 = -1.1
           c::UInt8 = 42
       end

main.jl

include("./vars.jl")
B=A()

and then I simply access the values with B.a and so on. It also allows to simply modify the values using C = A(a=7)

I have a bunch of functions which all use the same constants. In my previous MATLAB implementation, I had a constants struct which was passed through every function, but when I moved to Julia, it seemed neater to use global constants, in what I feel is a similar style to a C #define.

The solution I am going with is to have a parameters submodule which contains and exports the constants to all other submodules which use them.

I hope you don’t mind if I necro this thread: How is it possible?

I have a similar issue but with a different application.

We have a project that analyzes a large number of different data sets, with many steps of analysis. We have many functions that primarily exist to organize sections of the data analysis (though a few are reused frequently, most are used only once). We are organizing different scripts into modules to reduce risks of namespace collision and to further clarify ideas (when there are a very large number of steps involved in cleaning multiple data sets, long scripts that aren’t broken down into functions and further into modules can be very difficult to read, and are susceptible to hard-to-debug mistakes caused by state (for example, someone might define df = CSV.read(“path”, DataFrame) in one part of a script, then a different dataframe is loaded subsequently,. If the second loading line is accidentally deleted, then we have a difficult bug to detect or find… very bad)).

We have a config.json file which we use to load global configuration parameters, like directory paths. We had defined a global const CONFIG = dictionary_from_JSON_file.

yes, in principle we could add an additional filepath arguments to every function that might call a function that saves a figure or loads some data, but this clutters up the code and increases, rather than decreases, the risks of a mistake. Alternatively, we reload the global CONFIG constant from the JSON file into each module, but this seems repetitive. Another possibility is to eschew modules altogether.

How does one pass global constants into a module?

I suppose a fourth alternative is to use a "let CONFIG=CONFIG " block

You mean like:

julia> const CONFIG = 1
1

julia> module M
       import ..CONFIG

       run_analysis() = print("running with config = $CONFIG")
       end
Main.M

julia> M.run_analysis()
running with config = 1
2 Likes

I had no idea import worked on consts, thank you so much!

1 Like