Paul Moore wrote:
On 9 November 2011 20:15, Masklinn firstname.lastname@example.org wrote:
This would mean custom numerical types wouldn't be drop-in compatible with existing numerical *code*, which I am under the impression is what Case Van Horsen wants (and is a desirable outcome).
Furthermore, your second paragraph is not correct: Case does not propose "changing the behavior of built-in modules depending on the presence of another module", Case proposes adding *method hooks* to existing math and cmath functions. These would be protocols allowing custom numerical types to implement `math`/`cmath`'s operation in a sensible manner, as is already possible for four methods he mentions, as well as a number of other Python operations, including prominent numerical ones.
Correct. If a type does not implement one of the special methods, then there would be no change to the behaviour of the math/cmath modules.
I like the idea of being able to extend the math functions to allow user-defined numeric types to behave like built in ones. (In fact, if this were possible, complex could use it and a large proportion of the cmath module would be unneeded). However, I have to say that for me this is a purely theoretical issue - I've never had the need for the functionality myself in real code, and I doubt I ever will. Given the proliferation of special methods that would be needed, plus the runtime overhead of extra checking, I think the cost is likely too high.
It's also worth noting the preamble text in the math module documentation - the functions there deliberately only handle floats, and are thin wrappers over the C standard library. To get any sort of generic behaviour, users need to use cmath, by design. So as stated the proposal is unlikely to get much support.
Some alternative suggestions:
- As already noted, you could include a gmpmath module with the
relevant functions, and users could monkeypatch the math module if they wanted to do so.
The gmpy2 module provides a superset of the functions in math/cmath. I'm trying to avoid name collisions if someone replaces "from math import *" with "from gmpy2 import *". I know they shouldn't do that....
- To make such monkeypatching easier, publish a module that exposes a
context manager to do the job: with monkeypatch(math, 'sin', gmpmath.sin): your code here...
- Write a genericmath module that provides the "generic" versions
you're proposing, and see how much use it gets - if it's sufficiently popular, you have a better case then for folding the functionality into at least cmath.
I'll try to put a prototype together. One issue with merging math and cmath is that math.functions raise an exception instead of returning a complex result. If it becomes a single module, should it return complex values instead of raising an exception? That could be a major change in someone's code. (gmpy2 uses a context manager to enable/disable the return of a complex result from a real function.)
- As Georg mentioned, numpy's ufuncs have a feature like this, so
support that and people can use your types with numpy. That may be enough (depending on your expected user base).
I will look at numpy's ufuncs.
Overall, I think the idea of being able to use user-defined types interchangeably with built-in ones is a good one, but it's not something Python goes out of its way to support. If the idea of generic functions had taken off, then this is an area where they would have fit nicely - but once again, there wasn't much enthusiasm from the core developers for addressing the types of problem they were aimed at.