[Cython] [cython-users] Re: New function (pointer) syntax.

Ian Henriksen insertinterestingnamehere at gmail.com
Fri Nov 7 08:30:47 CET 2014


On Thursday, November 6, 2014 9:48:53 PM UTC-7, 1989lzhh wrote:
>
>
>
>
> > 在 Nov 7, 2014,02:56,Robert Bradshaw <robe... at gmail.com <javascript:>> 
> 写道: 
> > 
> > [Cc'ing elsewhere for more feedback. Also top-posting for initial 
> > impressions before the discussion.] 
> > 
> > Here's some proposed function pointer syntaxes; which are the most 
> > obvious to understand/read/remember? Can you figure them out? 
> > 
> >    cdef float (*F)(float) 
> >    cdef float (*G)(float (*)(float), float, float) 
> >    cdef float ((*H)(char*))(float (*)(float), float, float) 
> > 
> > vs 
> > 
> >    cdef float -> float F 
> >    cdef (float -> float, float, float) -> float G 
> >    cdef (char*) -> (float -> float, float, float) -> float H 
> > 
> > vs 
> > 
> >    cdef lambda float: float F 
> >    cdef lambda (lambda float: float), float, float: float G 
> >    cdef lambda (char*): lambda: (lambda float: float), float, float: 
> float H 
> > 
> > 
> > If you want a hint, the last is something that returns numerical 
> > integration algorithm given a string name. Yes, you could use 
> > typedefs, but you shouldn't have to. especially for the first. 
> > 
>    Here are numba kind function annotation, I guess it may fit in here. 
> cdef float(float) F 
> cdef float(float(float), float, float) G 
> cdef float(float(float), float, float)(char*) H 
> I personally feel this kind of annotation is more packed that using ->. 
>
> Regards, 
> Liu zhenhai
>

Here are my thoughts, for what they're worth.
I actually really like the arrow syntax. It matches the way
that the domains and ranges of functions are often written
mathematically. On the other hand, it does conflict with
the syntax from C.

The syntax from Numba is a really good way to do this as well.
It is just as clear and doesn't conflict with C. Strictly speaking,
it isn't Python, but it would be nice to have similarities in the
syntax for the different packages.

The C syntax is not intuitive. The only benefit there is the
overlap with C. For something this simple, learning the new
syntax is easy enough. It will also

The lambda syntax strikes me as an intuitive solution, but it
isn't particularly clean or concise. If the syntax is going
to change, it would be good to change it to something nicer
than that. I don't think this one would be worth making the change.

All things considered, the Numba syntax looks like the best idea.
The arrows are intuitive as well, but the overlap with the syntax
from C could be a bad thing.

Thanks for looking into this!
-Ian Henriksen


> > 
> >> On Thu, Nov 6, 2014 at 9:59 AM, Stefan Behnel <stef... at behnel.de 
> <javascript:>> wrote: 
> >> 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. 
> > 
> > True. However, " -> return_annotation" is still Python syntax. 
> > 
> >>>> 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) 
> >> 
> >> ? 
> > 
> > The comma token remains lower precedence than about everything else. 
> > It's just like a parameter list 
> > 
> >    cdef integrate(float -> float f, float a, float b): 
> >         ... 
> > 
> > f is something that takes floats to floats. 
> > 
> >> 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. 
> > 
> > Clearly we think differently... I can pick apart the latter 
> > definition, but I have to admit it took a lot longer to type than the 
> > former, and I still see "cdef float blah(...., float, float): ..." 
> > when in fact I'm declaring something that takes a char* (or should 
> > that read, "takes something that dereferences to a char" :-)). 
> > 
> > I am curious, when you read "cdef int * p" do you parse this as "cdef 
> > (int*) p" or "cdef int (*p)" 'cause for me no matter how well I know 
> > it's the latter, I think the former (i.e. I think "I'm declaring a 
> > variable of type p that's of int pointer type.") 
> > 
> >>>> 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. 
> > 
> > I should have said they'll be less common, at least for the "copy 
> > header file" in which I'd rather point to the header file and list 
> > members to declare. For advance use (e.g. you want to mis-declare 
> > types) we'd still need this. 
> > 
> >>> 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. 
> > 
> > Not being able to declare this without a ctypedef would be a weakness 
> > in the language, especially as ctypedefs can't be declared locally. 
> > Also, it just defers the ugliness to elsewhere, e.g. 
> > 
> >    ctypedef float (*FloatFunc)(float) 
> >    ctypedef float (*IntegrateFunc)(FloatFunc, float, float) 
> > 
> > The reason ctypedefs help, and are so commonly used for with function 
> > pointers, is because the existing syntax is just so horrendously bad. 
> > If there's a clear way to declare a function taking a single float and 
> > returning a single float, no typedef needed. 
> > 
> >>> 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 
> >> 
> >> _______________________________________________ 
> >> cython-devel mailing list 
> >> cython... at python.org <javascript:> 
> >> https://mail.python.org/mailman/listinfo/cython-devel 
> > 
> > -- 
> > 
> > --- 
> > You received this message because you are subscribed to the Google 
> Groups "cython-users" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to cython-users... at googlegroups.com <javascript:>. 
> > For more options, visit https://groups.google.com/d/optout. 
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20141106/adc8eda0/attachment-0001.html>


More information about the cython-devel mailing list