JuliaPhysics / JuliaPhysics/Unitful.jl
`AbstractQuantity` subtypes and quantity kinds
- Dominant language
- Julia
- Stars
- 675
- Forks
- 124
- Avg merge
- 3h 38m
- Merged PRs (30d)
- 1
Description
### The concept
["Defining ‘kind of quantity’" (Flater)](https://nvlpubs.nist.gov/nistpubs/TechnicalNotes/NIST.TN.2034.pdf) and ["On (kinds of) quantities" (Mari)](https://lmari.github.io/publ/2009Met_KindsQuantities.pdf) discuss a hierarchy of kinds of quantity, in which radius and wavelength are both kinds of quantity that have dimension "length". I think this could be useful for a function that's supposed to take a radius but not a wavelength, or for just keeping track of what's what.

### Implementation
Currently, for a type `Q <: AbstractQuantity`, the `*(::Number, ::Q)` and `/` methods return a `Quantity`, not a `Q`. I propose to replace them with methods that return a `Q`, so the type will be preserved. For example,
```jl
using Unitful
@eval Unitful begin
function *(x::Number, y::AbstractQuantity{T,D,U}) where {T,D,U}
y isa AffineQuantity && throw(AffineError("an invalid operation was attempted with affine quantities: $x*$y"))
Q = Base.typename(typeof(y)).wrapper
v = x*y.val
return Q{typeof(v), D, U}(v)
end
end
abstract type AbstractLength{T,D,U} <: Unitful.AbstractQuantity{T,D,U} end
abstract type AbstractRadius{T,D,U} <: AbstractLength{T,D,U} end
struct CircleRadius{T,D,U} <: AbstractRadius{T,D,U}
val::T
end
cr = CircleRadius{Float64, Unitful.𝐋, Unitful.FreeUnits{(u"m",), Unitful.𝐋, nothing}}(3.0)
@assert (4 * cr) isa CircleRadius
```
### Related work
The [mp-units](https://mpusz.github.io/mp-units/latest/users_guide/framework_basics/dimensionless_quantities/?h=kind#nested-quantity-kinds) C++ library supports a bunch of kinds for dimesionless quantities. I haven't got my head all the way around this one yet.
### Questions
There are a lot of different cases in quantities.jl, `* / // fma` etc. Which ones are supposed to propagate `Q` and which ones are supposed to promote to `Quantity`? I'm not sure. Maybe mp-units has the answer.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.