I've been looking carefully at the RingElement__add__ code some more, in light of some of the issues William brought up last week, and my conclusion is that it's still not right.
Part of the design was supposed to be that a highly optimised piece of pyrex code could call _add_sibling_cdef for any RingElement- derived type, to achieve maximum performance even for a generic type. But that's still broken in the current model, i.e. in the same scenario William thought up, which is a python class derived from Integer; it would be calling Integer's _add_sibling_cdef, instead of some _add_sibling python function provided in the derived class. Therefore, such a highly optimised algorithm wouldn't work on such a type. There's only one way I can think of to get around this, short of dropping some of the desirable properties we want the system to have. We need to introduce yet *another* cdef function, which I will call add_sibling_dispatch. (This solution may have been what Martin proposed in a Seattle coffee shop, although I was too confused at the time to understand what he was saying.) All these functions would behave as follows: ========================================= (1) __add__ will only call add_sibling_dispatch; it doesn't call either _add_sibling or _add_sibling_cdef as it does currently. (2) The default implementation of _add_sibling_cdef in RingElement is to raise NotImplementedError. (3) The default implementation of _add_sibling in RingElement is to call _add_sibling_cdef. No pyrex classes are allowed to override this. (4) add_sibling_dispatch decides whether to call _add_sibling or _add_sibling_cdef. It does this as follows: if HAS_DICTIONARY(self): self._add_sibling(other) else: self._add_sibling_cdef(other) (Even better would be if it could tell whether "self" has an implementation of _add_sibling which is not the default RingElement one, before trying to call it. We have code in there now that does this, but actually it's broken, because it doesn't take into account methods attached directly to the instance; it only looks for methods attached to the instance's class.) (5) No-one is allowed to call _add_sibling_cdef directly, except for add_sibling_dispatch. They should call add_sibling_dispatch instead. There's a speed hit here, which is unfortunate. (Well actually, if a specific piece of code knows the *exact* type of its variables, it could call _add_sibling_cdef directly if it wanted to, for a tiny bit of extra speed.) ========================================= In other words, add_sibling_dispatch is simulating function overrides. (Talk about getting into the language design business.) This is all horribly complicated. Probably there's something I've missed.... please tell me if it's so! David --~--~---------~--~----~------------~-------~--~----~ 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/ -~----------~----~----~----~------~----~------~--~---