Unitful.jl icon indicating copy to clipboard operation
Unitful.jl copied to clipboard

How to dispatch on molar mass?

Open ejmeitz opened this issue 2 years ago โ€ข 4 comments

Hello,

I'd like to differentiate my functions based on if the user provided a Mass dimension or a molar mass dimension. Unitful already has the Unitful.Mass to make it easy to dispatch on mass but I've been majorly struggling to dispatch on molar mass. My attempt is below:

molar_mass_unit = Unitful.Dimensions{(Unitful.Dimension{:Mass}(1//1), Unitful.Dimension{:Amount}(-1//1))}
function f(a::Unitful.Quantity{T, molar_mass_unit, U}) where {T,U}
       println("molar mass function")
end

I also tried using

 molar_mass_unit = Unitful.Dimensions{(Unitful.๐Œ,Unitful.๐^-1)}

ejmeitz avatar Jul 09 '23 00:07 ejmeitz

Ok like 50th thing I tried worked but I still don't get why the above doesn't.

If I define @derived_dimension MolarMass ๐Œ/๐ true I can just use MolarMass. I also created a PR to add this as one of the default derived units.

ejmeitz avatar Jul 09 '23 00:07 ejmeitz

My attempt is below:

molar_mass_unit = Unitful.Dimensions{(Unitful.Dimension{:Mass}(1//1), Unitful.Dimension{:Amount}(-1//1))}
function f(a::Unitful.Quantity{T, molar_mass_unit, U}) where {T,U}
       println("molar mass function")
end

This doesnโ€™t work for two reasons:

  1. The second type parameter must be an instance of a Dimensions type, not a type itself (i.e., molar_mass_unit() instead of molar_mass_unit)
  2. Unitful uses a canonical ordering of the dimensions in the Dimensions type parameter. A value of 1u"kg/mol" (and any other quantity or unit of molar mass) has dimension
    julia> typeof(dimension(1u"kg/mol"))
    Unitful.Dimensions{(Unitful.Dimension{:Amount}(-1//1), Unitful.Dimension{:Mass}(1//1))}
    
    As you can see, the order of the dimensions is switched compared to your attempt. Thatโ€™s why it doesnโ€™t work.

I also tried using

molar_mass_unit = Unitful.Dimensions{(Unitful.๐Œ,Unitful.๐^-1)}

This doesnโ€™t work because Unitful.๐Œ and Unitful.๐ are already instances of the type Unitful.Dimensions, not Unitful.Dimension. The following works:

molar_mass_unit = Unitful.๐Œ * Unitful.๐^-1

sostock avatar Jul 12 '23 10:07 sostock

We should have better documentation for this. I think we should

  1. Feature @derived_dimension more prominently in the manual.
  2. Improve the part of the Quantity docstring which explains that D is an instance while U is a type:

    The type parameters D :: Unitful.Dimensions and U <: Unitful.Units.

sostock avatar Jul 12 '23 10:07 sostock

Yeah definitely add another example to the dispatch part. Its a super useful and cool feature.

ejmeitz avatar Jul 12 '23 12:07 ejmeitz