[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