JuliaPhysics / JuliaPhysics/Unitful.jl
Parameter Type Stability on Unitful.jl parametric types
- Dominant language
- Julia
- Stars
- 675
- Forks
- 124
- Avg merge
- 3h 38m
- Merged PRs (30d)
- 1
Description
Currently `Unitful.jl` parametric type definitions lack indication/restrictions of what the type parameters are expected to be, for instance, `src/types.jl` defines `Quantity{T,D,U}` as:
```julia
struct Quantity{T,D,U} <: AbstractQuantity{T,D,U}
val::T
Quantity{T,D,U}(v::Number) where {T,D,U} = new{T,D,U}(v)
Quantity{T,D,U}(v::Quantity) where {T,D,U} = convert(Quantity{T,D,U}, v)
end
```
By building `Quantity` types by the intended interface, we finally know what `{T,D,U}` are expected to be—a numeric **Type**, a Dimensions **Value**, and a Units **Type**, respectively:
```julia-repl
julia> typeof(1u"m")
Quantity{Int64,𝐋,Unitful.FreeUnits{(m,),𝐋,nothing}}
julia> ptypes(x::Quantity{T,D,U}) where {T,D,U} = map(typeof, (T, D, U))
ptypes (generic function with 1 method)
julia> ptypes(1u"m")
(DataType, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}, DataType)
```
But this design allows for the **creation of "broken" instances**:
```julia-repl
julia> broken=Quantity{Float64,Float64,Float64}(3.0);
julia> typeof(broken)
Quantity{Float64,Float64,Float64}
```
In this example, `broken` cannot be *printed*, but can be wrongly *instantiated*.
This could be avoided if, for instance, each supertype parameter had type annotations in them, *for instance* (not necessarily a suggested implementation):
```julia
abstract type myAbstractQuantity{T<:Union{Real,Complex}, D<:Unitful.Dimensions, U<:Unitful.Units} end
struct myQuantity{T,D,U} <: myAbstractQuantity{T,D,U}
val::T
myQuantity{T,D,U}(v::Number) where {T,D,U} = new{T,D,U}(v)
# etc...
end
```
```julia-repl
julia> myQuantity{Float64} # Should be OK
myQuantity{Float64,D,U} where U where D
julia> myQuantity{Float64,Float64} # Should indeed error
ERROR: TypeError: in myAbstractQuantity, in D, expected D<:Unitful.Dimensions, got Type{Float64}
Stacktrace:
[1] top-level scope at REPL[22]:1
```
I also think that such type annotations make it easier to read the code and hence to write packages that use `Unitful.jl`.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.