diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index aea9a6669d3..a12efe22d51 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -1,5 +1,5 @@ PEP: 791 -Title: imath --- module for integer-specific mathematics functions +Title: intmath --- module for integer-specific mathematics functions Author: Sergey B Kirpichev Sponsor: Victor Stinner Discussions-To: https://discuss.python.org/t/92548 @@ -8,7 +8,6 @@ Type: Standards Track Created: 12-May-2025 Python-Version: 3.15 Post-History: `12-Jul-2018 `__, - 02-Jun-2019, `09-May-2025 `__, `19-May-2025 `__, @@ -35,10 +34,10 @@ when explicitly noted otherwise, all return values are floats." This is no longer true: *None* of the functions listed in the `Number-theoretic functions `_ subsection of the documentation return a float, but the -documentation doesn't say so. In the documentation for the proposed ``imath`` module the sentence "All +documentation doesn't say so. In the documentation for the proposed ``intmath`` module the sentence "All return values are integers." would be accurate. In a similar way we can simplify the description of the accepted arguments for functions in both the -:external+py3.14:mod:`math` and the new module. +new module and in :external+py3.14:mod:`math`. Apparently, the :external+py3.14:mod:`math` module can't serve as a catch-all place for mathematical functions since we also have the :external+py3.14:mod:`cmath` and @@ -53,12 +52,55 @@ comparable with the :external+py3.14:mod:`cmath` (1340LOC), which is *not* a simple wrapper to the ``libm``, as most functions in the :external+py3.14:mod:`math` module. +And this situation tends to get worse. When the module split `was first +proposed +`_, +there were only two integer-related functions: +:external+py3.14:func:`~math.factorial` and :external+py3.14:func:`~math.gcd`. +Now there are six and :external+py3.14:func:`~math.factorial` doesn't accept +:class:`float`'s anymore. + +Some possible additions, among those proposed in the initial discussion thread +and issue +`python/cpython#81313 `_ are: + +* ``ceil_div()`` --- for integer ceiling divide, see + `relevant discussion thread `_. +* ``gcdext()`` --- to solve linear `Diophantine equation `_ in two variables (the + :external+py3.14:class:`int` implementation actually includes an extended + Euclidean algorithm) +* ``isqrt_rem()`` --- to return both an integer square root and a remainder (which is non-zero only if + the integer isn't a perfect square) +* ``ilog()`` --- integer logarithm, :external+py3.14:func:`math.log` + has special handling for integer arguments. It's unique (with respect to other module + functions) and not documented so far, see issue + `python/cpython#120950 `_. +* ``fibonacci()`` --- `Fibonacci sequence `_. + + +Rationale +========= + +Why not fix the :external+py3.14:mod:`math` module documentation instead? +Sure, we can be much more vague in the module preamble (i.e. roughly say +that "the :external+py3.14:mod:`math` module contains some mathematical +functions"), we can accurately describe input/output for each function +and it's behavior (e.g. whether the :external+py3.14:func:`~math.factorial` +output is exact or not, like e.g. the `scipy.special.factorial `_, per default). + +But the major issue is that the current module mixes different, almost non-interlaced +application domains. Adding more documentation will just highlight this and +make the issue worse for end users (more text to read/skip). And it will not +fix issue with discoverability (to know in which module to find a function, and +that it can be found at all, you need to look at all the functions in the +module), nor with tab-completion. + Specification ============= The PEP proposes moving the following integer-related functions to a new -module, called ``imath``: +module, called ``intmath``: * :external+py3.14:func:`~math.comb` * :external+py3.14:func:`~math.factorial` @@ -74,9 +116,21 @@ Module functions will accept integers and objects that implement the object to an integer number. Suitable functions must be computed exactly, given sufficient time and memory. -Possible extensions for the new module and its scope are discussed in the -`Open Issues `_ section. New functions are not part of this -proposal. + +Possible Extensions +=================== + +New functions (like mentioned in `Motivation `_ section) are not +part of this proposal. + +Though, we should mention that, unless we can just provide bindings to some +well supported mathematical library like the GMP, the module scope should be +limited. For example, no primality testing and factorization, as +production-quality implementatons will require a decent mathematical background +from contributors and belongs rather to specialized libraries. + +When proposed function already exists in the :pypi:`gmpy2`, we should prefer a +compatible interface for the stdlib. Backwards Compatibility @@ -107,60 +161,25 @@ Reference Implementation `python/cpython#133909 `_ -Open Issues -=========== +Rejected ideas +============== Module name ----------- -The chosen name seems consistent with one existing domain-specific mathematical module: -:external+py3.14:mod:`cmath` (for complex numbers). - -We note the `Imath -`_ C++ library includes -Python bindings with the same name. There is also an :pypi:`imath` project on -PyPI, but only with two releases, with the most recent one four years ago. Its -repository is no longer accessible. - -`Polling showed `_ ``intmath`` as another -popular name. The argument made was that the normal mathematical spelling of -the imaginary unit is ``i``, which makes ``imath`` ambiguous. It also has no conflict -with any PyPI module. On the other hand, ``intmath`` may be confused with -interval math or numerical integration. +`Polling showed `_ ``intmath`` as most +popular candidate with ``imath`` as a second winner. Other proposed names include ``ntheory`` (like SymPy's submodule), -``integermath`` and ``imaths``. - +``integermath``, ``zmath``, ``dmath`` and ``imaths``. -Module scope and possible extensions ------------------------------------- - -Unless we can just provide bindings to some well supported mathematical library -like the GMP, the module scope should be limited. For example, no primality -testing and factorization, as production-quality implementatons will require a -decent mathematical background from contributors and belongs rather to -specialized libraries. - -Some possible additions, among those proposed in the initial discussion thread -(see also issue -`python/cpython#81313 `_): - -* ``ceil_div()`` --- for integer ceiling divide, see - `relevant discussion thread `_. -* ``gcdext()`` --- to solve linear `Diophantine equation `_ in two variables (the - :external+py3.14:class:`int` implementation actually includes an extended - Euclidean algorithm) -* ``isqrt_rem()`` --- to return both an integer square root and a remainder (which is non-zero only if - the integer isn't a perfect square) -* ``ilog()`` --- integer logarithm, :external+py3.14:func:`math.log` - has special handling for integer arguments. It's unique (with respect to other module - functions) and not documented so far, see issue - `python/cpython#120950 `_. -* ``fibonacci()`` --- `Fibonacci sequence `_. +As a variant, the new module can be added as a submodule of the +:external+py3.14:mod:`math`: ``integer`` (most preferred), ``discrete`` +or ``ntheory``. -Rejected ideas -============== +:external+py3.14:func:`~math.isqrt` renaming +--------------------------------------------- There was a brief discussion about exposing :external+py3.14:func:`math.isqrt` as ``imath.sqrt`` in the same way that :external+py3.14:func:`cmath.sqrt` is