Author here, thanks for posting!<p>On the Haskell Discourse [0], someone posted about another Haskell library, units [1], which allows to define unit systems NOT limited to the 7 physical dimensions. For example, adding a base dimension for currency would be nice to model electricity prices in currency per energy.<p>[0]: <a href="https://discourse.haskell.org/t/blog-post-scientific-computing-with-confidence-using-typed-dimensions/10767" rel="nofollow">https://discourse.haskell.org/t/blog-post-scientific-computi...</a><p>[1]: <a href="https://hackage.haskell.org/package/units" rel="nofollow">https://hackage.haskell.org/package/units</a>
The modeling of unit systems with types is fraught with all sorts of inconsistencies and design tradeoffs. There are quantities that have the same dimensions, but shouldn't be compared or allow arithmetic between them. Many issues with Temperature scales and how to interpret differences in these spaces.<p>I think a pretty well thought out approach to this is the mp-units library in c++ that uses the ISQ(International System of Quantities) [1].<p>There are some great blog posts on their site about modeling units systems and dimensions.
Fingers crossed it may even be added to the standard library in C++29.<p>[1]: <a href="https://mpusz.github.io/mp-units/latest/" rel="nofollow">https://mpusz.github.io/mp-units/latest/</a>
Also in Julia: <a href="https://painterqubits.github.io/Unitful.jl/stable/" rel="nofollow">https://painterqubits.github.io/Unitful.jl/stable/</a>
I have yet to see a language which does units better than F#: <a href="https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure" rel="nofollow">https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...</a> It is one of the main reasons I use F# over other functional languages.<p>Doing it within an existing type system is more trouble than it’s worth: the algebra of units is simple, but it doesn’t apply to other types without stretching the compiler. It is far easier to have a distinct subsystem with measure types specifically identified.
I will say that the OpenFOAM C++ library supports dimensions in a more user friendly way than this, with support for both vectors/matrices and for checking units when you take partial derivatives of your quantities.<p>There is even native support for reading dimensioned values from input files, so your user can specify "speed 12.7 [ft/s]" irrespective of what units you use internally in the code processing that input file. It just gets converted (or throws an error).<p>See e.g. this, from 4.2.6 onwards: <a href="https://doc.cfd.direct/openfoam/user-guide-v12/basic-file-format" rel="nofollow">https://doc.cfd.direct/openfoam/user-guide-v12/basic-file-fo...</a>
I misread this title (the word "confidence" threw me) and was initially very confused when it turned out to be about dimensional analysis instead of uncertainty.<p>But why not both? A number system with dimensions <i>and</i> which automatically propagates measurement uncertainty through calculations (a la Taylor's train wreck book) doesn't seem totally infeasible?<p>I would particularly like this for expressing cad models as code instead of brep.
I haven't had the opportunity to use this in research yet, but i liked numbat [0], as it comes with relevant common units and lets you define your own. It appeared on HN before [1].<p>[0]: <a href="https://github.com/sharkdp/numbat">https://github.com/sharkdp/numbat</a><p>[1]: <a href="https://news.ycombinator.com/item?id=38276430">https://news.ycombinator.com/item?id=38276430</a>
There is a good dimensional analysis package `ezunits` in Maxima. Very useful for working through equations and then sometimes generating the c/fortran code directly from Maxima is fine.
Would this work for something like linear algebra? Could it support multiplying two 3x3 matrices where each cell can have a different dimension, and only work if they are compatible?
Similar library for Rust providing zero cost unit safety<p><a href="https://github.com/paholg/dimensioned">https://github.com/paholg/dimensioned</a>
<p><pre><code> Two quantities with dimensions </code></pre>
D1 and D2 can only be added or subtracted if (and only if)
D1≡D2. For example, it does not make sense to add a length to a mass.<p>That’s not true though. Some units cannot be added together, for example all intensive units like speed, density, temperature etc.
This is a great article and I like that you are highlighting the benefits of Dimensions as Types.<p>While Raku is less popular than Python, it does have deep roots in Haskell and strong types (the first Raku / Perl6 parser - PUGS - was written in Haskell and all the early devs were encouraged to learn Haskell first).<p>Similar concepts are used in these Raku modules... which provide dimensional analysis and marry types to dimensions.<p>- <a href="https://raku.land/zef:librasteve/Physics::Measure" rel="nofollow">https://raku.land/zef:librasteve/Physics::Measure</a><p>- <a href="https://raku.land/zef:librasteve/Physics::Unit" rel="nofollow">https://raku.land/zef:librasteve/Physics::Unit</a><p>I had some fun with making this example of using these Raku modules with Jupyter <a href="https://rakujourney.wordpress.com/wp-content/uploads/2023/08/xkcd-solar-panel.pdf" rel="nofollow">https://rakujourney.wordpress.com/wp-content/uploads/2023/08...</a><p>[disclaimer: I am the author of these modules]<p>Raku is also good at Slangs (Sublanguages) and unicode, so these tools can be used in a very intuitive way:<p><pre><code> #!/usr/bin/env raku
use Physics::Constants;
use Physics::Measure :ALL;
say ~ℏ; #1.054571817e-34 J.s
my \λ = 2.5nm;
say "Wavelength of photon (λ) is " ~λ;
my \ν = c / λ;
say "Frequency of photon (ν) is " ~ν.in('petahertz');
my \Ep = ℎ * ν;
say "Energy of photon (Ep) is " ~Ep.in('attojoules');
Wavelength of photon (λ) is 2.5nm
Frequency of photon (ν) is 119.92PHz
Energy of photon (Ep) is 79.46aJ</code></pre>
Wolfram Language (aka Mathematica) is the best for doing scientific computing with physical unit dimensions.<p>See: <a href="https://reference.wolfram.com/language/guide/Units.html" rel="nofollow">https://reference.wolfram.com/language/guide/Units.html</a><p>> The units framework [of Wolfram Language] integrates seamlessly with visualization, numeric and algebraic computation functions. It also supports dimensional analysis, as well as purely symbolic operations on quantities.
For those coding in Swift, there is the Physical[0] package.<p>[0] <a href="https://github.com/hyperjeff/Physical">https://github.com/hyperjeff/Physical</a>
Can it also do reference frames?<p>Like if I have a cartesian coordinates in one reference frame, can I use them in a type-safe way? E.g. not add two vectors in two reference frames? Same for polar coordinates?<p>Etc.
I was so disappointed that this turned from Python to Haskell, I would just _love_ to have something like this in Python. Even just type annotations.<p>A similar thing I have been thinking about doing in robotics contexts is to annotate vectors and transformation matrices with their reference frames. So you can only matrix-vector multiply between compatible types: `object_in_world = camera_to_world @ object_in_camera`. It can be done somewhat in C++.
See also <a href="https://painterqubits.github.io/Unitful.jl/stable/" rel="nofollow">https://painterqubits.github.io/Unitful.jl/stable/</a>