Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

AbstractQuantity subtypes and quantity kinds #705

Open
jariji opened this issue Jan 26, 2024 · 0 comments
Open

AbstractQuantity subtypes and quantity kinds #705

jariji opened this issue Jan 26, 2024 · 0 comments

Comments

@jariji
Copy link

jariji commented Jan 26, 2024

The concept

"Defining ‘kind of quantity’" (Flater) and "On (kinds of) quantities" (Mari) 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

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,

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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant