Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

1 participant