I have a package MyPkg with some numbers that act as settings which for the most part are “constants”. But I would like users to be able to specify some variations of these so I can not define them as const. I’m thinking I’ll use functions. So if I want users to be able to specify the speed of sound or the data-storage format for some use, I might do something like:
soundspeed() = 344
dataformat() = Float32
I pass these values to other functions mostly in their arguments, but may sometimes use them directly in the function body. Examples:
function f(x, speed = soundspeed())
...
end
function g(x)
container = dataformat()[]
...
end
Then, users can do MyPkg.soundspeed() = 343 and continue to use the package.
Is this a good way to implement the flexibility I desire?
I considered using Refs, but I think I was getting into type-stability / type-inference issues. For example, if I want to allow dataformat Float32 and Float64, I’d need to create a dataformat = Ref{Type{<:AbstractFloat}}(Float32).
I considered creating a struct like Settings where I would store all my constants. This is useful because the constants are interdependent. For example, if the setting we_are_in_outer_space is true, then soundspeed must be 0. I could validate these interdependencies before returning a Settings object. The issue was that I still needed the fields of Constants to have abstract types. I think I can still do my validation checks with the above approach-- just need to do my checks against In the above approach, the user would also need to do a validation check after updating the settings.we_are_in_outer_space() inside soundspeed() before returning.
My concern is that because of things like inlining and constant proagation-- things I don’t understand-- the settings might get hard-coded. I’ve done a few tests and it doesn’t seem to be happening, but I believe Julia has some leeway on when it decides to do that stuff so I remain unsure.
I think if the user redefines these functions, other methods might get invalidated and need to be recompiled. That is okay, though if there is a way to ship the package with a few versions of these settings precompiled and cached, that would be nice.