
Target: Py2.6 and Py3.0 Author: Raymond Hettinger Date: May 31, 2008 Motivation ---------- The principal purpose of an abstract base class is to support multiple implementations of an API; thereby allowing one concrete class to be substitutable for another. This purpose is defeated when useful substitutions are precluded because the ABC is too aggressive in its behavioral requirements -- mandating too many methods, mandating methods that are difficult to implement, or too closely following the full API of a single concrete type. The Integral ABC is somewhat extensive and requires essentially every behavior exhibited by the int concrete class. Usefully, it provides for basic integer behaviors like simple arithmetic and ordering relations. However, the current ABC goes beyond that and requires bit-flipping and other operations that are not fundamental to the notion of being an integer. That makes it challenging to define a new Integral class that isn't already an int. Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator. Discussion ---------- The only known use cases for variants of int are types that limit the range of values to those that fit in a fixed storage width. One existing implementation is in numpy which has types like int0, int8, int16, int32, and int16. The numpy integral types implement all the methods present in Integral except for the new methods like __trunc__, __index__, real, imag, conjugate, numerator, and denominator. For the most part, they are fully substitutable into code that expects regular ints; however, they do have wrap-around behaviors such as int8(200)+int8(100) --> int8(44). The wrap-around behaviors make the numpy types totally unsuitable for some applications of Integral such as the fractions module which accepts any integral numerator and denominator.

On Sun, Jun 1, 2008 at 8:15 AM, Raymond Hettinger <python@rcn.com> wrote:
Discussion ---------- The only known use cases for variants of int are types that limit the range of values to those that fit in a fixed storage width.
Add: * Faster big integers (gmpy) * Integers with exact division to rationals (e.g. sympy) Fredrik

On Sat, May 31, 2008, Raymond Hettinger wrote:
Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator.
The only thing I object to is removing __index__ -- the whole point of an integral class is that it is substitutable as an index for sequences in a way that other numeric types are not. Having an __index__ special method is a key indicator for duck-typing purposes not covered by the ABC. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Need a book? Use your library!

The only comment so far was to keep the __index__ method. Other than that, is this good to go? Raymond ----- Original Message -----
Target: Py2.6 and Py3.0 Author: Raymond Hettinger Date: May 31, 2008
Motivation ---------- The principal purpose of an abstract base class is to support multiple implementations of an API; thereby allowing one concrete class to be substitutable for another. This purpose is defeated when useful substitutions are precluded because the ABC is too aggressive in its behavioral requirements -- mandating too many methods, mandating methods that are difficult to implement, or too closely following the full API of a single concrete type.
The Integral ABC is somewhat extensive and requires essentially every behavior exhibited by the int concrete class. Usefully, it provides for basic integer behaviors like simple arithmetic and ordering relations. However, the current ABC goes beyond that and requires bit-flipping and other operations that are not fundamental to the notion of being an integer. That makes it challenging to define a new Integral class that isn't already an int.
Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator.
Discussion ---------- The only known use cases for variants of int are types that limit the range of values to those that fit in a fixed storage width.
One existing implementation is in numpy which has types like int0, int8, int16, int32, and int16. The numpy integral types implement all the methods present in Integral except for the new methods like __trunc__, __index__, real, imag, conjugate, numerator, and denominator. For the most part, they are fully substitutable into code that expects regular ints; however, they do have wrap-around behaviors such as int8(200)+int8(100) --> int8(44). The wrap-around behaviors make the numpy types totally unsuitable for some applications of Integral such as the fractions module which accepts any integral numerator and denominator.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/python%40rcn.com

