Unchained
Unchained copied to clipboard
Declarative unit definitions and unit systems
The current way to add new units is
- annoying
- verbose
- littered all over
Instead we need to unify the unit construction. Instead of having:
- units defined as full name
- units defined as short name (alias)
- unit as element in
UnitKind
- string parsing helper based on each
UnitKind
- conversion factor based on
UnitKind
- mapping to base unit
- mapping to quantitý
- mapping to base type
We need to auto generate all this based on some macro. Essentially thinking about something like this:
declareUnit:
name: Meter
short: m
quant: Length
declareUnit:
name: Inch
short: inch # cannot use `in`
quant: Length
conv: Inch -> 2.54.cm
declareUnit:
name: Newton
short: N
quant: Force
comp: KiloGram•Meter•Second⁻²
where the fact that Meter
does not define a conversion conv
means it's a base unit. Newton
is neither a base unit as it provides its description in form of a compound of base units.
This allows to put another layer on top, namely one of full unit systems. So that we can have one set of SI units, another for CGS, imperial, .... With some helpers we can then even autogenerate conversions between unit systems.
If you read about dimensional analysis, with offshoots on natural units & Planck & geometic, etc., and also the made famous by Lord Rayleigh of Why the sky is blue fame Pi Theorem then I think you will agree that there is something kind of simple, general and maybe even beautiful struggling to make its way out of the whole mess. I'm not sure what the nicest APIs are for all of this, but I trust @Vindaar!
Something I didn't see in my 3 linked references but which also bears note is that sometimes "natural units" are re-written with constants in the unit - like eV/c
for "momentum". But it would be nice if this package could put in appropriate factors for c, G, hbar, kB, etc. automagically from designators like "absolute temperature" or "acceleration" (the abstract types of physical quantities not their unit-ed concrete realizations - there are usually many fewer abstract types in active use - maybe like 30..50 EDIT: though they are formally infinite via n-th time derivatives, for example).
There is this https://www.briancseymour.com/Natural-Units/ and the github repo, btw. Not sure if you have access to a Mathematica installation as this seems to build off the builtin units package.
There is this https://www.briancseymour.com/Natural-Units/ and the github repo, btw. Not sure if you have access to a Mathematica installation as this seems to build off the builtin units package.
Thanks! No, I wasn't aware of it.
It's nice to see that the Mathematica implementation is such an ugly beast though, haha. Yeah, I can get a Mathematica license via uni. Maybe I'll install it again one of these days to play around with it.
Actually, a 280 line notebook is tiny...Lots of just structural metadata like in Jupyter notebooks (which clearly were inspired by the 1990 era Wolfram thing, though he probably swiped the idea from elsewhere). I suspect that notebook relies on the main MMa units package a lot which might have most of my proposed functionality almost there. If it helps, they have some free player/viewer https://www.wolfram.com/player/.
Oh, hahaha. I didn't even stop to consider that the Mathematica files of course aren't meant to be read in raw text. :man_facepalming:
Haven't used Mathematica in over 5 years, oops.
If it helps, they have some free player/viewer https://www.wolfram.com/player/.
Interesting, didn't know about that either.
#21 is a small step towards this. We'll start by turning the existing logic into a plug & play system for the currently defined units. Once we're there and have all building blocks in place to generate the current code from macro declarations, we can transition to a cleaner declaration syntax than currently used. And after that, we'll think about interop between different unit systems.
With #24 merged, the only thing left of this issue is giving different unit systems names and adding some interop procedures like toUnitSystem(UnitInstance, UnitSystem)
, which would perform a conversion (if compatible) of the given quantity into the equivalent base quantity of the other system. i.e.
let x = 1.kg # in SI
doAssert x.toUnitSystem(CGS) == 1000.g