Robert Bradshaw wrote:
> On Apr 24, 2009, at 1:24 AM, Dag Sverre Seljebotn wrote:
>> So in the example
>>
>> Point& operator[](int edge);
>>
>> if you wanted to print something when changing a point, you could do
>>
>> PointInPolygon operator[](int edge);
>>
>> instead, and PointInPolygon would contain both a reference to the  
>> Polygon
>> and the index of the edge, and have overloaded "operator=" and  
>> "operator
>> Point" which would work as setitem and getitem, respecticely.
>>
>> So what I'm saying is: Mapping C++ operators to Python operators  
>> and vice
>> versa is difficult, with possibly many special cases where e.g. a  
>> Python
>> setitem operator would map to an entire C++ expression involving many
>> operators.
>>
>> Starting out with the binary operators only is simpler and probably  
>> a good
>> idea :-)
> 
> Perhaps I'm taking a too simplistic view of things, but it seems that  
> all we have to do is figure out whether or not we can pass a given  
> operator onto the C++ code, which is much easier to reason about.  
> Also, because in Python assignment is not an expression, we don't  
> have to worry about its return value.

Hmm. That's a nice perspective to have; but I don't think it is 
"obvious" and leads to some fairly concrete consequences IMO: Operators 
must be declared using the Python operator syntax. So you are never 
declaring anything about "operator[]" in Cython, instead you are 
declaring "what types are allowed for the full statement 'x[i] = y'".

(If we start using C++ syntax but don't support the whole thing in the 
same way it will bring lots of confusion I think.)

This pushes the hard work over to writing of the C++ pxd wrapper 
(whether that's a person or in time an automatic script). I think that's 
a good idea. It also makes Cython's grammar simpler than the alternative.

However, a consequence is that if we support overloading, we must also 
support overloading solely on return values :-) See below.

Some examples:
   int operator[](int idx)
would give
   int __getitem__(int idx)

while

   int& operator[](int idx)
would be declared as
   int __getitem__(int idx)
   void __setitem__(int idx, int value)


A more complicated example, with a collection which can retrieve items 
as either type A or B, but store them as types C or D, using either key 
type K or T:

class ItemAccessor {
     operator A() { ... } // coerce to A
     operator B() { ...}
     ItemAccessor operator=(C value) {
         ...
     }
     ItemAccessor operator=(D value) {
         ...
     }
     ItemAccessor(MyCollection col, K idx) { ... }
     ItemAccessor(MyCollection col, T idx) { ... }
}

class MyCollection {
     ItemAccessor operator[](K idx) { return ItemAccessor(this, idx);}
     ItemAccessor operator[](T idx) { return ItemAccessor(this, idx);}
}

In Cython this would be represtented rather different:

class MyCollection:
     A __getitem__(K idx)
     A __getitem__(T idx)
     B __getitem__(K idx) # note: overloads on return value...
     B __getitem__(T idx)
     void __setitem__(K idx, A value)
     void __setitem__(T idx, A value)
     void __setitem__(K idx, B value)
     void __setitem__(T idx, B value)

So it's not too bad :-)  A combinatorial explosion happens but I don't 
worry too much, in practice it's not likely to become large.

-- 
Dag Sverre
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to