In the previous post, I explored units as a semantic layer for calculation——the idea that numbers without units are just numbers, and that attaching dimensional meaning transforms them into something we can reason about, compose, and verify.
That post was motivated by real frustration.
At PhysIQ (acquired by Prolaio), a health tech company focused on remote patient monitoring, I worked with physiological signals where unit mismatches could silently corrupt derived metrics. At Nextera Analytics, energy trading demanded constant conversion between units of power, energy, currency, and time and the cost of getting it wrong was measured in dollars. In both environments, the same pattern repeated: someone combines two "naked numbers" that happen to be in different units, and the result is confidently wrong.
I wanted a tool that made this class of error impossible. Not a lookup table of conversion factors, but something that understood dimensional structure——that knew you can't add meters to seconds, that multiplying velocity by time yields distance, and could figure out the conversion path between units without being told every pair explicitly.
I made the first commit in 2020 and pecked at the problem over the years. The core challenge was always the same: how do you represent the relationship between units in a way that's both computationally tractable and general enough to handle the full zoo of physical (and even non-physical) dimensions?
The breakthrough came last year, when I started representing unit exponents as vectors.
A unit like m/s² becomes a vector in dimension-space: length to the first power, time to the negative second.
Multiplication of quantities becomes vector addition of their exponents.
Division becomes subtraction.
Dimensional compatibility is just checking whether two vectors are equal.
What had been a tangle of special cases collapsed into linear algebra.
The result is ucon: a unit conversion library built on this vector abstraction.
It won't just convert between units you've registered as pairs.
It's meant to derive conversion paths through dimensional analysis, catches incompatible operations at the point of combination, and treats units as first-class participants in calculation rather than afterthought annotations.
This post is just the introduction. In future posts, I'll dig into the features, the API, and the design decisions that fell out of treating units as vectors. For now, I wanted to share where this started: two industries, a lot of naked numbers, and the conviction that the type system should do more of the work.