|
| 1 | +PEP: 791 |
| 2 | +Title: imath --- module for number-theoretic functions |
| 3 | +Author: Sergey B Kirpichev <skirpichev@gmail.com> |
| 4 | +Sponsor: Victor Stinner <vstinner@python.org> |
| 5 | +Discussions-To: Pending |
| 6 | +Status: Draft |
| 7 | +Type: Standards Track |
| 8 | +Created: 10-May-2025 |
| 9 | +Python-Version: 3.15 |
| 10 | +Post-History: 02-Jun-2019, |
| 11 | + `09-May-2025 <https://discuss.python.org/t/91337>`__, |
| 12 | + |
| 13 | + |
| 14 | +Abstract |
| 15 | +======== |
| 16 | + |
| 17 | +This PEP proposes a new module for number-theoretical, combinatorial and other |
| 18 | +integer-valued functions defined for integer arguments, like |
| 19 | +:external+py3.14:func:`math.gcd` or :external+py3.14:func:`math.isqrt`. |
| 20 | + |
| 21 | + |
| 22 | +Motivation |
| 23 | +========== |
| 24 | + |
| 25 | +The :external+py3.14:mod:`math` documentation says: "This module provides access |
| 26 | +to the mathematical functions defined by the C standard." But as a state of |
| 27 | +art, over time the module was populated with functions that aren't related to |
| 28 | +the C standard or floating-point arithmetics. Now it's much harder to describe |
| 29 | +module scope, content and interfaces (returned values or accepted arguments). |
| 30 | + |
| 31 | +For example, the :external+py3.14:mod:`math` module documentation says: "Except |
| 32 | +when explicitly noted otherwise, all return values are floats." This is not |
| 33 | +longer true: *None* of the functions listed in the "Number-theoretic |
| 34 | +functions" [1]_ subsection of the documentation returns a float, but the |
| 35 | +documentation doesn't say so. In the proposed module a similar sentence "All |
| 36 | +return values are integers." could tell the truth once. In a similar way we |
| 37 | +can simplify description of accepted arguments for both the |
| 38 | +:external+py3.14:mod:`math` and the new module. |
| 39 | + |
| 40 | +Apparently, the :external+py3.14:mod:`math` can't serve as a catch-all place |
| 41 | +for mathematical functions: we have also the :external+py3.14:mod:`cmath` and |
| 42 | +the :external+py3.14:mod:`statistics`. Let's make same for integer-related |
| 43 | +functions. It would provide shared context, which reduces verbosity in the |
| 44 | +documentation and conceptual load. It also aids discoverability through |
| 45 | +grouping related functions and IDEs suggesting helpful completions. |
| 46 | + |
| 47 | + |
| 48 | +Specification |
| 49 | +============= |
| 50 | + |
| 51 | +The PEP proposes moving the following integer-related functions [1]_ in a new |
| 52 | +module, called ``imath``: |
| 53 | + |
| 54 | +* :external+py3.14:func:`~math.comb` |
| 55 | +* :external+py3.14:func:`~math.factorial` |
| 56 | +* :external+py3.14:func:`~math.gcd` |
| 57 | +* :external+py3.14:func:`~math.isqrt` |
| 58 | +* :external+py3.14:func:`~math.lcm` |
| 59 | +* :external+py3.14:func:`~math.perm` |
| 60 | + |
| 61 | +Their aliases in :external+py3.14:mod:`math` will be :term:`soft deprecated`. |
| 62 | + |
| 63 | +Modules functions will accept integers and objects that implement the |
| 64 | +:external+py3.14:meth:`~object.__index__` method which is used to convert the |
| 65 | +object to an integer number. |
| 66 | + |
| 67 | +Possible extensions for the new module and it's scope are discussed in the |
| 68 | +`Open Issues <Open Issues_>`_ section. New functions are not part of the |
| 69 | +proposal. |
| 70 | + |
| 71 | + |
| 72 | +Backwards Compatibility |
| 73 | +======================= |
| 74 | + |
| 75 | +As aliases in :external+py3.14:mod:`math` will be kept for indefinite time |
| 76 | +(their use would be discouraged), there are no anticipated code breaks. |
| 77 | + |
| 78 | + |
| 79 | +Reference Implementation |
| 80 | +======================== |
| 81 | + |
| 82 | +https://github.com/python/cpython/pull/133909 |
| 83 | + |
| 84 | + |
| 85 | +Open Issues |
| 86 | +=========== |
| 87 | + |
| 88 | +Module name |
| 89 | +----------- |
| 90 | + |
| 91 | +Chosen name seems consistent with other domain-specific mathematical module: |
| 92 | +:external+py3.14:mod:`cmath` (for complex numbers). |
| 93 | + |
| 94 | +There is already an ``imath`` project on PyPI, but only with two releases, with |
| 95 | +the most recent one 4 years ago. Its repository is no longer accessible. |
| 96 | +The `Imath <https://github.com/AcademySoftwareFoundation/Imath>`_ C++ library |
| 97 | +include Python bindings with same name. |
| 98 | + |
| 99 | +`Polling shows <https://discuss.python.org/t/91337/35>`_ ``intmath`` as another |
| 100 | +popular name. The argument made was that the normal mathematical spelling of |
| 101 | +the imaginary unit is ``i``, which makes imath ambiguous. It also has no conflict |
| 102 | +with any PyPI module. On the other hand, ``intmath`` may be confused with |
| 103 | +interval math or numerical integration. |
| 104 | + |
| 105 | +Other proposed names include ``ntheory`` (like SymPy's submodule), |
| 106 | +``integermath`` and ``imaths``. |
| 107 | + |
| 108 | + |
| 109 | +Module scope and possible extensions |
| 110 | +------------------------------------ |
| 111 | + |
| 112 | +Unless we can just provide bindings to some well supported mathematical library |
| 113 | +like the GMP, the module scope should be limited. For example, no primality |
| 114 | +testing and factorization. |
| 115 | + |
| 116 | +There are possible additions, among proposed in the initial discussion thread |
| 117 | +(see also [5]_): |
| 118 | + |
| 119 | +* ``c_div()`` --- for integer ceiling divide, see [2]_, [3]_. |
| 120 | +* ``gcdext()`` --- to solve linear Diophantine equation in two variables (the |
| 121 | + :external+py3.14:class:`int` implementation actually include extended |
| 122 | + Euclidean algorithm) |
| 123 | +* ``isqrt_rem()`` --- to return both integer square root and a remainder (if |
| 124 | + integer isn't a perfect square) |
| 125 | +* ``ilog()`` --- integer logarithm, currently :external+py3.14:func:`math.log` |
| 126 | + has a special handling for integer arguments. It's unique (wrt other module |
| 127 | + functions) and not documented so far, see [4]_ |
| 128 | +* ``fibonacci()``. |
| 129 | + |
| 130 | + |
| 131 | +Rejected ideas |
| 132 | +============== |
| 133 | + |
| 134 | +There was a brief discussion about exposing :external+py3.14:func:`math.isqrt` |
| 135 | +as ``imath.sqrt`` in the same way that :external+py3.14:func:`cmath.sqrt` is |
| 136 | +the complex version of :external+py3.14:func:`math.sqrt`. However, ``isqrt`` |
| 137 | +is ultimately a different function: it is the floor of the square root. It |
| 138 | +would be confusing to give it the same name (under a different module). |
| 139 | + |
| 140 | + |
| 141 | +Acknowledgements |
| 142 | +================ |
| 143 | + |
| 144 | +Thanks to Tim Peters for reviving the idea of the :external+py3.14:mod:`math` |
| 145 | +splitting. Thanks to Neil Girdhar for substantial improvements of |
| 146 | +the initial draft. |
| 147 | + |
| 148 | + |
| 149 | +Footnotes |
| 150 | +========= |
| 151 | + |
| 152 | +.. [1] Number-theoretic functions |
| 153 | + (https://docs.python.org/3.14/library/math.html#number-theoretic-functions) |
| 154 | +.. [2] Integer ceiling divide |
| 155 | + (https://discuss.python.org/t/91269) |
| 156 | +.. [3] https://gmpy2.readthedocs.io/en/stable/mpz.html#gmpy2.c_div |
| 157 | +.. [4] https://github.com/python/cpython/issues/120950 |
| 158 | +.. [5] https://github.com/python/cpython/issues/81313 |
| 159 | +
|
| 160 | +
|
| 161 | +Copyright |
| 162 | +========= |
| 163 | + |
| 164 | +This document is placed in the public domain or under the |
| 165 | +CC0-1.0-Universal license, whichever is more permissive. |
0 commit comments