[Cython] New function (pointer) syntax.

Stefan Behnel stefan_ml at behnel.de
Thu Nov 6 18:59:38 CET 2014


Robert Bradshaw schrieb am 06.11.2014 um 18:15:
> On Thu, Nov 6, 2014 at 12:29 AM, Stefan Behnel wrote:
>> Robert Bradshaw schrieb am 06.11.2014 um 08:34:
>>> I'd like to propose a more pythonic way to declare function pointer
>>> types, namelye
>>>
>>>     type0 (*[ident])(type1, type2, type3)
>>>
>>> would instead become
>>>
>>>     (type1, type2, type3) -> type0 [ident]
>>
>> Not convinced. Looks quite magic, very different from the C that people
>> would know, and takes a while reading from left to right until you see the
>> "->" which is essentially the only indication of what is happening here.
> 
> I suppose it depends on whether one knows just C, is familiar with a
> wide variety of other (more functional) languages. I think it's a lot
> easier for people to read who only know Python, or just a smattering
> of C.

The thing is, in order to use Cython, you currently only need to understand
Python, some C/C++ and a minor bit of special Cython syntax. The more new
syntax we add outside of Python/C/C++, the higher the entry bar is raised
for both the "mostly Python" and "I know C" users.


>> Also, "->" has a widely known meaning in C/C++ which makes the above very
>> confusing. I think in C when thinking about function pointers, and there is
>> no "def ..." keyword indication here that would switch me back to Python
>> (as for signature annotations).
>>
>> I do see the problem of "where did I have to put that '*' again in the C
>> declaration?", but this looks like it will produce more confusion than it
>> avoids.
> 
> Hmm, I hadn't thought of that meaning of ->. I don't think it would be
> as confusing in context, which will be immediately following cdef or
> in a function argument, e.g. one would write
> 
>     cdef (float -> float, float, float) -> float integrator =
> get_integrator(...)

My brain can't even parse that. Does it join as

    (float -> (float, float, float))

or

    ((float -> float), float, float)

?

A ctypedef would definitely help here.


> which doesn't to me look like member access, and is much clear than
> 
>     cdef float (*integrator)(float (*)(float), float, float) =
> get_integrator(...)

Apart from the (*), at least this makes it clear what gets passed into what.


> This becomes especially clear for return types, e.g.
> 
>     cdef ((float -> float, float, float) -> float)
> get_integrator(char* algorithm):
>         if algorithm == ...
> 
> vs
> 
>     cdef float (*get_integrator(char* algorithm))(float (*)(float),
> float, float):
>         if algorithm == ...

Same thing as above. The nesting is clearer in the latter.


>> Many (or most?) function pointer type declarations will come from some C
>> library's header file, so it means making it more difficult for users to
>> copy over the declaration.
> 
> I really hope, in the long run, people won't have to manually do these
> declarations.

They'll definitely stay. At least as an advanced feature and for the simple
(entry) cases, they provide both an easily understandable mapping and a
handy way to tune the declarations to make their usage friendlier in Cython
code.


> As well as making things easier to read, part of the motivation is to
> come up with a syntax for declaring this type without having to add
> the notion of declarators (empty or not) to the grammar. Essentially
> everyone thinks "cdef type var" even though that's not currently the
> true grammar.

True. But why not require at least a ctypedef for these things? Ad-hoc
declaration of C function types is just bound to get in the way of readability.


> Another option that just occurred to me would be the syntax "lambda
> type1, type2, type3: type0" so for this example one would have
> 
>     cdef lambda (lambda float: float), float, float: float integrator
> = get_integrator(...)
> 
> doesn't read as nice to me, but thought I'd throw it out there.

It's funny that lambda uses the same expression separator as the signature
annotations in Py3. Hadn't even noticed that before.

Looks a bit funny at first sight, but definitely clearer than any of the above.

Stefan



More information about the cython-devel mailing list