[Numpy-discussion] numarray unfriendly to user defined types

Tim Hochberg tim.hochberg at ieee.org
Fri Sep 26 10:14:07 EDT 2003


Todd Miller wrote:

>I tried out DeferredToByNumArray yesterday morning and was able to get
>it to work as planned with numarray and MA.  So yay!
>  
>
Excellent.

>Yesterday afternoon,  I stopped by Perry's office for a final check, and
>not surprisingly,  there are some aspects of this solution that we've
>overlooked.  So not yay!
>
>Perry pointed out two ways that the DeferredToByNumArray scheme may fall
>apart as our inheritance hierarchy becomes richer:
>  
>
Not so excellent.

>1)  Imagine not one, but two independent subclasses of NumArray, each of
>which want NumArray to defer to them.  Now imagine them trying to
>inter-operate with each other.  In this case, the meaning of the
>expression is determined by the order of the operands, so A+B and B+A
>will either return an A or a B depending on the expression order.
>  
>
I think that this is YAGNI right now, but may well be an issue is 
"proper" subclassing get's implemented. So we may as well think about it 
a bit. I call it YAGNI now because these subclasses either use the 
default __op__ methods, which presently have the same behaviour 
regardless of the subclasses (they always return NumArrays) or they 
define there own __op__ methods in which case they can worry about it ;> 
If NumArray starts to become more friendly to subclassing, this will 
probably change though.

>2)  Imagine again two subclasses of numarray, but this time imagine B as
>a subclass of A.  Here again, both might want to defer to numarray, and
>again, A+B and B+A return different types driven by the type order of
>the expression.
>  
>

I'd make the same comment for this case as for the above case except 
that all else being equal, subclasses should prevail over superclasses.

>I don't have a solution yet, but am hopeful that more free candy will
>fall from the sky... or YAGNI.  Perry pointed out that similar problems
>exist for *any* Python class hierarchy, so we're not alone, and perhaps
>should forget about this until it matters.  If someone sees an easy
>fix,  now would be better than later.
>  
>
Here's some quick thoughts. In order for this to work out sensibly you 
want the order between classes to be transistive and you probably also 
always want to be able to insert a class into the order between any two 
classes  This is equivalent to deciding the op priority based on a 
comparison based on some real number associated with each class. This 
leads to something like:

   
class NumArrayFamily:
    op_priority = 0.0
   
# This makes it compatible with the current proposal , but isn't 
strictly necessary.
class DeferredToByNumarray(NumArrayFamily):
    op_priority = 1000.0
   
class NumArrary(..., NumArrayFamily):
    # ...
    def __add__(self, object):
        if isinstance(object, NumArrayFamily):
            if ((object.op_priority > self.object.op_priority) or
                (object.op_priority == self.object.op_priority) and 
issubclass(object, self.__class__)):
                    return other.__radd__(self)
        return ufunc.add(self, other)


class MySubclassOfNumarray(NumArray):
    op_priority = 10.0 # deffered to by NumArray, but defers to 
DeferredToByNumarray classes.



Of course the user still has to be careful to make sure the priority 
order makes sense and you could have big problems when combining 
packages with disprate ideas about priority levels, but I'm not sure how 
you can get away from that.

-tim



