Ok, been thinking some more. To sum up, what we're after is some way of 
having the following work (A is a class with a value field, printme is a 
method somehow selected for inlining and optimization for Cython):

cdef A a = get_a()
a.printme()
a.printme()

turns into

cdef A a = get_a()
print a.value
print a.value

, while this:

cdef A(value=23) a = get_a()
a.printme()
a.printme()

would be turned into

cdef A a = get_a()
if a.value != 23: raise TypeError(...) # line (a)
print 23 # line (b)
print 23

(This is the final result, not saying it is a recipe for how it happens 
magically).

So, what is happening is that we want to set up some assumptions about 
an object (without actually changing the object); and have the code 
after generated by making use of those assumptions.

I have some seperate proposals building further on Robert's ideas here.

1) An explicit method for the assumptions bit. I.e:

cdef class A:
     cdef int value

     cdef __assume__(self, int value):
         if self.value != value: raise AssumptionError(...)

The argument list to this function is basically a more explicit 
declaration of type arguments. The reason I want this, so explicitly 
(rather than using a more general __coerce__ which must probably also be 
added) is that it hints strongly to the writer of the class A to treat 
self.value as "const". Once an assumption is made by having __assume__ 
called, you cannot "back out" and change self.value. This seem to make 
it explicit that value should be treated as a const after construction; 
and it leaves the contract for the name, number and types of "type 
arguments" on the class creator side rather than the caller side.

In addition to just checking assumptions, this method can also put 
general constraints on the arguments (i.e., "if value < 0: raise 
ValueError(...)").

Important: This does *not* address how one can make optimizations later 
on, line (b), it is simply a way to insert the assumption line, line 
(a). Also, __assume__ can simply be called in the normal way.

2) With this in place, it seems ok to follow Robert's proposal and 
automatically treat fields having the same name as type arguments as 
known compile-time. The parameter list to __assume__ restricts which 
fields can be used.

I am still thinking about something more explicit like

cdef class A:
     cdef int value
     cdef int not_possible_typearg

     __typearguments__ = ["value", "compiletimeonlyarg"]

but it doesn't seem strictly necesarry as the argument list to 
__assume__ can serve the same role; and in a possibly more dynamic way, ie

cdef A(constant_alpha=True, alpha=4) a = x # ok
print a.alpha # ok to optimize...

cdef A(constant_alpha=False, alpha=4) a = x # __assume__ might raise...
# .. run-time error because of invalid combination,
# .. so code below will never run, which is lucky because
# .. alpha is now for some reason changing constantly.
print a.alpha # Will be optimized but never run

3) I still want to throw __init__ into the mix. The main reason: For 
type inference, it would be nice if

A = ndarray(shape=(4, 4), dtype=float64, buffer=arr)

would automatically (because type arguments are somehow interlinked with 
constructor arguments) be type-inferred to

cdef ndarray(shape=(4,4), dtype=float64) A
A = ndarray(shape=(4,4), dtype=float64, buffer=arr)

If so, keeping () for the type argument syntax would also make more 
sense and be less confusing.

Perhaps all that is needed is this rule at the type-inference stage:

  * A call to a known constructor (of a type which is a candidate for 
typing) obviously leads to typing it explicitly
  * At the same time, any arguments passed to the constructor is checked 
for a match with the __assume__ signature -- the arguments that 
__assume__ can take are then put into the type arguments list.

(If so, we can pretty much ignore this for now, but we have a "defense" 
for using the () syntax.)


Dag Sverre


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

Reply via email to