Hi! I wrote this on the Slack but I think here may be a good fit.
I have a package that contains some physical constants (for example g, the acceleration of gravity). I provide units with the constants through Unitful.jl . But I want the user to be able to use the constants with units or without units
One option is to leave the user the burden of importing the module and defining all the unitless constants by hand at the beginning. But because my user is me, I found this annoying. What I thought is to have two submodules on my package. One contains the values with units and one without units.
module MyPackage
module WithUnits
export constantsWithUnits
end
module NoUnits
export constantsWithNoUnits
end
end
So that the user can do at the beginning:
using MyPackage
using MyPackage.WithUnits
or
using MyPackage
using MyPackage.NoUnits
and get the constants with units or without them at will.
This seems to work, but then how can I change my choice after I used one of them already? This would be useful for example to run the unit tests with both of the choices.
You could bind a non-constant name to the module, but probably that cannot be recommended if you need these constants for performance critical code:
julia> module A
export c
c = 1
end
Main.A
julia> module B
export c
c = 2
end
Main.B
julia> using .A
julia> mymod = A
Main.A
julia> mymod.c
1
julia> using .B
julia> mymod = B
Main.B
julia> mymod.c
2
I think this may work, although I wanted to avoid having to qualify constants name with a module, e.g. instead of g having to write constants.g which makes it many times longer. I should rethink my design and keep an eye open on other packages to see how they do similar things.
Hi,
This is something for which I’m also looking for a solution.
I was thinking more of another way, but maybe it’s not applicable to your case.
using Unitful
import PhysicalConstants.CODATA2018: c_0
Then define two methods that give back c_0:
speed_light( :: T ) where {T <: Number} = ustrip(c_0)
speed_light( ::Quantity{T,D,U}) where {T,D,U} = Float64(c_0)
The first method gives just the value of c_0, the second adds the units:
julia> speed_light(1.0)
2.99792458e8
julia> speed_light(1u"m")
2.99792458e8 m s^-1
Now you could use this in your code to compute the frequency
julia>frequency(wavelength) = speed_light(wavelength)/wavelength
frequency (generic function with 1 method)
julia> frequency(200e-9)
1.49896229e15
frequency(200e-9u"m")
1.49896229e15 s^-1