Because .numerator and .denominator are defined by the Rational ABC, and Integral inherits from that, removing them from Integral is a larger change than removing the other methods. You'd have to remove them from Rational or break the inheritance relation. Removing the bitwise operators sounds fine to me. On Wed, Jun 4, 2008 at 1:54 AM, Raymond Hettinger <python@rcn.com> wrote:
The only comment so far was to keep the __index__ method.
Other than that, is this good to go?
Raymond
----- Original Message -----
Target: Py2.6 and Py3.0 Author: Raymond Hettinger Date: May 31, 2008
Motivation ---------- The principal purpose of an abstract base class is to support multiple implementations of an API; thereby allowing one concrete class to be substitutable for another. This purpose is defeated when useful substitutions are precluded because the ABC is too aggressive in its behavioral requirements -- mandating too many methods, mandating methods that are difficult to implement, or too closely following the full API of a single concrete type.
The Integral ABC is somewhat extensive and requires essentially every behavior exhibited by the int concrete class. Usefully, it provides for basic integer behaviors like simple arithmetic and ordering relations. However, the current ABC goes beyond that and requires bit-flipping and other operations that are not fundamental to the notion of being an integer. That makes it challenging to define a new Integral class that isn't already an int.
Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator.
Discussion ---------- The only known use cases for variants of int are types that limit the range of values to those that fit in a fixed storage width.
One existing implementation is in numpy which has types like int0, int8, int16, int32, and int16. The numpy integral types implement all the methods present in Integral except for the new methods like __trunc__, __index__, real, imag, conjugate, numerator, and denominator. For the most part, they are fully substitutable into code that expects regular ints; however, they do have wrap-around behaviors such as int8(200)+int8(100) --> int8(44). The wrap-around behaviors make the numpy types totally unsuitable for some applications of Integral such as the fractions module which accepts any integral numerator and denominator.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/python%40rcn.com
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/jyasskin%40gmail.com
-- Namasté, Jeffrey Yasskin http://jeffrey.yasskin.info/

I haven't seen anyone applaud either. Unless more folks actually say they agree I don't want to go forward with this. There was quite a bit of discussion about PEP 3141 and it was accepted; striking this much from it with virtually no discussion seems wrong to me. Jeffrey made a good point: .numerator and .denominator need to be kept in the interface. I really don't want to divorce Integer from Rational. They're trivial to implement, and I won't complain if you leave them unimplemented while claiming conformance. :-) My position: I'm -1 on removing __index__, numerator, denominator, and on removing anything you didn't mention explicitly. You used the phrase "methods like", which seems inappropriate for a specification. Note also that these happen to be concrete methods, not abstract ones like you claim. I'm -0 on removing the bitwise operators, i.e. could be swayed by some +1 votes. --Guido On Wed, Jun 4, 2008 at 1:54 AM, Raymond Hettinger <python@rcn.com> wrote:
The only comment so far was to keep the __index__ method.
Other than that, is this good to go?
Raymond
----- Original Message -----
Target: Py2.6 and Py3.0 Author: Raymond Hettinger Date: May 31, 2008
Motivation ---------- The principal purpose of an abstract base class is to support multiple implementations of an API; thereby allowing one concrete class to be substitutable for another. This purpose is defeated when useful substitutions are precluded because the ABC is too aggressive in its behavioral requirements -- mandating too many methods, mandating methods that are difficult to implement, or too closely following the full API of a single concrete type.
The Integral ABC is somewhat extensive and requires essentially every behavior exhibited by the int concrete class. Usefully, it provides for basic integer behaviors like simple arithmetic and ordering relations. However, the current ABC goes beyond that and requires bit-flipping and other operations that are not fundamental to the notion of being an integer. That makes it challenging to define a new Integral class that isn't already an int.
Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator.
Discussion ---------- The only known use cases for variants of int are types that limit the range of values to those that fit in a fixed storage width.
One existing implementation is in numpy which has types like int0, int8, int16, int32, and int16. The numpy integral types implement all the methods present in Integral except for the new methods like __trunc__, __index__, real, imag, conjugate, numerator, and denominator. For the most part, they are fully substitutable into code that expects regular ints; however, they do have wrap-around behaviors such as int8(200)+int8(100) --> int8(44). The wrap-around behaviors make the numpy types totally unsuitable for some applications of Integral such as the fractions module which accepts any integral numerator and denominator.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/python%40rcn.com
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

