python-peps/pep-0239/index.html

249 lines
16 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 239 Adding a Rational Type to Python | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0239/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 239 Adding a Rational Type to Python | peps.python.org'>
<meta property="og:description" content="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 rationa...">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0239/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="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 rationa...">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 239</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 239 Adding a Rational Type to Python</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Christopher A. Craig &lt;python-pep&#32;&#97;t&#32;ccraig.org&gt;, Moshe Zadka &lt;moshez&#32;&#97;t&#32;zadka.site.co.il&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Formally declined and will not be accepted">Rejected</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">11-Mar-2001</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.2</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even">16-Mar-2001</dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#rationaltype">RationalType</a></li>
<li><a class="reference internal" href="#the-rational-builtin">The rational() Builtin</a></li>
<li><a class="reference internal" href="#open-issues">Open Issues</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<div class="pep-banner sticky-banner deprecated rejected admonition warning">
<p class="admonition-title">Warning</p>
<p>This PEP has been rejected.</p>
<p class="close-button">×</p>
<p>The needs outlined in the rationale section
have been addressed to some extent by the acceptance of <a class="pep reference internal" href="../pep-0327/" title="PEP 327 Decimal Data Type">PEP 327</a>
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 <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a>.</p>
<p><em>Postscript:</em> With the acceptance of <a class="pep reference internal" href="../pep-3141/" title="PEP 3141 A Type Hierarchy for Numbers">PEP 3141</a>, “A Type Hierarchy
for Numbers”, a Rational numeric abstract base class was added
with a concrete implementation in the fractions module.</p>
<p></p>
</div>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>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 <a class="pep reference internal" href="../pep-0240/" title="PEP 240 Adding a Rational Literal to Python">another PEP</a>.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>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.</p>
</section>
<section id="rationaltype">
<h2><a class="toc-backref" href="#rationaltype" role="doc-backlink">RationalType</a></h2>
<p>There will be a new numeric type added called <code class="docutils literal notranslate"><span class="pre">RationalType</span></code>. Its
unary operators will do the obvious thing. Binary operators will
coerce integers and long integers to rationals, and rationals to
floats and complexes.</p>
<p>The following attributes will be supported: <code class="docutils literal notranslate"><span class="pre">.numerator</span></code> and
<code class="docutils literal notranslate"><span class="pre">.denominator</span></code>. The language definition will promise that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">r</span><span class="o">.</span><span class="n">denominator</span> <span class="o">*</span> <span class="n">r</span> <span class="o">==</span> <span class="n">r</span><span class="o">.</span><span class="n">numerator</span>
</pre></div>
</div>
<p>that the GCD of the numerator and the denominator is 1 and that
the denominator is positive.</p>
<p>The method <code class="docutils literal notranslate"><span class="pre">r.trim(max_denominator)</span></code> will return the closest
rational <code class="docutils literal notranslate"><span class="pre">s</span></code> to <code class="docutils literal notranslate"><span class="pre">r</span></code> such that <code class="docutils literal notranslate"><span class="pre">abs(s.denominator)</span> <span class="pre">&lt;=</span> <span class="pre">max_denominator</span></code>.</p>
</section>
<section id="the-rational-builtin">
<h2><a class="toc-backref" href="#the-rational-builtin" role="doc-backlink">The rational() Builtin</a></h2>
<p>This function will have the signature <code class="docutils literal notranslate"><span class="pre">rational(n,</span> <span class="pre">d=1)</span></code>. <code class="docutils literal notranslate"><span class="pre">n</span></code> and <code class="docutils literal notranslate"><span class="pre">d</span></code>
must both be integers, long integers or rationals. A guarantee is
made that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rational</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">*</span> <span class="n">d</span> <span class="o">==</span> <span class="n">n</span>
</pre></div>
</div>
</section>
<section id="open-issues">
<h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2>
<ul>
<li>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.</li>
<li>Should a rational number with an integer value be allowed as a
sequence index? For example, should <code class="docutils literal notranslate"><span class="pre">s[5/3</span> <span class="pre">-</span> <span class="pre">2/3]</span></code> be equivalent
to <code class="docutils literal notranslate"><span class="pre">s[1]</span></code>?</li>
<li>Should <code class="docutils literal notranslate"><span class="pre">shift</span></code> and <code class="docutils literal notranslate"><span class="pre">mask</span></code> operators be allowed for rational numbers?
For rational numbers with integer values?</li>
<li>Marcin Qrczak Kowalczyk summarized the arguments for and
against unifying ints with rationals nicely on c.l.py<p>Arguments for unifying ints with rationals:</p>
<ul class="simple">
<li>Since <code class="docutils literal notranslate"><span class="pre">2</span> <span class="pre">==</span> <span class="pre">2/1</span></code> and maybe <code class="docutils literal notranslate"><span class="pre">str(2/1)</span> <span class="pre">==</span> <span class="pre">'2'</span></code>, it reduces surprises
where objects seem equal but behave differently.</li>
<li><code class="docutils literal notranslate"><span class="pre">/</span></code> can be freely used for integer division when I <em>know</em> that
there is no remainder (if I am wrong and there is a remainder,
there will probably be some exception later).</li>
</ul>
<p>Arguments against:</p>
<ul class="simple">
<li>When I use the result of <code class="docutils literal notranslate"><span class="pre">/</span></code> as a sequence index, its usually
an error which should not be hidden by making the program
working for some data, since it will break for other data.</li>
<li>(this assumes that after unification int and rational would be
different types:) Types should rarely depend on values. Its
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.</li>
<li>(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 dont accept
rationals. Its natural to think about them as about different
types.</li>
</ul>
</li>
</ul>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id2" role="doc-footnote">
<dt class="label" id="id2">[<a href="#id1">1</a>]</dt>
<dd>Raymond Hettinger, Propose rejection of PEPs 239 and 240 a builtin
rational type and rational literals
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2005-June/054281.html">https://mail.python.org/pipermail/python-dev/2005-June/054281.html</a></aside>
</aside>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0239.rst">https://github.com/python/peps/blob/main/peps/pep-0239.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0239.rst">2024-04-14 20:08:31 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#rationaltype">RationalType</a></li>
<li><a class="reference internal" href="#the-rational-builtin">The rational() Builtin</a></li>
<li><a class="reference internal" href="#open-issues">Open Issues</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0239.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>