[Python-Dev] Numeric PEPs

Moshe Zadka moshez@zadka.site.co.il
Sun, 11 Mar 2001 17:19:44 +0200 (IST)


Trying once again for the sought after position of "most PEPs on the
planet", here are 3 new PEPs as discussed on the DevDay. These PEPs
are in a large way, taking apart the existing PEP-0228, which served
its strawman (or pie-in-the-sky) purpose well.

Note that according to PEP 0001, the discussion now should be focused
on whether these should be official PEPs, not whether these are to
be accepted. If we decide that these PEPs are good enough to be PEPs
Barry should check them in, fix the internal references between them.
I would also appreciate setting a non-Yahoo list (either SF or python.org)
to discuss those issues -- I'd rather discussion will be there rather
then in my mailbox -- I had bad experience regarding that with PEP-0228.

(See Barry? "send a draft" isn't that scary. Bet you don't like me to
tell other people about it, huh?)

PEP: XXX
Title: Unifying Long Integers and Integers
Version: $Revision$
Author: pep@zadka.site.co.il (Moshe Zadka)
Status: Draft
Python-Version: 2.2
Type: Standards Track
Created: 11-Mar-2001
Post-History:


Abstract

    Python has both integers, machine word size integral types, and long 
    integers, unbounded integral types. When integers operations overflow,
    the machine registers, they raise an error. This proposes to do away
    with the distinction, and unify the types from the prespective of both
    the Python interpreter, and the C API.

Rationale

    Having the machine word size leak to the language hinders portability
    (for examples, .pyc's are not portable because of that). Many programs
    find a need to deal with larger numbers after the fact, and changing the
    algorithms later is not only bothersome, but hinders performance on the
    normal case.

Literals

    A trailing 'L' at the end of an integer literal will stop having any
    meaning, and will be eventually phased out. This will be done using
    warnings when encountering such literals. The warning will be off by
    default in Python 2.2, on by default for two revisions, and then will
    no longer be supported.

Builtin Functions

    The function long will call the function int, issuing a warning. The
    warning will be off in 2.2, and on for two revisions before removing
    the function. A FAQ will be added that if there are old modules needing
    this then

         long=int

    At the top would solve this, or

         import __builtin__
         __builtin__.long=int

    In site.py.

C API

    All PyLong_AsX will call PyInt_AsX. If PyInt_AsX does not exist, it will
    be added. Similarly PyLong_FromX. A similar path of warnings as for the
    Python builtins followed.


Overflows

    When an arithmetic operation on two numbers whose internal representation 
    is as a machine-level integers returns something whose internal 
    representation is a bignum, a warning which is turned off by default will
    be issued. This is only a debugging aid, and has no guaranteed semantics.

Implementation

    The PyInt type's slot for a C long will be turned into a 

           union {
               long i;
               digit digits[1];
           };

    Only the n-1 lower bits of the long have any meaning, the top bit is always
    set. This distinguishes the union. All PyInt functions will check this bit
    before deciding which types of operations to use.

Jython Issues

    Jython will have a PyInt interface which is implemented by both from 
    PyFixNum and PyBigNum.


Copyright

    This document has been placed in the public domain.



Local Variables:
mode: indented-text
indent-tabs-mode: nil
End:

==========================================
PEP: XXX
Title: Non-integer Division
Version: $Revision$
Author: pep@zadka.site.co.il (Moshe Zadka)
Status: Draft
Python-Version: 2.2
Type: Standards Track
Created: 11-Mar-2001
Post-History:


Abstract

    Dividing integers returns the floor of the quantities. This behaviour
    is known as integer division, and is similar to what C and FORTRAN do.
    This has the useful property that all operations on integers return
    integers, but it does tend to put a hump in the learning curve when
    new programmers are surprised that

                  1/2 == 0

    This proposal shows a way to change this will keeping backward 
    compatability issues in mind.

Rationale

    The behaviour of integer division is a major stumbling block found in
    user testing of Python. This manages to trip up new programmers 
    regularily and even causes the experienced programmer to make the
    occasional bugs. The work arounds, like explicitly coerce one of the
    operands to float or use a non-integer literal, are very non-intuitive
    and lower the readability of the program.

// Operator

    A '//' operator which will be introduced, which will call the nb_intdivide
    or __intdiv__ slots. This operator will be implemented in all the Python
    numeric types, and will have the semantics of

                 a // b == floor(a/b)

    Except that the type of a//b will be the type a and b will be coerced
    into (specifically, if a and b are of the same type, a//b will be of that
    type too).

Changing the Semantics of the / Operator

    The nb_divide slot on integers (and long integers, if these are a seperate
    type) will issue a warning when given integers a and b such that

                  a % b != 0

    The warning will be off by default in the 2.2 release, and on by default
    for in the next Python release, and will stay in effect for 24 months.
    The next Python release after 24 months, it will implement

                  (a/b) * b = a (more or less)

    The type of a/b will be either a float or a rational, depending on other
    PEPs.

__future__

    A special opcode, FUTURE_DIV will be added that does the equivalent
    of

        if type(a) in (types.IntType, types.LongType):
             if type(b) in (types.IntType, types.LongType):
                 if a % b != 0:
                      return float(a)/b
        return a/b

    (or rational(a)/b, depending on whether 0.5 is rational or float)

    If "from __future__ import non_integer_division" is present in the
    releases until the IntType nb_divide is changed, the "/" operator is
    compiled to FUTURE_DIV

Copyright

    This document has been placed in the public domain.



Local Variables:
mode: indented-text
indent-tabs-mode: nil
End:

====================================
PEP: XXX
Title: Adding a Rational Type to Python
Version: $Revision$
Author: pep@zadka.site.co.il (Moshe Zadka)
Status: Draft
Python-Version: 2.2
Type: Standards Track
Created: 11-Mar-2001
Post-History:


Abstract

    Python has no number type whose semantics are that of a unboundedly
    precise rational number. This proposal explains the semantics of such
    a type, and suggests builtin functions and literals to support such
    a type. In addition, if division of integers would return a non-integer,
    it could also return a rational type.

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 behaviour which is less surprising to newbies,

RationalType

    This will be a numeric type. The 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, .denominator.
    The language definition will not define other then that

           r.denominator * r == r.numerator

    In particular, no guarantees are made regarding the GCD or the sign of
    the denominator, even though in the proposed implementation, the GCD is
    always 1 and the denominator is always 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

Literals

    Literals conforming to the RE '\d*.\d*' will be rational numbers.

Backwards Compatability

    The only backwards compatible issue is the type of literals mentioned
    above. The following migration is suggested:

    1. from __future__ import rational_literals will cause all such literals
       to be treated as rational numbers.
    2. Python 2.2 will have a warning, turned off by default, about such 
       literals in the absence of such an __future__. The warning message
       will contain information about the __future__ statement, and that
       to get floating point literals, they should be suffixed with "e0".
    3. Python 2.3 will have the warning turned on by default. This warning will
       stay in place for 24 months, at which time the literals will be rationals
       and the warning will be removed.


Copyright

    This document has been placed in the public domain.



Local Variables:
mode: indented-text
indent-tabs-mode: nil
End:

-- 
"I'll be ex-DPL soon anyway so I'm        |LUKE: Is Perl better than Python?
looking for someplace else to grab power."|YODA: No...no... no. Quicker,
   -- Wichert Akkerman (on debian-private)|      easier, more seductive.
For public key, finger moshez@debian.org  |http://www.{python,debian,gnu}.org