On May 11, 2008, at 1:55 AM, Dag Sverre Seljebotn wrote: >> ---------a.pxd---------- >> cdef class A: >> cdef int len >> cdef int* data >> >> cdef inline [final?] int __getitem__(A a, int i): >> """ >> Note that subtypes can't override this. >> """ >> if i < 0 or i > a.len: >> raise IndexError >> return data[i] >> >> ---------b.pyx-------- >> >> from a cimport A >> cdef A(len=10) a = a([1,2,3,4,5,6,7,8,9,10]) # I'll leave the init >> function to your imagination >> print a[9] # the code from __getitem__ gets inlined here, and since >> len is known the a.len is resolved to 10 at compile time. >> >> (Here a.len tries to do a lookup first on the compile time type of a, >> and that failing the runtime type of a. The compile time types need >> not be struct members, but if they're not then they must be specified >> because the "runtime" lookup would fail.) > > On the type arguments solution: > > My first thought is that I don't think it will cover all cases -- if > native C++ template support is added, for instance, then the type > arguments must probably behave differently there. So type arguments in > itself is a more generic thing (related to the parser and type > handling > etc.), and this specifies one concrete use of them (ie, what > happens to > "cdef class"es when given type parameters). > > At first it struck me as way too magic. Then it grew on me. But then I > dislike it again :-) So these are some non-conclusive thoughts: > > 1) A "disadvantage" is that it looks like one has to break down the > type > specification vs. run-time parsing context seperation that we've > talked > about earlier? -- how would you specify that a type parameter "T" > should > take "unsigned short int*"? So to have consistency in any sane way one > needs to make "all compile-time types also available run-time types"
No matter what mechanism is used, the issue of specifying types will take some work. I think the question of having types as parameters in other types is a difficult but somewhat orthogonal issue that needs to be dealt with, and having runtime equivalents of types will play into this (does ctypes already provide a mechanism?). or perhaps A (type=(cdef unsigned short int*)) as a way to bind a parameter to a type. Here "(cdef ...)" would be an allowable expression resolving to some (dynamically generated?) runtype variable that represents this type. > 2) It seems to leave the way open for some confusing (if not > impossible > to solve compiler-wise) results: > > cdef A(len=10) a = ... > cdef A(len=8) b = a # What does this mean? Compile-time error? Yep, compile time error. If a was a plain "cdef A" then it may be a runtime error. Of course if one is feeling risky one can cast ;-). > Note, for instance, that while assigning a ndarray(2, int8) to a > ndarray(3, int8) or ndarray(2, float32); I assume you're trying to say this is not allowed... > it should (or rather, might be > wanted behaviour) for it to be legal to assign ndarray(2, uint8, > flat=True) to ndarray(2, uint8, flat=False); where flat is flag to > toggle multi-dimensional indexing. Perhaps, or one can cast. I think it would also be useful (especially in the context of C++ support) to have the notion of "assignable from." > Also consider: > > cdef A(len=10) a = ... > a.len = 8 # legal or not? Compile-time error--when it does a lookup on a.len, it will note it's trying to assign to a "constant." > cdef A(len=8) b = a # Is this legal now? Nope. The compile-time type of a is fixed. > Such things would have to be described in more detail, and since it is > hard to "guess" what the semantics should be (at least for me) it > might > be an indication that this is too magic. Think of len as an (compile-time fixed) attribute of a which has precedence over, and is used in place of a the (hypothetical runtime) attribute of a. This should answer the semantics questions. Again, it need not actually correspond to a actual attribute of A (in which case trying to access it would be a compile-time error when no compile-time value is given), though often it would. One thing I like about this syntax is that it allows one to write a single piece of code that handles the generic (value only known at runtime) case and can be optimized if the value is known at compile time. - Robert _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
