[Python-3000] Updated and simplified PEP 3141: A Type Hierarchy for Numbers
talin at acm.org
Thu May 17 09:40:19 CEST 2007
Jeffrey Yasskin wrote:
> I've updated PEP3141 to remove the algebraic classes and bring the
> numeric hierarchy much closer to scheme's design. Let me know what you
> think. Feel free to send typographical and formatting problems just to
> me. My schedule's a little shaky the next couple weeks, but I'll make
> updates as quickly as I can.
I need to give some background first, so be patient :)
The original version of this PEP was written at a time when ABCs were at
an earlier stage in their conceptual development. The notion of
overriding 'isinstance' had not yet been introduced, and so the only way
to inherit from an ABC was by the traditional inheritance mechanism.
At that time, there were a number of proposals for adding ABC base
classes to Python's built-in types. Those ABCs, being the foundation for
the built-in types, would have had to be built-ins themselves, and would
have been required to be initialized prior to the built-ins that
depended on them. This in turn meant that those ABCs were "special", in
the sense that they were officially sanctioned by the Python runtime
itself. The ABCs in this PEP and in the other ABC PEPs would have been
given a privileged status, elevated even above the classes in the
My feeling at the time was that I was uncomfortable with a brand new
type hierarchy, still in a relatively immature stage of development,
being deeply rooted into the core of Python. Being embedded into the
interpreter means that it would be hard to experiment with different
variations and to test out different options for the number hierarchy.
Not only would the embedded classes be hard to change, but there would
be no way that alternative proposals could compete.
My concern was that there would be little, if any, evolution of these
concepts, and that we would be stuck with a set of decisions which had
been made in haste. This is exactly contrary to the usual prescription
for Python library modules, which are supposed to prove themselves in
real-world apps before being enshrined in the standard library.
Now, the situation has changed somewhat. The ABC PEP has radically
shifted its focus, de-emphasizing traditional inheritance towards a new
mechanism which I call 'dynamic inheritance' - the ability to declare
new inheritance relations after a class has been created.
Lets therefore assume that the numeric ABCs will use this new
inheritance mechanism, avoiding the problem of taking an immature class
hierarchy and setting it in stone. The PEPs in this class would then no
longer need to have this privileged status; They could be replaced and
changed at will.
Assuming that this is true, the question then becomes whether these
classes should be treated like any other standard library submission. In
other words, shouldn't this PEP be implemented as a separate module, and
have to prove itself 'in the wild' before being adopted into the stdlib?
Does this PEP even need to be a PEP at all, or can it just be a
3rd-party library that is eventually adopted into Python?
Now, I *could* see adopting an untried library embodying untested ideas
into the stdlib if there was a crying need for the features of such a
library, and those needs were clearly being unfulfilled. However, I am
not certain that this is the case here.
At the very least, I think it should be stated in the PEP whether or not
the ABCs defined here are going to be using traditional or dynamic
If it is the latter, and we decide that this PEP is going to be part of
the stdlib, then I propose the following library organization:
import abc # Imports the basic ABC mechanics
import abc.collections # MutableSequence and such
import abc.math # The number hierarchy
... and so on
Now, there is another issue that needs to be dicussed.
The classes in the PEP appear to be written with lots of mixin methods,
such as __rsub__ and __abs__ and such. Unfortunately, the current
proposed method for dynamic inheritance does not allow for methods or
properties to be inherited from the 'virtual' base class. Which means
that all of the various methods defined in this PEP are utterly
meaningless other than as documentation - except in the case of a new
user-created class of numbers which inherit from these ABCs using
traditional inheritance, which is not something that I expect to happen
very often at all. For virtually all practical uses, the elaborate
methods defined in this PEP will be unused and inaccessible.
This really highlights what I think is a problem with dynamic
inheritance, and I think that this inconsistency between traditional and
dynamic inheritance will eventually come back to haunt us. It has always
been the case in the past that for every property of class B, if
isinstance(A, B) == True, then A also has that property, either
inherited from B, or overridden in A. The fact that this invariant will
no longer hold true is a problem in my opinion.
I realize that there isn't currently a solution to efficiently allow
inheritance of properties via dynamic inheritance. As a software
engineer, however, I generally feel that if a feature is unreliable,
then it shouldn't be used at all. So if I were designing a class
hierarchy of ABCs, I would probably make a rule for myself not to define
any properties or methods in the ABCs at all, and to *only* use ABCs for
type testing via 'isinstance'.
In other words, if I were writing this PEP, all of those special methods
would be omitted, simply because as a writer of a subclass I couldn't
rely on being able to use them.
The only alternative that I can see is to not use dynamic inheritance at
all, and instead have the number classes inherit from these ABCs using
the traditional mechanism. But that brings up all the problems of
immaturity and requiring them to be built-in that I brought up earlier.
More information about the Python-3000