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

2021-12-21 Thread Paul Moore
To me, these are mostly convincing examples that people need to name
parts of a complex type like this :-)

I don't actually find any of the syntaxes better than any other. They
are all a bit bad, but I view that as the fault of the complex nested
types, not the syntax (hence my preference for naming things). It's
hard to give examples of how I'd name things, because you need to know
the "business logic" to name things well, and I don't for these.

Frankly, if people were writing normal Python expressions like this,
everyone would be telling them that Python isn't about writing
one-liners and they should factor out named subexpressions. Why should
type annotations be any different?

Paul

PS If I wanted any improvement for callables, it would be to use
parentheses for the arguments rather than square brackets (which look
too "heavy" in my view). So Callable[(int, str), bool] rather than
Callable[[int, str], bool]. I understand why the outer brackets have
to be square (abuse of indexing notation) but as far as I can see
there's no reason the inner ones need to be (OK, for single arguments,
Callable[(int,), bool] is a bit clumsy...)

On Tue, 21 Dec 2021 at 22:10, Steven Troxler  wrote:
>
> In the example I was aiming for something easy to understand that produced a 
> type illustrating potential problems of PEP 677, which is at its worst when 
> there are callables in both argument and return position. I don't have a 
> great real-world example of this worst-case, most of what I've seen involves 
> simpler and the current PEP 677 proposal isn't as bad.
>
> As for formatting I agree that I wouldn't hand-write the type as
> ```
> ((int) -> float, (str) -> bool) -> (int, str) -> tuple[float, bool]
> ```
> but a lot of code formatters might fight me on this, so I think it's worthy 
> of consideration, and I was trying to illustrate a readability problem and 
> possible fix. Formatting the code nicely so that my proposal looks good would 
> have meant not really engaging with the concern.
>
> If you're looking for examples from real code where Callable is unweildy, 
> Pradeep collected a few at [1] from typeshed although most of them look just 
> fine with the current PEP 677 proposal. A couple examples:
>
> Callable[[AnyStr, Callable[[AnyStr, AnyStr, AnyStr], AnyStr]], AnyStr]
> Callable[[Optional[str], tuple[_Marshallable, ...]], Union[Fault, 
> tuple[_Marshallable, ...]]]
> Callable[[str, Callable[[Iterable[str], str], str]], None]
>
> versus the same types written using the current PEP 677 syntax:
>
> (AnyStr, (AnyStr, AnyStr, AnyStr) -> AnyStr) -> AnyStr
> (Optional[str], tuple[_Marshallable, ...]) -> Union[Fault, 
> tuple[_Marshallable, ...]]
> (str, (Iterable[str], str) -> str) -> None
>
> versus with outer parentheses:
>
> (AnyStr, (AnyStr, AnyStr, AnyStr -> AnyStr) -> AnyStr)
> (Optional[str], tuple[_Marshallable, ...] -> Union[Fault, 
> tuple[_Marshallable, ...]])
> (str, (Iterable[str], str -> str) -> None)
>
> and another idea, requiring both outer parentheses and argument parentheses:
>
> ((AnyStr, ((AnyStr, AnyStr, AnyStr )-> AnyStr)) -> AnyStr)
> ((Optional[str], tuple[_Marshallable, ...]) -> Union[Fault, 
> tuple[_Marshallable, ...]])
> (str, (Iterable[str], str) -> str) -> None)
>
> To me, these are convincing examples of where Callable is hard to read and an 
> arrow syntax is easier, but that doesn't necessarily mean it's worth the 
> price of new syntax.
> ___
> 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/KWQVEQDZFBZDQDLOGATXSFN7KSF4WVYJ/
> Code of Conduct: http://python.org/psf/codeofconduct/
___
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/CMDXHQPLJMGCJLL2SVPFJLC3CRE5AUYU/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2021-12-21 Thread Steven Troxler
In the example I was aiming for something easy to understand that produced a 
type illustrating potential problems of PEP 677, which is at its worst when 
there are callables in both argument and return position. I don't have a great 
real-world example of this worst-case, most of what I've seen involves simpler 
and the current PEP 677 proposal isn't as bad.

