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/
-~----------~----~----~----~------~----~------~--~---

Reply via email to