JuliaPhysics / JuliaPhysics/Unitful.jl

`AbstractQuantity` subtypes and quantity kinds

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

![image](https://github.com/PainterQubits/Unitful.jl/assets/96840304/7214686d-e022-454e-b50a-255e89610850)

### 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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.