JuliaPhysics / JuliaPhysics/Unitful.jl

Parameter Type Stability on Unitful.jl parametric types

Open
#282 3 comments 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.