>Todd
>On Wed, 2003-09-24 at 19:55, Tim Hochberg wrote:
>  
>
>>Todd Miller wrote:
>>
>>    
>>
>>>On Wed, 2003-09-24 at 18:27, Tim Hochberg wrote:
>>> 
>>>
>>>      
>>>
>>>>Hi Todd,
>>>>
>>>>There are three ways to spell "defer to me" on the table (the precise 
>>>>details of
>>>>each spelling are, of course, still open for debate):
>>>>
>>>>  1.  numarray.defer_to(my_class)
>>>>
>>>>  2. class ArrayLike(numarray.DeferTo):
>>>>        # ...
>>>>
>>>>  3. class ArrayLike:
>>>>        _numarray_defer_to = True
>>>>       # ...
>>>>
>>>>I'd prefer a non-registration solution since those are both 
>>>>aesthetically displeasing and leave you open to the situation where a 
>>>>class in module A gets registered by module B, but module C expects it 
>>>>not to be registered and everything breaks. Not all that likely, I 
>>>>admit, but let's avoid the registration version if we can.
>>>>   
>>>>
>>>>        
>>>>
>>>I was picturing this as module A registering it's own classes only. 
>>>Nevertheless, inverting the problem and distributing the registration as
>>>you suggested is better.
>>> 
>>>
>>>      
>>>
>>The case you describe probably will describe the majority of actual use 
>>cases, and in fact describes mine. I'm trying to think ahead a bit to 
>>cases may encounter as start using NumArray more extensively. Let's hope 
>>this solution still looks good in six months!
>>
>>    
>>
>>>>The other two solutions are almost equivalent. The one case where 3 has 
>>>>an edge over 2 is if I have an object (not a class), I could potentially 
>>>>set a _numarray_defer_to on the object before passing it to numarray 
>>>>without having to mess with the class
>>>>of the object at all. YAGNI, though.
>>>>   
>>>>
>>>>        
>>>>
>>>I was more concerned about the potential impact of lots of multiple
>>>inheritance, but that's probably just my own personal blend of FUD.
>>>
>>> 
>>>
>>>      
>>>
>>>>The advantage of 2 in my view is that it *does* force you to subclass. 
>>>>With 3, there will be the temptation to poke into some other  module and 
>>>>set _numarray_defer_to on some poor unsuspecting class. This has the 
>>>>same disadvantage as 1, that it could confuse some other poor 
>>>>unsuspecting module. The correct way to do get a deferred class from a 
>>>>third party module is to import and subclass. This works with either 2 
>>>>or 3::
>>>>
>>>> import A
>>>>
>>>> class Klass2(a.Klass, numarray.DeferTo):   #2
>>>>    #...
>>>>
>>>> class Klass3(a.Klass): #3 the good way
>>>>     _numarray_defer_to = True
>>>>    # ...
>>>>
>>>>  A.Klass._numarray_defer_to = True #3 the evil way.
>>>>
>>>>Version 2 is cleaner and encourages you to do the right thing, so I'd 
>>>>prefer that solution.
>>>>
>>>>   
>>>>
>>>>        
>>>>
>>>Good enough for me.  If no one else has any comments, then
>>>numarray.DeferTo is where I'll start implementing.  Tomorrow.
>>> 
>>>
>>>      
>>>
>>One more minor thing. I'm not sure tha DeferTo is ideal as the mix-in 
>>class name. It was perfect for the registration function name, but I'm 
>>not sure it's so clear whether the class or numarray is being deferred 
>>to when you say numarray.DeferTo. DeferToMe is more descriptive, but 
>>seems sort of slangy. DeferredTo is better than DeferTo, but still not 
>>as descriptive as DeferToMe. numarray.DefersTo reads perfect as long as 
>>numarray is included but is a disaster if you read it on your own.  
>>Below I've put down all the ideas I could come up with
>>
>>class CustomArray(numarray.DeferTo)
>>class CustomArray(numarray.DefersTo)
>>class CustomArray(numarray.DeferredTo)
>>class CustomArray(numarray.DeferToMe)
>>class CustomArray(numarray.DeferredToByNumarray)
>>class CustomArray(DeferTo)
>>class CustomArray(DefersTo)
>>class CustomArray(DeferredTo)
>>class CustomArray(DeferToMe)
>>class CustomArray(DeferredToByNumarray)
>>
>>For me it's a toss up between DefferedTo, DeferToMe and 
>>DeferredToByNumarray. The first is a little lacking in descriptive 
>>power, the second is slangy and the third is wordy.
>>
>>-tim
>>
>>[not that this matters much....]
>>
>>
>>    
>>
>>>>regards,
>>>>
>>>>-tim
>>>>   
>>>>
>>>>        
>>>>
>>>Thanks again,
>>>Todd
>>>
>>>
>>>
>>>
>>>
>>> 
>>>
>>>      
>>>
>>
>>
>>
>>-------------------------------------------------------
>>This sf.net email is sponsored by:ThinkGeek
>>Welcome to geek heaven.
>>http://thinkgeek.com/sf
>>_______________________________________________
>>Numpy-discussion mailing list
>>Numpy-discussion at lists.sourceforge.net
>>https://lists.sourceforge.net/lists/listinfo/numpy-discussion
>>    
>>







More information about the NumPy-Discussion mailing list