PEP 239 – Adding a Rational Type to Python
- Author:
- Christopher A. Craig <python-pep at ccraig.org>, Moshe Zadka <moshez at zadka.site.co.il>
- Status:
- Rejected
- Type:
- Standards Track
- Created:
- 11-Mar-2001
- Python-Version:
- 2.2
- Post-History:
- 16-Mar-2001
Table of Contents
Abstract
Python has no numeric type with the semantics of an unboundedly precise rational number. This proposal explains the semantics of such a type, and suggests builtin functions and literals to support such a type. This PEP suggests no literals for rational numbers; that is left for another PEP.
BDFL Pronouncement
This PEP is rejected. The needs outlined in the rationale section have been addressed to some extent by the acceptance of PEP 327 for decimal arithmetic. Guido also noted, “Rational arithmetic was the default ‘exact’ arithmetic in ABC and it did not work out as expected”. See the python-dev discussion on 17 June 2005 [1].
Postscript: With the acceptance of PEP 3141, “A Type Hierarchy for Numbers”, a ‘Rational’ numeric abstract base class was added with a concrete implementation in the ‘fractions’ module.
Rationale
While sometimes slower and more memory intensive (in general, unboundedly so) rational arithmetic captures more closely the mathematical ideal of numbers, and tends to have behavior which is less surprising to newbies. Though many Python implementations of rational numbers have been written, none of these exist in the core, or are documented in any way. This has made them much less accessible to people who are less Python-savvy.
RationalType
There will be a new numeric type added called RationalType
. Its
unary operators will do the obvious thing. Binary operators will
coerce integers and long integers to rationals, and rationals to
floats and complexes.
The following attributes will be supported: .numerator
and
.denominator
. The language definition will promise that:
r.denominator * r == r.numerator
that the GCD of the numerator and the denominator is 1 and that the denominator is positive.
The method r.trim(max_denominator)
will return the closest
rational s
to r
such that abs(s.denominator) <= max_denominator
.
The rational() Builtin
This function will have the signature rational(n, d=1)
. n
and d
must both be integers, long integers or rationals. A guarantee is
made that:
rational(n, d) * d == n
Open Issues
- Maybe the type should be called rat instead of rational. Somebody proposed that we have “abstract” pure mathematical types named complex, real, rational, integer, and “concrete” representation types with names like float, rat, long, int.
- Should a rational number with an integer value be allowed as a
sequence index? For example, should
s[5/3 - 2/3]
be equivalent tos[1]
? - Should
shift
andmask
operators be allowed for rational numbers? For rational numbers with integer values? - Marcin ‘Qrczak’ Kowalczyk summarized the arguments for and
against unifying ints with rationals nicely on c.l.py
Arguments for unifying ints with rationals:
- Since
2 == 2/1
and maybestr(2/1) == '2'
, it reduces surprises where objects seem equal but behave differently. /
can be freely used for integer division when I know that there is no remainder (if I am wrong and there is a remainder, there will probably be some exception later).
Arguments against:
- When I use the result of
/
as a sequence index, it’s usually an error which should not be hidden by making the program working for some data, since it will break for other data. - (this assumes that after unification int and rational would be different types:) Types should rarely depend on values. It’s easier to reason when the type of a variable is known: I know how I can use it. I can determine that something is an int and expect that other objects used in this place will be ints too.
- (this assumes the same type for them:) Int is a good type in itself, not to be mixed with rationals. The fact that something is an integer should be expressible as a statement about its type. Many operations require ints and don’t accept rationals. It’s natural to think about them as about different types.
- Since
References
Copyright
This document has been placed in the public domain.
Source: https://github.com/python/peps/blob/main/pep-0239.txt
Last modified: 2022-01-21 11:03:51 GMT