I would like to propose a solution that was not discussed yet. The basis for that is this paper about a runtime unit of measure library for common lisp: https://3e8.org/pub/scheme/doc/lisp-pointers/v5i2/p21-cunis.pdf
The paper is quite short and light on detail, but i like the idea very much.
TLDR: Associate each unit with a unique prime number. Store a compound unit as a rational number. For example:
m ~ 2; s ~ 3
~>
m/s^2 ~ 2/9
Prime factorisation of the nominator and denominator yield the set of sorted base units. Equal compound units have equal rational representation as long as they are reduced. So, multiplications of the measure only requires multiplication and reduction of the rationals, addition a test of equality.
New units can be defined in a backward compatible way, but the associated prime number has to be unique.
With this as the underpining idea, i’d propose a library that provides a DynamicMeasure
and a StaticMeasure
type (all names are just stand ins). StaticMeasure checks at compile time and can be converted into a dynamic measure. Dynamic measures can be created at runtime and checks at runtime. So it’d be even possible to check user input on correctness, which is by definition impossible with compile time checking.
The representation is quite memory efficient. Its hard to list a range for nominator and denominator that is sufficient in practice, since additional units use greater primes and the compound number gets big fast, but what i found while experimenting is normal physical compounds fit into a u32, but barely. u64 should be fine for everything not extremely weird and u128 should be on the safe side. So that would mean 16-32 bytes runtime overhead per number. Should be much more acceptable than a whole hashmap.
const generics could use the same representation, which would make conversion easier. And the fixed size representation would mean no boxing.
Imo, having compile time safety with an escape hatch to defer to the runtime when necessary seems quite rusty to me.
The runtime part could be written today, the other as soon as const generics land.
Open questions:
- How to enforce prime uniqueness
- Something like a
Display
for types would be needed to show the real unit of measure in compile errors