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

2014-11-06 Thread Stefan Behnel
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.

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.

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.

Stefan

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [FEATURE REQUEST] VisualBasic

2014-11-06 Thread Zaxebo Yaxebo
o good, that solved this issue.

Thanks  a lot

Zaxebo1

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [FEATURE REQUEST] VisualBasic

2014-11-06 Thread Stefan Behnel
Zaxebo Yaxebo schrieb am 06.11.2014 um 09:49:
> o good, that solved this issue.
> 
> Thanks  a lot

If you think there's anything missing from the documentation that would
have helped you find these features yourself, please consider submitting a
pull request that improves the current state.

Stefan

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Robert Bradshaw
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.

> 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(...)

which doesn't to me look like member access, and is much clear than

cdef float (*integrator)(float (*)(float), float, float) =
get_integrator(...)

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 == ...

> 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.

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.

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.

- Robert
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Stefan Behnel
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

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Robert Bradshaw
[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.


On Thu, Nov 6, 2014 at 9:59 AM, Stefan Behnel  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 Cyth

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

2014-11-06 Thread Stefan Behnel
Robert Bradshaw schrieb am 06.11.2014 um 19:56:
> On Thu, Nov 6, 2014 at 9:59 AM, Stefan Behnel wrote:
>> Robert Bradshaw schrieb am 06.11.2014 um 18:15:
>>> 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 already said that C function types have their own quirks - I keep writing
(func*) instead of (*func), for example. It feels just arbitrary and fails
to stick in my head. But "->" is too well known as an operator when it
comes to pointers (which function types are in C) to provide for a *more*
readable alternative. Just because some functional languages use it in some
specific way doesn't mean it fits into a language that mixes Python and C.


> I am curious, when you read "cdef int * p" do you parse this as "cdef
> (int*) p" or "cdef int (*p)"

Definitely the former. And the complexity that some type declarations can
take in C (let alone C++) is just devastating.

Problem is, any new syntax in Cython will have to co-exist with the
existing (C) syntax potentially forever, and will add to the language
learning curve. People will learn one syntax, but have to understand the
second syntax in order to read other people's code. And others will start
adopting the new syntax in code that uses the old syntax without cleaning
up first.

If we go that route of adding yet another syntax, it needs to be an obvious
one from both a "C with Python features and syntax" and a "Python with C
datatypes" point of view. In short, it has to fit into the existing
language mix.

Stefan

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Robert Bradshaw
On Thu, Nov 6, 2014 at 11:56 AM, Stefan Behnel  wrote:
> Robert Bradshaw schrieb am 06.11.2014 um 19:56:
>> On Thu, Nov 6, 2014 at 9:59 AM, Stefan Behnel wrote:
>>> Robert Bradshaw schrieb am 06.11.2014 um 18:15:
 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 already said that C function types have their own quirks - I keep writing
> (func*) instead of (*func), for example. It feels just arbitrary and fails
> to stick in my head. But "->" is too well known as an operator when it
> comes to pointers (which function types are in C) to provide for a *more*
> readable alternative. Just because some functional languages use it in some
> specific way doesn't mean it fits into a language that mixes Python and C.

Even Java8 is adopting this token for lambdas, though I have to admit
my bias probably comes at least partially from mathematics (where I
write "let f: Z -> Z be a map from the integers to itself")... and I
was happy that

def foo(a: x, b: y) -> z: ...

simplified nicely down to

(x, y) -> z

but I see your point that this is much more foreign coming from the C
side of things.

>> I am curious, when you read "cdef int * p" do you parse this as "cdef
>> (int*) p" or "cdef int (*p)"
>
> Definitely the former. And the complexity that some type declarations can
> take in C (let alone C++) is just devastating.
>
> Problem is, any new syntax in Cython will have to co-exist with the
> existing (C) syntax potentially forever, and will add to the language
> learning curve. People will learn one syntax, but have to understand the
> second syntax in order to read other people's code. And others will start
> adopting the new syntax in code that uses the old syntax without cleaning
> up first.

I wouldn't say forever. Yes, this sounds a bit like Python 2 vs. 3,
but we could provide a tool to do the conversion (completely correctly
in this case) and as developers often run Cython themselves and ship
the .c files it should be a much less painful transition.

> If we go that route of adding yet another syntax, it needs to be an obvious
> one from both a "C with Python features and syntax" and a "Python with C
> datatypes" point of view. In short, it has to fit into the existing
> language mix.

+1. I hope to get more than two pairs of eyeballs on the issue.

- Robert
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Greg Ewing

Robert Bradshaw wrote:

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.


I don't find *any* of those particularly easy to read in the third
case, or even the second. Using typedefs to make the intention
clear, even if the syntax doesn't require it, seems entirely
appropriate to me.


I am curious, when you read "cdef int * p" do you parse this as "cdef
(int*) p" or "cdef int (*p)"


C syntax is sufficiently well embedded in my brain that I
parse it as "int (*p)", and read it as "p points to an int"
or "p is of type pointer-to-int".

But I don't find myself needing to parse "int * p" very often,
because I always write it as "int *p", and so do most other
people who write C. Whenever I see something like "int * p"
or "int* p", it makes me think it was written by someone who
doesn't understand C very well.

--
Greg
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Robert Bradshaw
On Thu, Nov 6, 2014 at 1:07 PM, Nils Bruin  wrote:
> On Thursday, November 6, 2014 10:57:23 AM UTC-8, Robert Bradshaw wrote:
>>
>> cdef float -> float F
>> cdef (float -> float, float, float) -> float G
>> cdef (char*) -> (float -> float, float, float) -> float H
>
> Is there any precedent for an infix operator in type declarations? I find it
> really surprising.

The "input -> output" syntax is used for anonymous functions and
callable types in several languages, from Haskell to OCaml to Java.
Python 3 introduces -> to annotate function return types in PEP 3107.

> It's a little better with parentheses I think:
>
> cdef (float -> float) F
>
> Without them, the "float F" seems to visually bind much more closely than
> the "float -> float", contrary to your proposed precedence.

Yeah, the parentheses make this more clear, though cdef float ->
(float F) doesn't really have a reasonable interpretation. The syntax
"[type] [space] [name]" is a bit unfortunate--we already have ugly,
special logic to handle things like "cdef unsigned short int foo" or
even worse "def foo(self, int): ..."

> Also, C's
> convention that "a->b == *a.b" makes the "->" use here unexpected,
> especially because it's used in an environment where pointer (type)s are
> involved.

Yeah, Stefan pointed this out too, though we don't use -> in Cython
(except for function return annotation). I think the fact that these
are function *pointers* wouldn't need to be called out, given that
functions can be assigned to function pointers and function pointers
are callable just like functions. They'd behave more like first class
function objects.

>> 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
>
>
> At least this overcomes the infix issue a bit: right from the start, the
> "lambda" hints that this is a function type. However, visually again this
> reads to me (because : in normal writing a : would separate sentences of
> words separated by spaces, hence indicating that a space has higher
> precedence than a colon) as:
>
> cdef lambda float: (float F)
>
> which can be circumvented by parentheses:
>
> cdef (lambda float: float) F
>
> The "lambda" solution doesn't look very appealing here, but I think (with
> parentheses) it is the one that is most likely to be unambiguously clear.

