[Python-3000] Updated and simplified PEP 3141: A Type Hierarchy for Numbers (original) (raw)

Talin 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.

General comments:

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 standard library.

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 inheritance.

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.

-- Talin



More information about the Python-3000 mailing list