As for formatting I agree that I wouldn't hand-write the type as
```
((int) -> float, (str) -> bool) -> (int, str) -> tuple[float, bool]
```
but a lot of code formatters might fight me on this, so I think it's worthy of 
consideration, and I was trying to illustrate a readability problem and 
possible fix. Formatting the code nicely so that my proposal looks good would 
have meant not really engaging with the concern.

If you're looking for examples from real code where Callable is unweildy, 
Pradeep collected a few at [1] from typeshed although most of them look just 
fine with the current PEP 677 proposal. A couple examples:

Callable[[AnyStr, Callable[[AnyStr, AnyStr, AnyStr], AnyStr]], AnyStr]
Callable[[Optional[str], tuple[_Marshallable, ...]], Union[Fault, 
tuple[_Marshallable, ...]]]
Callable[[str, Callable[[Iterable[str], str], str]], None]

versus the same types written using the current PEP 677 syntax:

(AnyStr, (AnyStr, AnyStr, AnyStr) -> AnyStr) -> AnyStr
(Optional[str], tuple[_Marshallable, ...]) -> Union[Fault, tuple[_Marshallable, 
...]]
(str, (Iterable[str], str) -> str) -> None

versus with outer parentheses:

(AnyStr, (AnyStr, AnyStr, AnyStr -> AnyStr) -> AnyStr)
(Optional[str], tuple[_Marshallable, ...] -> Union[Fault, tuple[_Marshallable, 
...]])
(str, (Iterable[str], str -> str) -> None)

and another idea, requiring both outer parentheses and argument parentheses:

((AnyStr, ((AnyStr, AnyStr, AnyStr )-> AnyStr)) -> AnyStr)
((Optional[str], tuple[_Marshallable, ...]) -> Union[Fault, 
tuple[_Marshallable, ...]])
(str, (Iterable[str], str) -> str) -> None)

To me, these are convincing examples of where Callable is hard to read and an 
arrow syntax is easier, but that doesn't necessarily mean it's worth the price 
of new syntax.
___
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/KWQVEQDZFBZDQDLOGATXSFN7KSF4WVYJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: facing the issue for remove the value from list (when value is repeated)

2021-12-21 Thread Ethan Furman

Hello!

The python-dev list is for developing the next version of Python.  For help 
using Python, please send your question to

  python-l...@python.org

Thanks, and good luck!

--
~Ethan~
___
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/UED6OIEVBCF2MW4CPIO7EXYS3OTNTQME/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] facing the issue for remove the value from list (when value is repeated)

2021-12-21 Thread laxmikant5656
Good evening everyone I used python 3.7.3 IDLE i found the bug to solve the 
problem when list contain repetitive value is come i.e. if i want to delete 2 
from list using remove function it's 2 value put containouls 2 and such value 
is remove using any type of loop all element are not delete from list. Any 
higher version cover such type of problem? or any other method for delete such 
value
list1=[1,2,3,2,4,2,7,2,2,2,2,5,5,5,2,4,5,6,7,8]
a=0
while a < len(list1):
if list1[a]==2:
list1.remove(2)
a=a+1
print(list1)
___
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/QJHHX2YAP2TQHS7O545B5GUVPVBJC6ZI/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2021-12-21 Thread Gregory Beauregard via Python-Dev
Ahah, that makes sense. But then I think I buy into your reasoning that this 
isn't really a replacement for callable syntax (although functions as types 
opens up other interesting possibilities). For this and other reasons I'd hate 
to see callable syntax rejected in favor of it, so definite +1 on new callable 
syntax for me.

p.s. I'm +0.5 on | binding tighter than ->
___
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/ZURCWPSOE72MFPWONUIOH3XWVJ6ETWR5/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2021-12-21 Thread Ken Jin
I agree with what Batuhan said. Adding on, I'm very concerned about the 
potential maintenance burden for Python implementations.

