Unitful.jl: State of the units

Unitful.jl, a package for manipulating unitful quantities, has recently undergone some extensive changes on the master branch aimed at improving the defaults system and achieving compatibility with the upcoming Julia 0.6 release.

Previously, users could specify default dimensions, units, and promotion rules in a file that was ignored by git but included into package precompilation. This approach enabled full precompilation of default preferences. Moreover, if a user changed their defaults, the package would not be marked as dirty and Unitful could still be updated. However, there were a number of shortcomings:

  • Because user defaults could be modified, other packages could not rely on the existence of a particular unit; the user may have removed it or changed its meaning #33

  • Tests involving Unitful could have side effects #42

  • There was no way to have unit packages #33

  • Brittle behavior: changes to the Unitful API could lead to unexpected errors if the defaults file lagged behind recent changes

The upcoming version of Unitful will not have a user defaults file, but manages to retain similar flexibility. SI units (along with a few common internationally used units) are simply built into Unitful. You don’t have to use them if you don’t want to, but they are there. For other units, one can now develop and maintain a units package, which will be important in standardizing unit definitions and improving testing capabilities. In the latest documentation I give a prescription for how to write such a package. There is also a string macro to easily recall units from all participating units packages, without having to qualify with module names, etc.

Regarding promotion, quantities are promoted to products of base SI units when unit promotion is required (e.g. 1g*cm^2/s^2 + 1kg*m^2/s^2 + 1J will give a result with units kg*m^2/s^2). However, promotion rules can be added / overruled when Julia is launched prior to the first occurrence of any Unitful.Quantity promotion. Some commonly desired promotion rules may be optionally requested (J instead of kg*m^2/s^2, for instance)

While this is an important step forward, there remains work to be done. This update has reduced the reliance on generated functions, which were being abused in some cases, but they are still being abused with respect to how promotion is implemented. In the future, to retain flexibility and functionality, I see no alternative but to move some of the promotion logic into the type signature of quantities. This would have the upshot of potentially enabling package-specific promotion rules (e.g. a nanofab CAD package that knows to promote lengths to microns, etc.) at the expense of possible type proliferation / type signature complexity. There are also important and as-of-yet unfulfilled feature requests: unitful linear algebra, better unit simplification, etc.

All tests pass on Julia 0.5.0 and on 0.6.0-dev. Feedback is welcome. After some time passes, I’ll tag a new release. To be safe, I suggest you back up your old Defaults.jl file first if you are an existing user.

16 Likes