Paul Moore wrote:
On 9 November 2011 20:15, Masklinn <masklinn@masklinn.net> 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[0], including prominent numerical ones[1].
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:
1. 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....
2. 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...
3. 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.)
4. 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.
Paul.
casevh