[Python-ideas] Units in type hints

Koos Zevenhoven koos.zevenhoven at aalto.fi
Fri May 15 16:00:26 CEST 2015


On 14.5.2015 14:59, Steven D'Aprano wrote:
> On Thu, May 14, 2015 at 02:03:39PM +0300, Koos Zevenhoven wrote:
>> Hi all,
>>
>> How about extending the type annotations for int, float and complex to
>> optionally include also a unit?
> I really, really like the idea of having unit-aware calculations.
>
> But this is not the way to do it. See below:
>
>

Getting something even better would of course be great. Needless to say, 
I would not be in favor of adding my first rough sketch to Python. I do 
believe that, whatever the solution, it would need to be some kind of a 
standard for it to really work. See comments below.

>> For instance,
>>
>>      def sleep(duration : Float['s']):
>>          ...
>>
>> Now the type checker could catch the error of trying to pass the sleep
>> duration in milliseconds, Float['ms'].
> But that's not an error. Calling sleep(weight_in_kilograms) is an error.

In the example I gave, it is clearly an error. And it would be an error 
with time.sleep. But you are obviously right, sleeping for kilograms is 
also an error, although a very bizarre one.

> But calling sleep(milliseconds(1000)) should be the same as calling
> sleep(seconds(1)).

Yes, something like that would be nice. What would sleep(1) do?

> If the user has to do the conversion themselves,
> that's a source of error:
>
> sleep(time_in_milliseconds / 1000)  # convert to seconds
>
> If you think that's too obvious an error for anyone to make,

You lost me now. There does not seem to be an error in the line of code 
you provided, especially not when using Python 3, which has true 
division by default. However, in what I proposed, the type checker would 
complain because you made a manual conversion without changing the unit 
hint (which is also potential source of error, and you seem to agree). 
According to my preliminary sketch, the correct way (which you did not 
quote) would be

     sleep(convert(time_in_milliseconds, 'ms', 's'))

I do think this might be unnecessarily verbose. Anyway, I was not 
proposing the 'user' should do the actual conversion calculation by hand.

> (1) you're
> wrong, I've made that error, yes even that simple, and (2) you should
> try it with more complex sets of units. How many pound-foot per minute
> squared in a newton?

There's no error so we will never find out whether I would have been 
wrong :(. But I can assure you, I have made errors in unit conversions 
too. Anyway, you did not quote the part of my email which addresses 
conversions and derived units (km/h). Regarding your example, it might 
work like this (not that I think this is optimal, though):

     convert(value, 'lb * ft / min**2', 'N')

> Having the language support unit calculations is not just to catch the
> wrong dimensions (passing a weight where a time is needed), but to
> manage unit conversions automatically without the user being responsible
> for getting the conversion right.

That would be ideal, I agree. Would that not be a really hard thing to 
introduce into the language, taking into account backwards compatibility 
and all? I intentionally proposed something less than that.

> A type checker is the wrong tool for
> the job.

At least not ideal. I do think the error of using the wrong unit is 
conceptually similar to many cases of accidentally passing something 
with the wrong type. Also, the type hints have other uses besides type 
checkers. Of course, having everything just work, without the 
user/programmer having to care, would be even better.

> If you want to see what a good unit-aware language should be capable of,
> check out:
>
> - Frink:https://futureboy.us/frinkdocs/
>
> - the HP-28 and HP-48 series of calculators;
>
> - the Unix/Linux "units" utility.
>
> There are also some existing Python libraries which do unit
> calculations. You should look into them.
>

There was also a talk at PyCon about existing libraries, but I can't 
seem to find it now. I assume some of you have seen it.

-- Koos



More information about the Python-ideas mailing list