From: "Guido van Rossum" <guido@python.org>
Unless more folks actually say they agree I don't want to go forward with this. There was quite a bit of discussion about PEP 3141 and it was accepted; striking this much from it with virtually no discussion seems wrong to me.
Not sure how to generate more discussion. It seems self-evident that an abc with lots of abstract methods is inherently less usable and that bitwise operations go beyond the basic notion of "integeriness". Requiring all those methods to be defined makes it harder to write a compliant class. Other than int/long, no currently existing type matches-up with Integral. Does anyone care about this? If something like numpy's int8 eventually grows the required methods, it is worriesome that the numerator/denominator properties will be automatically supplied for fractions.py to accept as inputs eventhough int8's wrap-around behavior makes them entirely unsuitable. I don't know if this bothers anyone. It would seem that a consumer of an Integral can assume the existence of methods but nothing about whether the result is usable. That might not be a big deal except that numpy is t he only known use case. Hopefully, some discussion gets generated. But if no one cares, I'll happily drop it. Raymond

On Wed, Jun 4, 2008 at 12:57 PM, Raymond Hettinger <python@rcn.com> wrote:
From: "Guido van Rossum" <guido@python.org>
Unless more folks actually say they agree I don't want to go forward with this. There was quite a bit of discussion about PEP 3141 and it was accepted; striking this much from it with virtually no discussion seems wrong to me.
Not sure how to generate more discussion. It seems self-evident that an abc with lots of abstract methods is inherently less usable and that bitwise operations go beyond the basic notion of "integeriness". Requiring all those methods to be defined makes it harder to write a compliant class.
In general it is good to require that more thought goes into the design and implementation of a class, so that less thought needs to go into using it.
Other than int/long, no currently existing type matches-up with Integral. Does anyone care about this?
Does "this" refer to "the Integral ABC" or "no type matches up with it" ?
If something like numpy's int8 eventually grows the required methods, it is worrysome that the numerator/denominator properties will be automatically supplied for fractions.py to accept as inputs eventhough int8's wrap-around behavior makes them entirely unsuitable.
I'm not sure what you mean. This is probably just my lack of imagination. Can you give a small code example where using an int8 with the fractions module would cause problems? The Fraction class appears to be calling __index__ on its arguments, which would convert the int8 to a proper int (or long, in Python 2.6).
I don't know if this bothers anyone. It would seem that a consumer of an Integral can assume the existence of methods but nothing about whether the result is usable. That might not be a big deal except that numpy is t he only known use case.
Any integer type that performs arithmetic modulo some number is problematic. Perhaps a totally separate ABC needs to be defined for this purpose, one that doesn't inherit from Rational.
Hopefully, some discussion gets generated. But if no one cares, I'll happily drop it.
Have you asked the numpy folks? If enough people care, we could easily create a BinaryInteger ABC that defines the bitwise operations. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Wed, Jun 4, 2008 at 12:57 PM, Raymond Hettinger <python@rcn.com> wrote:
Not sure how to generate more discussion. It seems self-evident that an abc with lots of abstract methods is inherently less usable and that bitwise operations go beyond the basic notion of "integeriness". Requiring all those methods to be defined makes it harder to write a compliant class.
Other than int/long, no currently existing type matches-up with Integral. Does anyone care about this?
Hopefully, some discussion gets generated. But if no one cares, I'll happily drop it.
I'm just responding out of duty to add more discussion on the topic. I think I agree with Raymond on the basic principle that simple ABC's are easier to use than simple ones. Anyway, it's hard to add anything to the discussion when I haven't seen many applications of the Integral ABC, but in principle, but if I had to vote I'd say that the bitwise operators aren't particularly integery. -- Andrew McNabb http://www.mcnabbs.org/andrew/ PGP Fingerprint: 8A17 B57C 6879 1863 DE55 8012 AB4D 6098 8826 6868

I think I agree with Raymond on the basic principle that simple ABC's are easier to use than simple ones.
I don't think he was saying that. He was saying that simple ABC's are easier to implement to. It's not at all clear to me that simple ABC's are good in and of themselves. I think a String ABC should probably include all the methods that basestring provides, perhaps by reducing the methods that basestring provides, and moving the removed methods to the String ABC, with implementations that call the methods provided by basestring. That way, String classes could be implemented by overriding the "base" set of methods, but still inherit from String to get the other methods. But, then, isn't basestring the true simple ABC for strings? Bill