Yeah, it looks funny, but is harder to miss-interpret.

- Robert
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [sage-devel] Re: New function (pointer) syntax.

2014-11-06 Thread Robert Bradshaw
Thanks for all the feedback!


On Thu, Nov 6, 2014 at 7:13 PM, Travis Scrimshaw  wrote:
> Here's my 2 cents.
>>
>>
>> cdef float (*F)(float)
>> cdef float (*G)(float (*)(float), float, float)
>> cdef float ((*H)(char*))(float (*)(float), float, float)
>
>
> I prefer this one because it mimics C function pointers (at least how I
> remember, I'm somewhat rusty).

It is C function pointer syntax... if you consider that a plus (aside
from compatibility).

> When I saw the "->", I thought of pointer
> redirection (without reading the rest of the post which mentioned it) and
> believe it could be a major source of confusion.

I'm surprised so many people are noting this; good feedback.

> However since cython is
> suppose to mimic python as much as possible (please correct me if I'm wrong
> here), perhaps the lambda one is better?

Yeah, it's a bit odd, but less confusing.

A goal is a syntax such that when you look at it you know what it
means, unlike, say, the C syntax that you have to learn how to decode.
When I first saw it in Miranda ages ago, but clearly others think of C
first when they think of something of type "float -> float."



On Thu, Nov 6, 2014 at 8:06 PM, Peter Schay  wrote:
>
> The C function pointer syntax is clever and makes a lot of sense but
> reading/writing a complicated declaration usually feels like I'm solving a
> puzzle.

Exactly what I want to avoid. Certainly violates several points of the
Zen of Python.

> IANACG (I am not a compiler guy) so I am sure there must be some flaw in the
> following but I can't help asking whether there would be anything wrong with
> this form, which reads more like a sentence ("a pointer to a function F with
> args x which returns y"):
>
> cdef lambda F(float): float
> cdef lambda G(
>   (lambda (float): float),
>   float,
>   float
> ): float
> cdef lambda H(char *): (lambda (float, float, float): float)

In Python "lambda (a, b): ..." with the parentheses means a function
taking one argument that's unpacked into two variables.

> One could also use an underscore for the unnamed lambdas, maybe.

One of the main goals is to move away from C style declarators, i.e.
actually have "cdef [type] [name]" instead of "cdef [basetype]
[mix_of_names_and_type_info]. So one would write

cdef (float -> float) f, g, h

to declare three variables of type float -> float. Then we might have
hope of an actual, comprehensible grammar for Cython. (Few folks think
in terms of declarators, so one would write "int[10] x" to declare an
array of size 10 rather than "int x[10].")



On Thu, Nov 6, 2014 at 8:46 PM, Nathann Cohen  wrote:
> Hello !
>
> To me the second looks the most clear. Except that I would have written
>
> cdef (char*) -> ((float -> float, float, float) -> float H) instead of
>
> cdef (char*) -> (float -> float, float, float) -> float H
>
> But well, one gets used to things like that.

Yeah, cdef ( (char*) -> ((float -> float, float, float) -> float) ) H
would be just fine as well for those who like parentheses.

> It is clearer but indeed is it surprising to find such a syntax in Cython...
> Actually like Travis I would expect Cython to support the first, even though
> it is the least obvious...

It does now.

> If both are implemented I will definitele use the second whenever I can :-)

Me too.




On Thu, Nov 6, 2014 at 8:48 PM, 1989lzhh <1989l...@gmail.com> wrote:
>
>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 ->.

That's an interesting alternative. Would float(float)* be a pointer to
a function pointer then? (float*)(float) something that returned a
pointer to a float?

- Robert
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread C Blake
I think you should just use the C declarator syntax.  Cython already
allows you to say "cdef int *foo[10]".  Declarators aren't bad - just
poorly taught, though I can see some saying those are the same thing.
More below.  I absolutely like the declarator one the most, and the
lambda one second most.  Declarator style makes it far easier to take
C code/.h files using function pointers over to Cython.  So, this
discussion also depends on whether you view Cython as a bridge to
C libs or its own island/bias toward pure Py3.

One other proposal that might appease Stefan's "Python lexical cues"
where he was missing "def" would be to take the Python3 function
definition header syntax and strip just variable names.  I.e., keep the
":"s
def foo(x: type1, y: type2, z: type3) -> type0: pass
goes to
(: type1, : type2, : type3) -> type0 [ident]

I don't think that looks like anything else that might valid in C or
Python.  It does just what C does - strip variable names from a function
header, but the ":"s maybe key your brain into a different syntax mode
since they are arguably more rare in C.  (Besides stripping names, C has
some extra parens for precedence/associativity - which admittedly are
tuned to make use-expressions simpler than type-expressions.)  Anyway,
I don't really like my own proposal above.  Just mentioning it for
completeness in case the ":"s help anyone.


Robert wrote:
>I really hope, in the long run, people won't have to manually do these
>declarations.

I agree they'll always be there somehow and also with Stefan's comments
about the entry bar.  So, most people not needing them most of the time
doesn't remove the question.


>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.")
>[..]
>Essentially everyone thinks "cdef type var" even though that's not
>currently the true grammar.
>[..]
>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.

No, no, no.  Look, generations of C/C++ programmers have been done
monumental disservice by textbooks/code/style guides that suggest
"int*  p" is *any less* confusing than spacing "2+3/x" as "2+3 / x".
Early on in my C exposure someone pointed this out and I've never been
confused since.  It's a syntax-semantics confusion.  Concrete syntax
has always been right associative dereference *.  In this syntax family,
the moment any operators []/*/() are introduced, you have to start
formatting it/thinking of it as a real expression, and that formatting
should track the syntax not semantics like in your head "pointer
to"/indirection speak or whatever.  Spacing it as if * were left
associative to the type name is misleading at best.

If you can only think of type decls in general as (type, var) pairs
syntactically and semantically then *of course* you find typedefs more
clear.  They make pairing more explicit & shrink the expression tree to
be more trivial.  You should *still* space the typedef itself in a way
suggestive of the actual concrete syntax -- "typedef int *p" (or
"ctypedef") just like you shouldn't write "2+3 / x".  You should still
not essentially think of "ctypedef type var" *either*, but rather
"typedef basetype expr".  In short, "essentially everyone" *should* think
and be taught and have it reinforced and "gel" by spacing that "basetype
expr" is the syntax to create a type-var bindings semantically, and only
perceive "type var" as just one simple case.  Taking significance of
space in Python/Cython one step further, "int* p" could even be a hard
syntax error, but I'm not seriously proposing that change.  I really
do not think it is "essentially everyone".  You know better as you
said anyway, but are in conflict with yourself, I think syntax-semantics
wise.

Semantically, pointer indirection loads from an address before using,
and sure that can be confusing to new programmers in its own right.
Trying to unravel that confusion with anti-syntax spacing/thought
cascades the wrong way out of the whole situation and contributes
to your blocked assimilation.  *If* the space guides you or barring
space parens guide you, you quickly get to never forgetting that types
are inside-out/inverse/what-I-get-if specifications.  Note that this
is as it would if +,/ had somehow tricky concepts somehow "fixable"
by writing "2+3 / x" all the time.  Arithmetic isn't a binding..so
the analogy is hard to complete, but my point is ad nauseum at this
stage (or even sooner! ;-).  Undermine syntax with contrary whitespace
and of course it will seem bad/be harder.  It might even lock you in
to thought patterns that make it really hard to think about it how
you know you "oug

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

2014-11-06 Thread Stefan Behnel
1989lzhh schrieb am 07.11.2014 um 05:48:
>> 在 Nov 7, 2014,02:56,Robert Bradshaw 写道:
>> 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 ->. 

I find it clearer than any of the above. And it still allows the use of
named arguments, i.e. you could say

cdef char*(float x, int y) F = ...
F(y=1, x=2.0)

Drawback is that you have to parse up to the name in order to distinguish
it from

cdef char*(float x, int y):
...

Then there's also

cdef char*(float x, int y) nogil F

And we have to disallow

cdef char*(float x, int y) with gil F

It gets a bit less readable when you take a proper lower-case variable
name, e.g.

cdef char*(float x, int y) nogil get_gil

We could fix some of that by allowing

cdef nogil:
cdef char*(float x, int y) get_gil

But then, that's adding yet another special case.

Stefan

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


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

2014-11-06 Thread Stefan Behnel
Stefan Behnel schrieb am 07.11.2014 um 08:18:
> We could fix some of that by allowing
> 
> cdef nogil:
> cdef char*(float x, int y) get_gil
> 
> But then, that's adding yet another special case.

... except when it's already supported, which it turns out to be...

Stefan

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel