Why Python 3?

Ian Kelly ian.g.kelly at gmail.com
Sat Apr 19 15:58:24 EDT 2014


On Sat, Apr 19, 2014 at 3:37 AM, Chris Angelico <rosuav at gmail.com> wrote:
> On Sat, Apr 19, 2014 at 7:25 PM, Ian Kelly <ian.g.kelly at gmail.com> wrote:
>> The change from / denoting "classic
>> division" to "true division" really only affects the case where both
>> operands are integers, so far as I'm aware.  If you want to divide two
>> integers and get a decimal result, then convert one or both of them to
>> decimals first; you would have needed to do the same with classic
>> division.
>
> If float were a perfect superset of int, and the only logical superset
> when you want non-integers, then it'd be fine.

Decimal is also not a perfect superset of int (although I believe it
is a superset of the intersection of int and float).  Even if it were,
I'm not sure it would be appropriate to bless Decimal in this way
either, because they have no place in Python's number type hierarchy:

>>> from decimal import Decimal
>>> from numbers import Real
>>> isinstance(Decimal('1.23'), Real)
False

> But if you're mixing
> int and Decimal, you have to explicitly convert, whereas if you're
> mixing int and float, you don't. Why is it required to be explicit
> with Decimal but not float? Of all the possible alternate types, why
> float? Only because...
>
>> As for "why float" specifically, the division __future__ import has
>> been around since 2.2, longer than either decimals or fractions.
>
> ... it already existed. There's no particular reason to up-cast to
> float, specifically, and it can cause problems with large integers -
> either by losing accuracy, or by outright overflowing.

The authors of PEP 238 expressed their hope that when a rational type
(i.e. Fraction) was implemented, it would become the result type for
true division on two integers.  I don't know why that never came to
pass; perhaps performance considerations won out.

> In Python 3, you have to say "Oh but I want my integer division to
> result in an integer":
>
> x * 10 // 5 == x * 2

Technically this says "I want the result of floor division", not "I
want the result as an integer".  If you apply the floor division
operator to a non-int type, you'll get a non-int result.  It just so
happens that the result of floor division of two integers can be given
as an integer, whereas the result of true division cannot.

Considering that Fraction and Decimal did not exist yet, what type do
you think the PEP 238 implementers should have chosen for the result
of dividing two ints?  If float is not acceptable, and int is not
acceptable (which was the whole point of the PEP), then the only
alternative I can see would have been to raise a TypeError and force
the user to upcast explicitly.  In that case, dividing arbitrary ints
using floating-point math would not be possible for those ints that
are outside the range of floats; you would get OverflowError on the
upcast operation, regardless of whether the result of division would
be within the range of a float.

> Yes, I can see that it's nice for simple interactive use.

More importantly, it's useful for implementers of generic mathematical
routines.  If you're passed arbitrary inputs, you don't have to check
the types of the values you were given and then branch if both of the
values you were about to divide happened to be ints just because the
division operator arbitrarily does something different on ints.



More information about the Python-list mailing list