On Thu, Jun 05, 2008 at 09:41:44AM -0700, Bill Janssen wrote:
I think I agree with Raymond on the basic principle that simple ABC's are easier to use than simple ones.
I don't think he was saying that. He was saying that simple ABC's are easier to implement to.
Sorry; I used the wrong word. I should have said "implement to" rather than "use." I agree with you. -- Andrew McNabb http://www.mcnabbs.org/andrew/ PGP Fingerprint: 8A17 B57C 6879 1863 DE55 8012 AB4D 6098 8826 6868

"Raymond Hettinger" <python@rcn.com> wrote in message news:2745D7EB7C064B16A88E433588021756@RaymondLaptop1... | From: "Guido van Rossum" <guido@python.org> | > Unless more folks actually say they agree I don't want to go forward | > with this. There was quite a bit of discussion about PEP 3141 and it | > was accepted; striking this much from it with virtually no discussion | > seems wrong to me. | | Not sure how to generate more discussion. It seems self-evident | that an abc with lots of abstract methods is inherently less usable | and that bitwise operations go beyond the basic notion of "integeriness". On reading PEP3141 some months ago and again today, I thought and still do that all the methods that depend on a 2s-complement representation and implementation really belong to an implentation-defined subclass of Integral. But I am not sure of the purpose of the class and of including such concrete methods in an ABC, and so said nothing ;-). I notice that the similarly implementation-based frexp and ldexp math methods are *not* in the Real class. | Requiring all those methods to be defined makes it harder to write | a compliant class. Other than int/long, no currently existing type | matches-up with Integral. Does anyone care about this? I might some day, for didactic purposes, write integer classes based on prime-factorization or fibonacci representations. I certainly would skip all the 2s-complement methods. But I do not know that I would care much about being 'non-compliant'. | If something like numpy's int8 eventually grows the required methods, | it is worriesome that the numerator/denominator properties will be | automatically supplied for fractions.py to accept as inputs eventhough | int8's wrap-around behavior makes them entirely unsuitable. In my view, the members of residue/remainder classes are not really integers unless their usage is carefully restricted to avoid invocation of the mod operation. Terry Jan Reedy

Terry Reedy wrote:
"Raymond Hettinger" <python@rcn.com> wrote in message news:2745D7EB7C064B16A88E433588021756@RaymondLaptop1... | From: "Guido van Rossum" <guido@python.org> | > Unless more folks actually say they agree I don't want to go forward | > with this. There was quite a bit of discussion about PEP 3141 and it | > was accepted; striking this much from it with virtually no discussion | > seems wrong to me. | | Not sure how to generate more discussion. It seems self-evident | that an abc with lots of abstract methods is inherently less usable | and that bitwise operations go beyond the basic notion of "integeriness".
On reading PEP3141 some months ago and again today, I thought and still do that all the methods that depend on a 2s-complement representation and implementation really belong to an implentation-defined subclass of Integral. But I am not sure of the purpose of the class and of including such concrete methods in an ABC, and so said nothing ;-).
I think it definitely makes sense to separate out the number-as-sequence-of-bits operations from the main Integral ABC. This would involve moving: lshift, rshift, and, or, xor, invert (along with their reversed and in-place counterparts) Note that this leaves the Integral ABC adding only __long__, __index__ and 3-argument __pow__ over and above the Rational ABC. If 3-argument __pow__ goes (which appears likely), we're left with __long__ and __index__. However, there's still a few additional public properties and methods inherited from higher up in the numeric stack which most existing integral types are unlikely to provide: .real, .imag, .conjugate(). Unlike the methods being relocated, however, these are absolutely trivial for all non-complex numeric types. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org

On Thu, Jun 5, 2008 at 6:20 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Terry Reedy wrote:
"Raymond Hettinger" <python@rcn.com> wrote in message news:2745D7EB7C064B16A88E433588021756@RaymondLaptop1... | From: "Guido van Rossum" <guido@python.org> | > Unless more folks actually say they agree I don't want to go forward | > with this. There was quite a bit of discussion about PEP 3141 and it | > was accepted; striking this much from it with virtually no discussion | > seems wrong to me. | | Not sure how to generate more discussion. It seems self-evident | that an abc with lots of abstract methods is inherently less usable | and that bitwise operations go beyond the basic notion of "integeriness".
On reading PEP3141 some months ago and again today, I thought and still do that all the methods that depend on a 2s-complement representation and implementation really belong to an implentation-defined subclass of Integral. But I am not sure of the purpose of the class and of including such concrete methods in an ABC, and so said nothing ;-).
I think it definitely makes sense to separate out the number-as-sequence-of-bits operations from the main Integral ABC. This would involve moving:
lshift, rshift, and, or, xor, invert (along with their reversed and in-place counterparts)
Agreed. Let's move these into a separate BinaryInteger class.
Note that this leaves the Integral ABC adding only __long__, __index__ and 3-argument __pow__ over and above the Rational ABC. If 3-argument __pow__ goes (which appears likely), we're left with __long__ and __index__.
Let's ditch 3-arg pow, but keep __long__ (in 2.6) and __index__. Actually __long__ can go too.
However, there's still a few additional public properties and methods inherited from higher up in the numeric stack which most existing integral types are unlikely to provide: .real, .imag, .conjugate(). Unlike the methods being relocated, however, these are absolutely trivial for all non-complex numeric types.
I definitely want to keep these. They're essential for people who want to use the higher-up classes in the numeric tower. I think this is settled now; Raymond can update PEP 3141 (if he refrains from editorializing) and patch numbers.py. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

[Terry Reedy]
On reading PEP3141 some months ago and again today, I thought and still do that all the methods that depend on a 2s-complement representation and implementation really belong to an implentation-defined subclass of Integral. But I am not sure of the purpose of the class and of including such concrete methods in an ABC, and so said nothing ;-).
[Nick Coghlan]
I think it definitely makes sense to separate out the number-as-sequence-of-bits operations from the main Integral ABC. This would involve moving:
lshift, rshift, and, or, xor, invert (along with their reversed and in-place counterparts)
I vote for complete removal of the bit flipping methods. There's a cost to creating new ABCs that are devoid of use cases. When Terry says "I am not sure of the purpose of the class ...", I think he meant that a binary abc wasn't proposed because of its questionable utility. At some point, if you want an int type, you just use an int type. What is the purpose of having yet another layer in the "numeric tower"? Does anyone actually need an int lookalike with binary methods but cannot just inherit from int? Looking back at PEP 3119, I see there was an early decision "between standardizing more, fine-grained ABCs or fewer, course-grained ones" and that the choice was resolved in favor the few. That is how we avoided urban sprawl with the likes of "ComposableSet, MutableSet, HashableSet, MutableComposableSet, HashableComposableSet". I had thought everyone was on-board with the notion that thin abcs that capture the essence of a type are better than fat abcs that seek emulate every aspect of a single concrete type. Without agreement on that premise, simplification is a lost cause. If the group wants to go forward with a Binary subclass of Integral, then I would like to withdraw this simplification mini-pep. Better to stick with what we have now than to addcomplexity to a module that is already use case challenged. Raymond

On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well? -- --Guido van Rossum (home page: http://www.python.org/~guido/)

2008/6/6 Guido van Rossum <guido@python.org>:
On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well?
I have no vested interest either way, but I think someone mentioned creating a long int equivalent based on Decimal earlier in the thread. Wrappers for the gmp library might also want to do this. It's hardly the world's biggest use case, though... Paul.

On Fri, Jun 6, 2008 at 11:01 AM, Guido van Rossum <guido@python.org> wrote:
On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well?
Yes, there's a use case for implementing long integers as arrays of decimal digits -- addition is roughly as efficient as for binary integers (x86 chips still have instructions to help with that), and emitting as decimal digits is MUCH more efficient of course -- so if I/O in decimal form is the most common operation, with a little arithmetic (particularly sums), you could gain performance; binary operations, however, would be as inefficient as decimal form conversion is for ordinary binary ints, and not needed for the typical applications that would use these "decimal coded integers" (accounting), so why not save the implementer of such an extension from having to write that unneeded and slow extra code? Alex

On Fri, Jun 6, 2008 at 11:40 AM, Alex Martelli <aleaxit@gmail.com> wrote:
On Fri, Jun 6, 2008 at 11:01 AM, Guido van Rossum <guido@python.org> wrote:
On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well?
Yes, there's a use case for implementing long integers as arrays of decimal digits -- addition is roughly as efficient as for binary integers (x86 chips still have instructions to help with that), and emitting as decimal digits is MUCH more efficient of course -- so if I/O in decimal form is the most common operation, with a little arithmetic (particularly sums), you could gain performance;
I tried this with ABC in '83. We didn't see any of the hoped-for benefits though. That's why Python has binary long integers. :-)
binary operations, however, would be as inefficient as decimal form conversion is for ordinary binary ints, and not needed for the typical applications that would use these "decimal coded integers" (accounting), so why not save the implementer of such an extension from having to write that unneeded and slow extra code?
You could just raise an exception. This is common in Java when an Interface requires you implement a method you can't. Or use virtual inheritance from the Integral class and leave them unimplemented. See if anyone cares. :-) -- --Guido van Rossum (home page: http://www.python.org/~guido/)

In data 06 giugno 2008 alle ore 20:40:01, Alex Martelli <aleaxit@gmail.com> ha scritto:
On Fri, Jun 6, 2008 at 11:01 AM, Guido van Rossum <guido@python.org> wrote:
On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well?
Yes, there's a use case for implementing long integers as arrays of decimal digits -- addition is roughly as efficient as for binary integers (x86 chips still have instructions to help with that), and emitting as decimal digits is MUCH more efficient of course -- so if I/O in decimal form is the most common operation, with a little arithmetic (particularly sums), you could gain performance; binary operations, however, would be as inefficient as decimal form conversion is for ordinary binary ints, and not needed for the typical applications that would use these "decimal coded integers" (accounting), so why not save the implementer of such an extension from having to write that unneeded and slow extra code?
Alex
I don't know if you are talking about BCD numbers, but they are quite inefficient and slow in x86 architecture. There are instructions only to add and subtract packed BCD numbers which uses just two decimal digits (packed in two nibbles into a single byte). For unpacked BCDs, there are instructions to add, subtract, multiply and divide numbers, but which uses only one digit at the time. So using packed BCDs to store 8 decimal digits in 32 bits, for example, requires 4 instructions to make addictions or subractions, plus the required shift & mask instructions to put every couple digits into the AL register to execute BCD operations. Unpacked BCDs need double of them. Also, these instructions still use microcode to execute on modern processors, slowing down the execution pipeline (most of the simpler instructions do not require microcode, and execute "directly"). Last but not least, on x86-64 architecture BCD instructions were completely removed from the ISA; opcodes are assigned to new instructions. Obviously, binary operations can be performed twice faster thanks to the 64 bit registers and ALUs. The only practical advantage on using BCD numbers is the conversion-to-string operation, which can be done faster than binary numbers. Binary addition, subtraction, multiplication and division are greatly faster than BCD ones, and should be the preferred way to do integer math. Cesare

New idea! I missed an obvious solution. Let the binary methods in Integral be mixins instead of abstract methods. That minimizes the burden on the class implementer while providing maximum support for clients. class Integral(Rational): ... def __lshift__(self, other): """self << other""" return long(self) << long(other) def __xor__(self, other): """self ^ other""" return long(self) ^ long(other) I worried a bit about changing type, but this kind of thing is already baked into numbers.py: @property def imag(self): """Real numbers have no imaginary component.""" return 0 @property def denominator(self): """Integers have a denominator of 1.""" return 1 Raymond ----- Original Message ----- From: "Alex Martelli" <aleaxit@gmail.com> To: "Guido van Rossum" <guido@python.org> Cc: "Raymond Hettinger" <python@rcn.com>; <python-dev@python.org> Sent: Friday, June 06, 2008 11:40 AM Subject: Re: [Python-Dev] Mini-Pep: Simplifying the Integral ABC
On Fri, Jun 6, 2008 at 11:01 AM, Guido van Rossum <guido@python.org> wrote:
On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well?
Yes, there's a use case for implementing long integers as arrays of decimal digits -- addition is roughly as efficient as for binary integers (x86 chips still have instructions to help with that), and emitting as decimal digits is MUCH more efficient of course -- so if I/O in decimal form is the most common operation, with a little arithmetic (particularly sums), you could gain performance; binary operations, however, would be as inefficient as decimal form conversion is for ordinary binary ints, and not needed for the typical applications that would use these "decimal coded integers" (accounting), so why not save the implementer of such an extension from having to write that unneeded and slow extra code?
Alex

Make that int() instead of long() and I'm okay with it. On Fri, Jun 6, 2008 at 1:33 PM, Raymond Hettinger <python@rcn.com> wrote:
New idea! I missed an obvious solution. Let the binary methods in Integral be mixins instead of abstract methods. That minimizes the burden on the class implementer while providing maximum support for clients.
class Integral(Rational): ... def __lshift__(self, other): """self << other""" return long(self) << long(other) def __xor__(self, other): """self ^ other""" return long(self) ^ long(other)
I worried a bit about changing type, but this kind of thing is already baked into numbers.py:
@property def imag(self): """Real numbers have no imaginary component.""" return 0
@property def denominator(self): """Integers have a denominator of 1.""" return 1
Raymond
----- Original Message ----- From: "Alex Martelli" <aleaxit@gmail.com> To: "Guido van Rossum" <guido@python.org> Cc: "Raymond Hettinger" <python@rcn.com>; <python-dev@python.org> Sent: Friday, June 06, 2008 11:40 AM Subject: Re: [Python-Dev] Mini-Pep: Simplifying the Integral ABC
On Fri, Jun 6, 2008 at 11:01 AM, Guido van Rossum <guido@python.org> wrote:
On Thu, Jun 5, 2008 at 8:45 PM, Raymond Hettinger <python@rcn.com> wrote:
Does anyone actually need an int lookalike with binary methods but cannot just inherit from int?
Does anyone actually need an int lookalike with operations like +, - etc. but cannot just inherit from int? If the answer is yes, is there a compelling reason why they wouldn't want to support binary methods as well?
Yes, there's a use case for implementing long integers as arrays of decimal digits -- addition is roughly as efficient as for binary integers (x86 chips still have instructions to help with that), and emitting as decimal digits is MUCH more efficient of course -- so if I/O in decimal form is the most common operation, with a little arithmetic (particularly sums), you could gain performance; binary operations, however, would be as inefficient as decimal form conversion is for ordinary binary ints, and not needed for the typical applications that would use these "decimal coded integers" (accounting), so why not save the implementer of such an extension from having to write that unneeded and slow extra code?
Alex
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

From: "Guido van Rossum" <guido@python.org>
Make that int() instead of long() and I'm okay with it.
Does anyone know why Integral says that __long__ is a required abstract method, but not __int__? Likewise, why is index() defined as long(self) instead of int(self)? There may be some design nuance that I'm not seeing. Raymond

Both of these seem 2.6-specific quirks. Those lines wereJeffrey's; maybe he remembers? I'm guessing that adding __long__ was done since 2.6 supports it, and the removal of __int__ was an oversight. I also think that there's no reason to change __index__ to call long(); int() will automatically return a long as needed. Maybe changing __long__ back to __int__ is also harmless. On Fri, Jun 6, 2008 at 2:13 PM, Raymond Hettinger <python@rcn.com> wrote:
From: "Guido van Rossum" <guido@python.org>
Make that int() instead of long() and I'm okay with it.
Does anyone know why Integral says that __long__ is a required abstract method, but not __int__?
Likewise, why is index() defined as long(self) instead of int(self)?
There may be some design nuance that I'm not seeing.
Raymond _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

Well, it seems like Integral instances should be able to be passed to either int() or long(), so __long__ should probably stay. I have no idea why I didn't include __int__, but its absence was probably the only reason __index__ calls long() instead of int(). On Fri, Jun 6, 2008 at 3:23 PM, Guido van Rossum <guido@python.org> wrote:
Both of these seem 2.6-specific quirks. Those lines wereJeffrey's; maybe he remembers? I'm guessing that adding __long__ was done since 2.6 supports it, and the removal of __int__ was an oversight. I also think that there's no reason to change __index__ to call long(); int() will automatically return a long as needed. Maybe changing __long__ back to __int__ is also harmless.
On Fri, Jun 6, 2008 at 2:13 PM, Raymond Hettinger <python@rcn.com> wrote:
From: "Guido van Rossum" <guido@python.org>
Make that int() instead of long() and I'm okay with it.
Does anyone know why Integral says that __long__ is a required abstract method, but not __int__?
Likewise, why is index() defined as long(self) instead of int(self)?
There may be some design nuance that I'm not seeing.
Raymond _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
-- Namasté, Jeffrey Yasskin http://jeffrey.yasskin.info/

I recommend switching back to __int__ and int; even in 2.5, these are expected to return either an int or a long as required. There's no need to mess with __long__ at all. On Fri, Jun 6, 2008 at 8:25 PM, Jeffrey Yasskin <jyasskin@gmail.com> wrote:
Well, it seems like Integral instances should be able to be passed to either int() or long(), so __long__ should probably stay. I have no idea why I didn't include __int__, but its absence was probably the only reason __index__ calls long() instead of int().
On Fri, Jun 6, 2008 at 3:23 PM, Guido van Rossum <guido@python.org> wrote:
Both of these seem 2.6-specific quirks. Those lines wereJeffrey's; maybe he remembers? I'm guessing that adding __long__ was done since 2.6 supports it, and the removal of __int__ was an oversight. I also think that there's no reason to change __index__ to call long(); int() will automatically return a long as needed. Maybe changing __long__ back to __int__ is also harmless.
On Fri, Jun 6, 2008 at 2:13 PM, Raymond Hettinger <python@rcn.com> wrote:
From: "Guido van Rossum" <guido@python.org>
Make that int() instead of long() and I'm okay with it.
Does anyone know why Integral says that __long__ is a required abstract method, but not __int__?
Likewise, why is index() defined as long(self) instead of int(self)?
There may be some design nuance that I'm not seeing.
Raymond _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
-- Namasté, Jeffrey Yasskin http://jeffrey.yasskin.info/
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Sun, Jun 1, 2008 at 2:15 AM, Raymond Hettinger <python@rcn.com> wrote:
Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator.
+1 from me. I'd support removing all these, minus the exceptions already pointed out (__index__, numerator, denominator). As a (so far incomplete) effort to speed up the Decimal type I recently implemented a decimal-based integer type; this type would seem a natural candidate to inherit from Integral, but the logical and shift operators above make less sense for this type. The other odd man out here is three-argument pow; this *is* a method that makes sense for integers without reference to the way they're stored. So maybe this should stay. (Though I've occasionally wondered why three-argument pow is part of the core language, rather than being in the standard library.) Mark

I think it's fine to remove 3-arg pow() from the ABC; implementations are of course free to provide it. Raymond, why don't you cook up a patch? It should patch both the PEP and numbers.py. On Wed, Jun 4, 2008 at 8:44 PM, Mark Dickinson <dickinsm@gmail.com> wrote:
On Sun, Jun 1, 2008 at 2:15 AM, Raymond Hettinger <python@rcn.com> wrote:
Proposal -------- Remove non-essential abstract methods like __index__, three argument __pow__, __lshift__, __rlshift__, __rshift__, __rrshift__, __and__, __rand__, __xor__, __rxor__, __or__, __ror__, and __invert__, numerator, and denominator.
+1 from me. I'd support removing all these, minus the exceptions already pointed out (__index__, numerator, denominator). As a (so far incomplete) effort to speed up the Decimal type I recently implemented a decimal-based integer type; this type would seem a natural candidate to inherit from Integral, but the logical and shift operators above make less sense for this type. The other odd man out here is three-argument pow; this *is* a method that makes sense for integers without reference to the way they're stored. So maybe this should stay. (Though I've occasionally wondered why three-argument pow is part of the core language, rather than being in the standard library.) Mark
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (13)
-
Aahz
-
Alex Martelli
-
Andrew McNabb
-
Bill Janssen
-
Cesare Di Mauro
-
Fredrik Johansson
-
Guido van Rossum
-
Jeffrey Yasskin
-
Mark Dickinson
-
Nick Coghlan
-
Paul Moore
-
Raymond Hettinger
-
Terry Reedy