Native Python support for units?
Native Python support for units?
Posted Jul 14, 2022 7:37 UTC (Thu) by taladar (subscriber, #68407)In reply to: Native Python support for units? by k8to
Parent article: Native Python support for units?
Posted Jul 14, 2022 8:07 UTC (Thu)
by farnz (subscriber, #17727)
[Link] (2 responses)
That's an important point. There are two uses of units in a program:
The first is very Pythonic in nature - the second amounts to a static type system for units, and I'm not sure how that fits in with the dynamic typing Python prefers.
Posted Jul 15, 2022 19:09 UTC (Fri)
by NYKevin (subscriber, #129325)
[Link]
The problem with the existing support is that, for example, [length] + [length] should be of type [length], but if you try to do that with NewType, you just get back float or int (types aren't preserved across binary operations). That's fixable for addition and subtraction relatively easily (define and type hint appropriate dunder methods), but it would be more complicated in the case of multiplication and division, because Python's generics are insufficiently advanced to support e.g. [length] / [time] = [speed]. You could hard-code all of those conversions one at a time, and perhaps generate the code somehow, but a lot of fundamental constants have weird units that wouldn't necessarily have a "standard" interpretation, such as the Boltzmann constant ([length]^2 * [mass] * [time]^-2 * [temperature]^-1), and it would not be fun to hard code those as well.
Ideally, a unit library should allow you to multiply and divide whatever by whatever and just make sense of it, but that would require the ability to put non-type arguments into Python's generics. Then we could express the Boltzmann constant's type as something like Quantity[2, 1, -2, 0, -1, 0, 0], where each number indicates the exponent of a given unit. Right now, Python does not let you do that (to the best of my understanding), because the arguments have to be types, not integers.
However, this also raises more philosophical problems. There are seven base units in the SI system, so one might assume that Quantity should have a fixed arity of seven exponents. However, the SI system doesn't cover many commonly-used units, such as bytes. There are also logarithmic units such as the bel (or decibel) and the cent (used in music theory, not to be confused with various currencies), which are subject to more complicated coherence rules than typical (linear) units. And the radian is officially a derived unit of the form m/m (so that the equation s=rθ) is valid, but that would just simplify to dimensionless unless you special-case it somehow (the steradian has the same problem).
Posted Jul 24, 2022 23:41 UTC (Sun)
by pdundas (guest, #15203)
[Link]
Interestingly you can *multiply* or *divide* distance and time, giving a quantity with a complex unit - speed might be 5m/30s (or 10m/minute, or some other number in furlongs per microfortnight). All kinds of weird and wonderful composite units are available - as some posters mentioned earlier. Or consider electrical units - Amps are Coulombs per second, Volts are Joules per Coulomb, and Watts are Joules per second - or something like that - it's been a while. Which raises interesting possibilities for *display* of numbers with units attached, when they need to be scaled, or converted between families of units that measure the same thing, or expressed (as for Current) in a particular way.
As for how to do that in Pythin, I've no idea. But it's a fascinating problem.
Native Python support for units?
Native Python support for units?
Native Python support for units?