[Python-ideas] SI scale factors in Python
Steven D'Aprano
steve at pearwood.info
Fri Aug 26 11:35:18 EDT 2016
On Fri, Aug 26, 2016 at 02:49:51PM +0300, Ivan Levkivskyi wrote:
> 1. By defining __mul__ and __truediv__ on m, s, and other units one can
> achieve the desirable semantics
I'm not entirely sure about that. I'm not even close to an expert on the
theory of types, so I welcome correction, but it doesn't seem reasonable
to me to model units as types. Or at least not using a standard type
checker. ("Define standard," I hear you ask. Um, the sort of type
checker that Lingxiao Jiang and Zhendong Su had in mind when they wrote
Osprey?)
http://web.cs.ucdavis.edu/~su/publications/icse06-unit.pdf
Okay, so you certainly can do dimensional analysis with *some*
type-checkers. But should you?
I think that units are orthogonal to types: I can have a float of unit
"gram" and a Fraction of unit "gram", and they shouldn't necessarily be
treated as the same type.
Likewise I can have a float of unit "gram" and a float of unit "inch",
and while they are the same type, they aren't the same dimension. So I
think that you need *two* distinct checkers, one to check types, and one
to check dimensions (and do unit conversions), even if they're both
built on the same or similar technologies.
Another issue is that a decent dimensional system should allow the user
to create their own dimensions, not just their own units. The seven
standard SI dimensions are a good starting point, but there are
applications where you may want more, e.g. currency, bits are two common
ones. And no, you (probably) don't want bits to be a dimensionless
number: it makes no sense to add "7 bits" and "2 radians".
Your application may want to track "number of cats" and "number of dogs"
as separate dimensions, rather than treat both as dimensionless
quantities. And then use the type-checker to ensure that they are both
ints, not floats.
> 2. Arbitrary (reasonable) unit can be described by a tuple of 7 rational
> numbers
> (powers of basic SI units, m/s will be e.g. (1, -1, 0, 0, 0, 0, 0)), if one
> wants also
> non SI units, then there will be one more float number in the tuple.
A decent unit converter/dimension analyser needs to support arbitrary
dimensions, not just the seven SI dimensions. But let's not get bogged
down with implementation details.
> 3. It is impossible to write down all the possible overloads for operations
> on units,
> e.g. 1 m / 1 s should be 1 m/s, 1 m/s / 1 s should be 1 m/s**2,
> and so on to infinity. Only finite number of overloads can be described
> with PEP 484 type hints.
Right. This is perhaps why the authors of Osprey say that
"standard type checking algorithms are not powerful enough to handle
units because of their abelian group nature (e.g., being commutative,
multiplicative, and associative)."
Another factor: dimensions should support rational powers, not just
integer powers.
--
Steve
More information about the Python-ideas
mailing list