Just for typing in CPython, some combination of the following knowledge is 
required to contribute code:
1. Metaclasses
2. Descriptors and CPython dunders
3. C internals due to PEP 585 and 604
4. If we throw in annotations internals, maybe we need some parser knowledge 
too, but this is usually not required.

With the new callable syntax, that likely needs strong parser and compiler 
knowledge. I'm not claiming everyone needs to know all of the above to 
contribute (to the contrary, not knowing most of these is fine), but IMO the 
list is getting very long. I'd be sad if one day new typing contributors feel 
too overwhelmed by typing's implementation complexity (I admit sometimes 
feeling overwhelmed too).

That said, thank you PEP authors for working to make Python's typing syntax 
more elegant. I hope my concerns didn't come across as overly harsh.

- KJ
___
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/YZG53T2D3UO6WZCR5U3N45GVAK3E7JPN/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2021-12-21 Thread Paul Moore
On Tue, 21 Dec 2021 at 18:35, Steven Troxler  wrote:
>
> I've been thinking about readability hard because I share many of your 
> concerns about readability.

Before I comment on syntax, I'd like to question the example:

> An example
> =
>
> The function
> 
>
> To get at what I mean, here's a nice simple function:
> ```
> def zip(f, g):
> def zipped(x: int, y: str):
> return f(x), g(y)
> return zipped
> ```

So my first question is why a generic function like this would limit
the parameters x and y to int and str. Surely this is an entirely
workable function for *any* arguments with the appropriate "shape"? So
how is this a good example of somewhere you'd use types like
Callable[[int], bool] (by the way, where did that "bool" appear from?)
in a signature?

My immediate thought when seeing that zip function is that its type is
"obvious"¹, (takes two functions, returns a function which takes 2
arguments matching the args of the 2 functions and returns a tuple
matching the results of the 2 functions). That type is almost
impossible to express clearly, because it needs pretty complex
generics. But the more important point is that I'd never, **ever**,
want to write that type out longhand. I'd expect a type system to
either infer the type, and it would be anonymous¹, or to give up and
treat it as untyped. One thing I absolutely would not want to do is
over-constrain any of the arguments just to make it possible to write
the type down.

The real issue with this function, in my view, is not expressing
callables, but rather generic type variables ("return a function whose
first argument has the same type as the single argument of the
function which is the first argument of this function..." !!!)

Can you suggest a more "real world" function as an example, which
focuses on the callable syntax and doesn't use things like arguments
called f and g? Maybe a GUI callback with a function argument like
on_click?

¹ By which I mean intuitive, not easy to express in words!!! :-)
² Some languages may allow syntax like `typeof(zip)` to refer to that
anonymous type, but that's a separate point.

> Here's it's type using typing.Callable:
> ```
> typing.Callable[
> [typing.Callable[[int], bool], typing.Callable[[str], float]],
> typing.Callable[[int, str], tuple[bool, float]
> ]
> ```
> which seems ugly. It's actually not bad compared to a lot of production code, 
> but this is the kind of thing that led to PEP 677.

It's massively over-constrained. I assume that's because you're trying
to make a point about Callable[] rather than about generics, but can
you give a realistic example that *doesn't* involve over-constraining
higher order functions?

On a side note, why not name at least some of those function types?
And why not use "from typing import Callable"? It feels like you're
not making enough effort to make your example readable, which
undermines your point as a result.

> ((int) -> float, (str) -> bool) -> (int, str) -> tuple[float, bool]

To your credit, you've made this pretty unreadable, which gives some
balance here :-) Seriously, making it a one-liner with all those ->
arrows is a disaster. Changing the location of the parentheses doesn't
alter that at all.

Rewriting as a multi-line expression:

(
(int) -> float,
(str) -> bool
) -> (int, str) -> tuple[float, bool]

