David H, Hi -- I'm concerned because I think the __add__, etc., architecture that you guys came up with (as of now) prevents implementation of any derived class's arithmetic in Python. You do have an _add_sibling_cdef in the base class that tries to deal with this problem, but it only works if the Python class derives directly from RingElement. If the derivation looks like this:
RingElement Integer My Python Class then your current solution doesn't work. More precisely, suppose somebody makes a class MyInteger: class MyInteger(Integer) and they want to define their own version of "+", so that if x and y are of type MyInteger, then x+y is also. Since MyInteger is defined in Python, there is no way to overload _add_sibling_cdef, which is a cdef. The user could of course overload __add__, but then their type doesn't obey SAGE's coercion rules. If MyInteger defines a Python method _add_sibling, def _add_sibling(self, right): ... does that mean in the base class __add__ method, we're going to have to check for _add_sibling every time we do an add? If so, this could end up being slower than just making everything a Python def method. Perhaps there is a fast way to tell whether a class is a Python class or a Pyrex class (say in the base class __add__ method), and always call _add_sibling_cdef if it's a Pyrex class and _add_sibling if it's a Python class. There probably is, because, e.g., Pyrex classes and Python classes print differently; one prints as <type ...> and the other as <class ...>. I've been looking at the Python/C API for a few minutes though and I haven't figured out a fast way to distinguish these two. NOTE. Also, you (obviously) can't just over-ride _add_sibling_cdef with some Python code: sage: class myint(Integer): ... def _add_sibling_cdef(self, x): ... print "hello world" sage: a = myint(1); b = myint(2) sage: type(a + b) <type 'sage.rings.integer.Integer'> Another possible (but confusing) option is to require that Python classes that derive from builtin SAGE classes multiply inherit. E.g., the following works: sage: class python_arith: ... def __add__(self, x): ... return self._add_sibling(x) sage: class myint(python_arith, Integer): ... def _add_sibling(self, x): ... print "python _add_sibling" ... return myint(0) ... def _add_(self, x): ... print "_add_" sage: a = myint(1); b = myint(2) sage: type(a+b) python _add_sibling <class '__main__.myint'> ------- But it is potentially *very* confusing to be forced to multiply derive whenever inheriting from SAGE builtin types. Plus I'll never remember the name of the other class I have to inherit from. Even if we can determine whether a class is defined in Pyrex instead of Python, another potential confusion would be if the user moves a Python class to Pyrex and forgets to change from _add_sibling to _add_sibling_cdef. By the way, this stuff you guys did " x = <Integer> PY_NEW(Integer)" is impressively fast! From that I get a factor of 5 speed up in some tests I'm doing. -- William --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---