SciNim / Unchained

A fully type safe, compile time only units library.
https://scinim.github.io/Unchained
109 stars 0 forks source link

Declarative unit definitions and unit systems #8

Open Vindaar opened 3 years ago

Vindaar commented 3 years ago

The current way to add new units is

  1. annoying
  2. verbose
  3. littered all over

Instead we need to unify the unit construction. Instead of having:

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.

c-blake commented 3 years ago

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!

c-blake commented 3 years ago

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).

c-blake commented 3 years ago

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.

Vindaar commented 3 years ago

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.

c-blake commented 3 years ago

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/.

Vindaar commented 3 years ago

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.

Vindaar commented 2 years ago

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.

Vindaar commented 2 years ago

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