On Apr 11, 2008, at 1:16 AM, Dag Sverre Seljebotn wrote: > >> The main idea (Lisandro came up with this) is to build these >> capabilities into cython itself by introducing the following syntax: >> >> cdef foo(size): >> cdef double a[size] # This is like the dynamic arrays in C99 >> # do stuff with a, but don't worry about deallocating the memory!!!
I really like this syntax, and it seems easy enough to support. One could then even do things like "for x in a" correctly, do bounds checking (or should we let the user shoot themselves in the foot for speed--or perhaps it could usually be optimized away), and coerce it too (or from?) a Python object. It has one drawback, which is that it can never be re-sized, and nor can it be used in any control structures (e.g. inside an if statement or loop). > It sure looks like it would be convenient; but I'll take the role > as an > advocate against it :-) > > 1) Having "cdef double a[size]" allocate anything is very against the > Python syntax -- nothing is ever allocated in Python without a > function > call and an assignment (same as in Java). To somebody who comes from a > strict Python background and not C, it really looks like only a > variable > type declaration, not object allocation. In Cython, this Python way of > working is mostly kept, and this would be a step *away* from Python in > terms of the "feel" of the language. It looks like cdef double a[10], which is currently legal. > 2) This kind of duplicates the behaviour of the "with" keyword > (which is > not present in Cython today (either), but definitely is a goal, and is > present in current Python). > > However, using the with keyword would be a bit less convenient, given > function template support and with keyword support in Cython it could > look something like this: > > with carray(double, size) as buf: > cdef double* a = buf.data > # do stuff with a > > If you want a different memory allocator, simply use a different > function than carray... > > 3) Long-term Python users with very little C experience might end up > doing something like > > cdef double a[size] > # fill in a > return a If the return type is double*, an error can be given at compile time, and if it's object it could even coerce to a Python list. I would say a can neither be assigned to or used as an assignment to something else--just indexed. > (Or, some more complex variant that we can't emit a warning for). With > the "with" keyword however, Python users will *know* not to return a. I think it will be less clear that a is volatile, as it doesn't show up in the with statement at all (and imagine if the assignment were made much later). > (*) This is assuming a new carray template function as well, and so > assumes even more Cython development. One might have to type "a" as > well > but with type inference it might look something like the above. > > 3) Just an overall comment: I personally think NumPy arrays are > excellent for this. I'd have no problems personally with using a NumPy > array only in order to allocate memory and then pass that memory on > to a > C library for instance. (The problem is, I suppose, having to > depend on > the NumPy library...though investing effort in creating a garbage > collected array type when NumPy already has that seems too much like > reinventing the wheel to me.) This will become more convenient than > today if Cython grows better NumPy support. One can make something much lighter weight than numpy--the PyString_FromStringAndLength example that started this thread is *much* faster than creating a NumPy array, let alone a call to malloc () and free(). Although I don't anticipate using Cython much without having NumPy around, I don't want to make it a requirement for effectively using Cython. >> 3) The trick is to make sure that free(private_ptr) is called when >> the >> function's scope is finished. How can this be done. One way >> would be >> to have a private/hidden python object (it would have to be a C >> extension type) that 1) hold's private_ptr as an attribute and 2) >> calls free(private_ptr) when it is garbage collected. >> > This is very trivially implemented by having Cython automatically wrap > the function with try/finally prior to generating C code. Not going to > be a problem at all. (But it can be done the way you say as well...) It's even easier than that, the generated functions all have a single exit point (once they've successfully parsed arguments at least) that does cleanup code (such as deallocate any remaining temp variables, etc.). This could just be added here. - Robert _______________________________________________ Cython-dev mailing list Cython-dev@codespeak.net http://codespeak.net/mailman/listinfo/cython-dev