helps quite a bit, but returning a function looks bad here. We're not
writing Haskell, you know ;-)

I'd prefer a "mixed" notation here:

(
(int) -> float,
(str) -> bool
) -> Callable[(int, str), tuple[float, bool]]

I don't honestly think there's a readable "function returning a
function" form here - the chained -> tokens is just awkward. Although
that's clearly a matter of preference, there's never going to be an
objective answer here.

> Here’s the type if we change the syntax to put the right parenthesis after 
> the return type:
> ```
> ((int -> float), (str -> bool) -> (int, str -> tuple[float, bool])
> ```
>
> To my eyes, most of the pain points are now eliminated.
> - there’s never a double-arrow due to callable in return position
> - even for argument types, to my eyes it’s now easier to read

To my mind, the eye is still drawn to the arrows, and the readability
is no better. And the parentheses give me a lisp vibe, for reasons I
can't really pin down but which makes this version *less* readable.

> An added bonus is we no longer have to think about double-arrows when a 
> callable type is in the return position of a function, e.g.:
> ```
> def f() -> (int, str -> bool): ...
> ```

Still looks like double arrows to me, I'm afraid. The parentheses
don't group strongly enough to override the "chain of arrows"
impression.

> And it solves another major usability problem we found - writing optional 
> callables - because it’s now no problem at all to write
> ```
> (int, str -> bool) | None
> ```
> as the type of an optional callable argument.

I guess, but it feels like punctuation 

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

2021-12-21 Thread Steven Troxler
I've been thinking about readability hard because I share many of your concerns 
about readability.

I'm starting to think parenthesizing the outside might work much better in 
practice:
```
(int, str -> bool)
```
instead of
```
(int, str) -> bool
```

This looks a bit less familiar, but it
- eliminates any situation
- helps the eye group together functions (and lets us use an editor's 
go-to-delimiter if we get lost!)


An example
=

The function


To get at what I mean, here's a nice simple function:
```
def zip(f, g):
def zipped(x: int, y: str):
return f(x), g(y)
return zipped
```



typing.Callable


Here's it's type using typing.Callable:
```
typing.Callable[
[typing.Callable[[int], bool], typing.Callable[[str], float]],
typing.Callable[[int, str], tuple[bool, float]
]
```
which seems ugly. It's actually not bad compared to a lot of production code, 
but this is the kind of thing that led to PEP 677.


current PEP 677 proposal
--


With the current PEP 677 proposal, writing the type on one line we get
```
((int) -> float, (str) -> bool) -> (int, str) -> tuple[float, bool]
```

I prefer this to the Callable version. But it’s dense, and I do agree it 
illustrates some readability issues with PEP 677.



Using (int, str -> bool) syntax

Here’s the type if we change the syntax to put the right parenthesis after the 
return type:
```
((int -> float), (str -> bool) -> (int, str -> tuple[float, bool])
```

To my eyes, most of the pain points are now eliminated.
- there’s never a double-arrow due to callable in return position
- even for argument types, to my eyes it’s now easier to read

An added bonus is we no longer have to think about double-arrows when a 
callable type is in the return position of a function, e.g.:
```
def f() -> (int, str -> bool): ...
```

And it solves another major usability problem we found - writing optional 
callables - because it’s now no problem at all to write
```
(int, str -> bool) | None
```
as the type of an optional callable argument.


New edge cases / readability issues?
-

I’m pretty sure *all* existing edge cases and readability issues are basically 
solved by this syntax because the grouping becomes obvious.

The only new edge case I can see is that we might not like `(-> bool)` for 
parameterless callables. I’d be okay with that, but I’d also be down with a 
hack like `(() -> bool)`.

I don’t actually think it matters much - by making this change we would trade 
multiple edge cases in *complicated* examples for a single edge case in the 
*simplest possible* example where readability isn’t a big problem.
___
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/AXRKGCPP2GTDRINQ6NQYM743Y6EH6FO5/
Code of Conduct: http://python.org/psf/codeofconduct/