# Typed Units instead of parameterized (Unitful) or exponent-tracking (DynamicQuantities)?

**URL:** <https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735>\
**Category:** General Usage\
**Tags:** question, unitful\
**Created:** [November 2, 2023, 10:31pm UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735 "2023-11-02T22:31:17Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![bcon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcon/32/23495_2.png) [@bcon](https://discourse.julialang.org/u/bcon)\
**Post date:** [November 2, 2023, 10:31pm UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/1 "2023-11-02T22:31:17Z")

</div>

Adding units to a package greatly obfuscates error messages, slowing development. _If you share this annoyance_ I’d appreciate your thoughts on a package, ‘UnitTypes’, that simply treats units as types. The package would

- define SI / common units as Julia types [::Meter, ::MilliMeter, …]
- define an abstract type tree to relate units [Meter \<: AbstractExtent] and facilitate conversion
- define convert(),promote(), for each type…just as you normally do
- provide a macro to introduce new types

I haven’t seen this done; the closest are comments about it being laborious to manually define the whole type tree. I have used Unitful.jl widely enough to be annoyed at it, and while [DynamicQuantities](https://discourse.julialang.org/t/unitful-jl-without-parametrizing-types-on-units/99869) is an improvement, it was motivated by an all-encompassing type, which is what I’d like to avoid.

Thanks

---

<div class="post-metadata">

**Author:** ![cgarling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgarling/32/29278_2.png) [@cgarling](https://discourse.julialang.org/u/cgarling)\
**Post date:** [November 2, 2023, 10:52pm UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/2 "2023-11-02T22:52:40Z")

</div>

What do you see as the downside of the “all-encompassing type” design of DynamicQuantities? I read their release pitch but haven’t had occasion to try it yet.

It’s somewhat unclear to me how derived units would work; i.e. if you have a value of type ::Meter and divide it by a value of type ::Second, is the result a unique type, like ::MeterperSecond? Would all such derived units require definition at time-of-writing, or would they be generated or something like that?

I often work with values that represent physical units and most of the time I don’t use unit packages because I find the gain in ease-of-use initially is offset by development being more complicated down the road. So in general I am interested in improvements to the unit ecosystem.

---

<div class="post-metadata">

**Author:** ![bcon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcon/32/23495_2.png) [@bcon](https://discourse.julialang.org/u/bcon)\
**Post date:** [November 3, 2023, 12:52am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/3 "2023-11-03T00:52:10Z")

</div>

In functions requiring a certain unit type; the second call should error but succeeds:

```julia
calculateDistance(a::typeof(1u"m")) = a*2
@show calculateDistance(1u"m")
@show calculateDistance(1u"s")

> calculateDistance(1 * u"m") = 2.0 m
> calculateDistance(1 * u"s") = 2.0 s

```

(I didn’t see how to properly assert a type in DynamicQuantities)

Whereas Unitful:

```julia
using Unitful
calculateDistance(a::Unitful.Length) = 3*a
@show calculateDistance(1u"ft")
@show calculateDistance(1u"s")

> calculateDistance(1 * u"ft") = 3 ft

> ERROR: MethodError: no method matching calculateDistance(::Unitful.Quantity{Int64, 𝐓 , Unitful.FreeUnits{(s,), 𝐓 , nothing}})

Closest candidates are:
  calculateDistance(::Union{Unitful.Quantity{T, 𝐋, U}, Unitful.Level{L, S, Unitful.Quantity{T, 𝐋, U}} where {L, S}} where {T, U})

```

correctly complains that seconds were given instead of Unitful.Length, but the error message requires knowing Unitful’s type design in order to locate the problem and the verbosity of the closest candidate is even worse.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [November 3, 2023, 12:54am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/4 "2023-11-03T00:54:22Z")

</div>

Can Unitful types be simplified without other major changes to the package design? It’s a great battle-tested package, maybe `Quantity` can be implemented with just two simple parameters (underlying number type + unit)?

---

<div class="post-metadata">

**Author:** ![bcon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcon/32/23495_2.png) [@bcon](https://discourse.julialang.org/u/bcon)\
**Post date:** [November 3, 2023, 12:55am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/5 "2023-11-03T00:55:10Z")

</div>

And yes, I think written-out labels (::MeterPerSecond) are most easily implemented and straightforwardly understood, though I half recall a discussion in Unitful about providing a ‘display name’ to the error machinery, allowing ‘m/s’ to be printed instead.

---

<div class="post-metadata">

**Author:** ![bcon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcon/32/23495_2.png) [@bcon](https://discourse.julialang.org/u/bcon)\
**Post date:** [November 3, 2023, 12:58am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/6 "2023-11-03T00:58:06Z")

</div>

That’s on my experiments list, to see whether a bunch of convert()s would allow clean type assertions and errors while relying on Unitful for conversions between units. Of course I’d really like for unit conversion errors to be readable and that may prohibit including Unitful.

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 3, 2023, 12:59am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/7 "2023-11-03T00:59:35Z")

</div>

another option could be to improve the show method for `Unitful.Quantity` types?, like what was done recently with named tuples: [print NamedTuple types using the macro format by KristofferC · Pull Request #49117 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/49117)

---

<div class="post-metadata">

**Author:** ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)\
**Post date:** [November 3, 2023, 2:38am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/8 "2023-11-03T02:38:40Z")

</div>

I use units regularly in MathCad, rarely in Julia. From the user experience point of view, units are nicely handled there. I don’t know if it can be inspiration for a Julia package? I show a quick velocity calculation and then display the result with 3 different units. The default is SI with the option to use British (which I never do) and the other two are arbitrary units that I chose.

Sorry that I cannot help with the technical details of implementing this.

 ![mathcad_units](https://global.discourse-cdn.com/julialang/original/3X/a/f/afd4e78edc59bd4ccc8d0a2309abd0ebc69daf65.png)

---

<div class="post-metadata">

**Author:** ![bcon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcon/32/23495_2.png) [@bcon](https://discourse.julialang.org/u/bcon)\
**Post date:** [December 22, 2023, 1:56am UTC](https://discourse.julialang.org/t/typed-units-instead-of-parameterized-unitful-or-exponent-tracking-dynamicquantities/105735/9 "2023-12-22T01:56:53Z")

</div>

I put these ideas into [UnitTypes](https://github.com/mechanomy/UnitTypes.jl); give it a try and let me know what you think. Though I’m using this internally, expect bugs and send along any design and implementation suggestions.
