[Python-Dev] Re: RFC on Callable Syntax PEP

2021-12-20 Thread asleep . cult
This is such a great idea that I think it deserves its own PEP (to compete with 
this one?) Let me explain. PEP 677 was created for the sole purpose of 
replacing typing.Callable, but there are still some other areas where function 
metadata is required. What if we instead introduced a function prototype that 
allows you to "declare" a "function" without a body.

typing example:

import typing

@typing.Callable
def IntToIntFunc(a: int) -> int

def flat_map(
l: list[int],
func: IntToIntFunc
) -> list[int]:
...

ctypes example:

import ctypes

@ctypes.CFUNCTYPE
def f(x: int) -> bool

But of course this comes with a few issues: should it be an expression and if 
so, should the name be optional? How can ParamSpec be handled?
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/XPPZZZWVVW6KRBKYXJKXHPTECRDIOFUE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: RFC on Callable Syntax PEP

2021-12-20 Thread asleep . cult
My proposal wasn't to make the body optional based on the presence of a 
decorator, but rather to return a "function prototype" iff the body does not 
exist (I probably should have made my made my own reply instead of piggybacking 
on his proposal). I also mentioned some form of expression to represent this,  
similar to lambda. Maybe a friendly error message telling the user to use a 
function when this thing is called would alleviate some confusion? I'm not sure 
how one would forget to add the function body anyway.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/3HJY6VGLIWRJ7F4BZBNGNCSJJTXH3CVM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Function Prototypes

2021-12-23 Thread asleep . cult
Hello

In thread about PEP 677, I (with the help of another proposal) came up with an 
alternative to typing.Callable called function prototypes. The basic concept is 
to create a function prototype object when the body of a function is omitted.

The thread can be found here: 
https://mail.python.org/archives/list/python-dev@python.org/thread/OGACYN2X7RX2GHAUP2AKRPT6DP432VCN/

Mark Shannon initially proposed that functions be used as types and provided 
this example:

@Callable
def IntToIntFunc(a:int)->int:
 pass

def flat_map(
 l: list[int],
 func: IntToIntFunc
) -> list[int]:
 

I further proposed that we make the body of a function non-mandatory and create 
a function prototype if it is omitted. I provided these examples:

import typing

@typing.Callable
def IntToIntFunc(a: int) -> int

def flat_map(
l: list[int],
func: IntToIntFunc
) -> list[int]:
...

import ctypes

@ctypes.CFUNCTYPE
def f(x: int) -> bool

I have since taken it upon myself to implement this in a fork of cpython: 
https://github.com/asleep-cult/cpython

To remain consistent with function definitions, I have also added an 
alternative lambda syntax that allows you to annotate arguments and the return 
type. The syntax requires you to parenthesize the argument list:

lambda (a: int, b: int) -> int: ...

This new lambda syntax also allows you to create a function prototype by 
omitting the body. The original example can be rewritten as follows:

def flat_map(
l: list[int],
func: lambda (a: int) -> int
) -> list[int]:
...

Problems:
- It is not possible to use ParamSpec with this
- The lambda prototype syntax might be jarring
- Some people might accidentally forget the function body

Here is some feedback that I have already collected:

"Yeah, making the body optional (without looking at decorators) is not
acceptable either. Too easy to do by mistake (I still do this All. The.
Time. :-)" - Guido van Rossum

"i would strongly prefer this over the existing pep" - Ronny Pfannschmidt

"I find this unnecessary and unreadable.

Python isn't C or Java." - BundleOfJoysticks (Reddit)
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/B6VKYV5TKD2VSK6D2CUN77Q6MI5VIBU5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Function Prototypes

2021-12-23 Thread asleep . cult
Hello and thank you for the much needed feedback.

One thing that you must consider is that function prototypes
have a few implications beyond typing but it seems like you're
only looking at it as a tool for type hinting. The interpreter will
create a function prototype object regardless of if you forget your
decorator, it needs to pass something to the decorator after all.

After reading through your reply, I am seeing that the main concern
is the bloat added by the lambda keyword. My decision to use lambda
instead of introducing a special syntax was one that required heavy
deliberation. I ultimately decided to stick with lambda because it was
consistent with the prototype statement form. The fact that lambda
is hard to type has been felt by almost everyone who has ever used
Python, this isn't just a problem that would be introduced by
function prototypes. PEP 677 has taken the lazy approach to solving
this issue and has prioritized type hinting over functionality. PEP 667
also suggests the usage of => for lambdas which would likely
never be accepted because of the confusion it would cause.
As someone who has used typing with Python, I do think that a new
callable syntax is needed, but I truly believe that PEP 677 is taking the
wrong approach.

So what if we broke every Python program in existence by creating a
new lambda syntax, how would it look? This question is particularly
hard to answer because the body and annotations both need to be
optional. Our best bet is an augmented form of the PEP 677 syntax
that allows you to add a body. Here is an example:

(a: int) -> int: a ** 2

But of course this causes ambiguity when the return annotation and
body are both omitted. One thing that I did consider is simply treating
it like a tuple if there is no return annotation AND there is no body, but
that might lead to confusion. Another thing that I considered is a different
prefix than lambda:

$(a: int) -> int: a ** 2
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/JJZGZ6EK5CY4RADPSQPRDWOB6GXQSSJ3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Function Prototypes

2021-12-23 Thread asleep . cult
> Just to be clear, by "function prototype", do you mean what PEP 677 
> calls a Callable Type?
A "function prototype" would be a concrete type that exists alongside
the function type. The objects would hold the arguments, defaults,
annotations and name of a function.

> What sort of implications beyond typing?
Here are a few places where "function prototypes" would be useful:

import ctypes

@ctypes.CFUNCTYPE
def f(a: ctypes.c_int) -> ctypes.c_int

import abc

class Model(abc.ABC):
def get_id(self) -> int

By returning a concrete object, I leave it up to the implementation
to define its meaning.

> What kind of object does `def Func(a:int)->int` create, if you leave 
> out the decorator? Is that what you are calling a "function prototype 
> object"?
Yes, it would create a "function prototype" object.

> What does it need the @Callable decorator for?
The @Callable decorator is not needed, it's just something leftover from
Mark Shannon's proposal. Interpretation is entirely up to type checkers.

> What happens if you leave out the annotations and just say
> `def Func(a)` alone?
The same thing that happens when you create a function with no annotations.

> Do you have any response to my other criticisms about this syntax?
Maybe I'm misinterpreting your reply, but I don't see any other criticisms
about the syntax besides the one I addressed. The rest seem to be
geared towards Mark Shannon's proposal.

> What does that mean? What is lazy about it?
I called it lazy because it fixes the callable syntax with little to no care
about how it affects the future (if any) of the lambda syntax. I firmly
believe that fixing the callable syntax and revising the lambda syntax
should be done at the same time, or at least done in a way that doesn't
make a new lambda syntax impractical.

> Creating new syntax is backwards compatible: it doesn't break existing 
> code that is syntactically correct.
I meant this in the context of my proposal where the lambda syntax and
"callable" syntax are tightly coupled. Apologies if that wasn't clear.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/4NIP24ZM4SKQVE3KCJA3B2GXMN2SKW43/
Code of Conduct: http://python.org/psf/codeofconduct/