[Python-Dev] return type of complex (original) (raw)
Nick Coghlan ncoghlan at gmail.com
Sun Oct 21 04:57:31 CEST 2012
- Previous message: [Python-Dev] return type of __complex__
- Next message: [Python-Dev] return type of __complex__
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Sun, Oct 21, 2012 at 11:53 AM, Steven D'Aprano <steve at pearwood.info> wrote:
On 21/10/12 06:28, Tres Seaver wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 10/19/2012 07:35 PM, Greg Ewing wrote:
Antonio Cuni wrote:
Traceback (most recent call last): File "", line 1, in TypeError: complex should return a complex object i.e., the complex constructor does not check that complex returns an actual complex, while the cmath functions do.
Looks to me like cmath is being excessively finicky here. Why shouldn't a float be usable in any context expecting a complex? Exactly: float is perfectly Liskov-substituable for complex; only applications which do explicit type sniffing can tell the difference, which makes the sniffing bogus. But float is not numerically substitutable for complex, which is why type-sniffing is not bogus at all. If you have an application which assumes numeric quantities represent real values, then you need to distinguish between real-valued and complex-valued arithmetic, and treating floats as implicitly complex is the wrong thing to do. Since most applications are based on real-values, implicit promotion to complex is in my opinion an anti-feature. Python 2.x legitimately distinguished between floats and complex, e.g.: py> (-100.0)**0.5 Traceback (most recent call last): File "", line 1, in ValueError: negative number cannot be raised to a fractional power If you wanted a complex result, you can explicitly ask for one: py> (-100.0+0j)**0.5 (6.123031769111886e-16+10j) I see that behaviour is changed in Python 3. Was this discussed before being changed? I see a single sample docstring buried in PEP 3141 that: """a**b; should promote to float or complex when necessary.""" but I can't find any discussion of the consequences of this for the majority of users who would be surprised by the unexpected appearance of a "j" inside their numbers.
PEP 3141 is indeed the driver for these changes, and it's based on the Python 3.x numeric tower consisting of strict supersets: Complex > Real > Rational > Integral
If an operation at one level of the tower produces a result in one of the larger supersets, then that's what it will do rather than throwing TypeError. int / int promoting to float is one example, as is raising a negative number to a fractional power promoting to complex.
The general philosophy is described in http://www.python.org/dev/peps/pep-3141/#implementing-the-arithmetic-operations
It sounds like cmath (or, more specifically, the "D" conversion code) missed out on the associated updates).
Cheers, Nick.
-- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
- Previous message: [Python-Dev] return type of __complex__
- Next message: [Python-Dev] return type of __complex__
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]