[Python-Dev] Re: Structural pattern matching and mangling private names

2022-06-15 Thread Daniel Moisset
I don't remember this topic ever being discussed, but still I wouldn't
expect that __something to be mangled, given that it refers to an attribute
of an instance of D.

I might expect that in a "case D(something=__y)" you get the mangling for
__y, but I'm not sure what the implementation does now and I'm writing from
my phone

On Wed, 15 Jun 2022, 20:12 ,  wrote:

> For this code:
>
> class C:
>   def f(self, x):
> match x:
>   case D(__something=y):
> return y
>
> It appears that the name "__something" isn't mangled. Under most other
> circumstances I'd expect this to be mangled to "_C__something". Is this:
> * intentional,
> * accidental, but how that it's done it's the defined behaviour,
> * or a defect?
>
> It doesn't seem like it's explicitly tested for in test_patma.py either
> way.
>
> Thanks
> David
> ___
> 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/LILLO3MBTVY6ZQT3VNUVXATEPS3ASGQF/
> 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/335CR2QTKIP6DLVDCIEAGRKKQW6EU6WK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 653: Precise Semantics for Pattern Matching

2021-02-23 Thread Daniel Moisset
In addition to the changes proposed here that go beyond PEP-634 (which
other people discuss), I find that many of the definitions fail to capture
some of the basic features of PEP-634, especially when nesting patterns.

Take for example: "case [int(), str()]". According to
https://www.python.org/dev/peps/pep-0653/#sequence-patterns that desugars
to:

if $kind & MATCH_SEQUENCE:
if $list is None:
$list = list($value)
if len($list) == len([int(), str()]):
int(), str() = $list   *# This is invalid!*
if guard:
   DONE
In general, the way these semantics are defined non-recursively over
patterns won't be able to work with nested patterns.

I value the idea of having a more accurate definition of what the semantics
are, but this approach doesn't seem to work.

Best,   D.


On Thu, 18 Feb 2021 at 16:45, Mark Shannon  wrote:

> Hi everyone,
>
> I'd like to announce a new PEP.
> https://www.python.org/dev/peps/pep-0653/
>
> It builds on PEP 634 (Structural Pattern Matching: Specification), adding:
>
> More precise semantics.
> A bit more customization for complex classes.
>
> Its also a bit more robust and should be faster (eventually).
>
> The syntax is unchanged, and in most cases the semantics are the same.
>
> As always, comments and suggestions are welcome.
>
> Cheers,
> Mark.
> ___
> 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/O4I345VHIQUXPDJWPDA54RWVXMYEEBRM/
> 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/6RGSDHU7ZB77RTWUS7IBTMCZNLV4NBJH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Concerns about PEP 634

2021-02-06 Thread Daniel Moisset
Hi Mark,

I think some of these issues have already been raised and replied (even if
no agreement has been reached). but this is a good summary, so let me reply
with a summary of responses for this.

On Sat, 6 Feb 2021 at 15:51, Mark Shannon  wrote:

> Hi,
>
> Since a decision on PEP 634 is imminent, I'd like to reiterate some
> concerns that I voiced last year.
>
> I am worried about the semantics and implementation of PEP 634.
> I don't want to comment on the merits of pattern matching in general, or
> the proposed syntax in PEP 634 (or PEP 640 or PEP 642).
>
> Semantics
> -
>
> 1. PEP 634 eschews the object model, in favour of adhoc instance checks,
> length checks and attribute accesses.
>
> This is in contrast to almost all of the the rest of the language, which
> uses special (dunder) methods:
>All operators,
>subscripting,
>attribute lookup,
>iteration,
>calls,
>tests,
>object creation,
>conversions,
>and the with statement
>
> AFAICT, no justification is given for this.
> Why can't pattern matching use the object model?
>

No one has said that "we can't". It's just that "we don't have to". The
underlying mechanisms used by pattern matching (instance check, length,
attribute access) already have their defined protocols and support within
the object model. It's analogous as the way in which  iterable unpacking
didn't need to define it's own object model special methods, because the
existing iteration mechanism used in for loops was sufficient.

This does not exclude possible future extensions to the object model to
include a richer protocol like described in
https://www.python.org/dev/peps/pep-0622/#custom-matching-protocol (where
it also describes why we're not proposing that *now*, why it can be done
later, and why we think it's best to do it later)


>
> PEP 343 (the "with" statement) added the __enter__ and __exit__ methods
> to the object model, and that works very well.
>
>
> 2. PEP 634 deliberately introduces a large area of undefined behaviour
> into Python.
>
>
> https://www.python.org/dev/peps/pep-0634/#side-effects-and-undefined-behavior
>
> Python has, in general, been strict about not having undefined behaviour.
> Having defined semantics means that you can reason about programs, even
> non-idiomatic ones.
> [This is not unique to Python, it is really only C and C++ that have
> areas of undefined behaviour]
>

The C standard uses a very peculiar definition of "undefined behaviour"
(I'm not familiar with the C++ one to assert anything, I'll assume it's the
same), where for certain set of programs, any resulting behaviour is valid,
even at compile time (so a compiler that deletes all your files when trying
to compile "void f() {int a[10]; a[10]=0;}" is standard compliant).
Comparing that with the use of the term "undefined behaviour" in the PEP is
not very useful, because even if they are the same words, they don't have
the same meaning

If you want to compare it with the C standards, the term we'd use would be
"implementation defined behaviour". Python has a lot of those. For example,
the output of all these python programs can change between implementations
(And some of these even change between versions of cpython):

   - print({3,2,1})
   - print(hash("hello"))
   - if id(1) == id(1): print("hello")
   - import sys; print(sys.getsizeof([]))

Some order of operations is also implementation dependent for example in
def foo():
   print(open("/etc/passwd")).read()
foo()

The moment where file closing happens is implementation dependent.

The section you linked to introduces behaviour in similar lines to all of
the above.


> I can see no good reason for adding undefined behaviour. It doesn't help
> anyone.
>
>
It helps for the point 3 that you mention (See below)


> The lack of precise semantics makes programs harder to understand, and
> it makes the language harder to implement.
> If the semantics aren't specified, then the implementation becomes the
> specification.
> This bakes bugs into the language and makes it harder to maintain,
> as bug-for-bug compatibility must be maintained.
>
>
> 3. Performance
>
> PEP 634 says that each pattern must be checked in turn.
> That means that multiple redundant checks must be performed on (for
> example) a sequence if there are several mapping patterns.
> This is unnecessarily slow.
>

What PEP 634 says about this(unless we're reading different sections, a
quote could help here) is that the semantics are the one of selecting
the *first
case block whose patterns succeeds matching it and whose guard condition
(if present) is "truthy"*.

As long as the semantics are respected, a smart compiler could reduce some
of the redundant checks (and that's *precisely* why the order of the checks
is left as implementation dependent).

It's important here to separate "sequential semantics" vs "implemented as
sequential checks". For an analogy, look at the "serializable" concept in
databases, where the outcome of 

[Python-Dev] Re: Pattern Matching Scope

2020-12-04 Thread Daniel Moisset
This is an answer to "what PEP 634 proposes":

On Fri, 4 Dec 2020 at 19:18, Jim J. Jewett  wrote:

> (...)
> I'm getting a bit confused over when people mean "the PEP currently says"
> vs "the implementation probably should" vs "the PEP should additionally
> require" vs "the PEP should instead say".
>
> To be more specific, I'm not sure what is intended for the 2nd or 3rd case
> below, which reuse a variable "bound" by the first (failed) match.  Nor am
> I sure whether it matters that the first match fails on the guard
> predicate, instead of immediately on the match.
>
> case (a, b, c) if f():  # assume f() returns false
>

This will guarantee binding of a, b, and c when the subject is a sequence
of 3 elements. Otherwise, which are assigned is implementation defined.
Nothing of this is affected in any way by the behaviour of f, and the
binding is guaranteed to be done before f is called.


>
> case (a, b) if a == c:  # is a still bound from case above?  Is that
> implementation-dependent?
>

This will guarantee binding of a and b when the subject is a sequence of 2
elements. Otherwise, which are assigned is implementation defined. Nothing
of this is affected in any way by the behaviour of a==c, and the binding is
guaranteed to be done before the equality is computed.


>
> case (d = a):  # is a still bound from case above?  Is that
> implementation-dependent?  Is it even still possible to put restrictions in
> before the guard clause, like d=4?
>

This is a SyntaxError, (d=a) is not a pattern.

To summarize:
* on a successful match of the *pattern* (ignoring the guard), all captured
variables are bound, and that happens before the guard is evaluated
* on a failed match, an arbitrary subset of the variables may be bound, and
the guard is guaranteed to not be evaluated.

My previous belief was that this was implementation defined, because the
> cases could be processed in parallel, so that the first case might not have
> finished by the time variable a was needed in the later cases.  My reading
> of PEP 634 suggests that there is a linearization, but only of the guards,
> so ... now I am not sure.
>
> -jJ
> ___
> 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/F5KRIPR4HUDG6TIUWLYBD6CBUFKPLYVF/
> 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/V5DDEGA6CQLBQCMMRCS5QUKGTN37R6BC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Words rather than sigils in Structural Pattern Matching

2020-11-22 Thread Daniel Moisset
On Sun, 22 Nov 2020 at 00:31, Greg Ewing 
wrote:

> On 22/11/20 6:47 am, David Mertz wrote:
> > I'm convinced by Guido,
> > Brandt, and others that the binding  use will be far more common, so
> > adding extra characters for the 90% case does not feel desirable
>
> Minimising the number of characters is not the only consideration.
> Readability counts too, and I think the proposed DWIM rules suffer
> in the readability area.
>
> There are about five different contexts in which a bare name can
> appear as part of a match case:
>
> * As a constructor name
> * As a bare name in an argument position
> * As part of a dotted expression
> * On the left of an =
> * On the right of an =
>
> Only in some of those contexts is it treated as a name to be
> assigned. That's a fairly complex bit of mental parsing to do
> when reading a case.
>
>
Hi Greg,

Look at the following (non-pattern-matching) snippet:

event = datetime.date(x, month=y, day=z)


you have bare names appearing as:
* a constructor name (date)
* bare name in an argument position (x)
* part of a dotted expression (datetime, date)
* left of = (event, month, day)
* right of = (y, z)

some of them are lookups in the namespace (datetime, x, y, z). Others are
targets to write (event). "date" is actually a literal to be used as
attribute lookup, for reading (a key in the module dictionary). "month" and
"day" are literals to lookup in the list of formal parameters of a
function, for writing into the new function stack frame.

I never found Python students struggle too much with the line above, and I
don't expect it to be much different for names in patterns. Names in Python
can appear with a lot of different "roles" in a lot of different contexts,
but the context is usually easy to recognise (is it left or right of a
chain of dots? does it have an = on the left or right? is it in an argument
list? a parameter list?).

Of course I can never deny if you tell me "I find this syntax hard to read"
(only a person can decide what's easy or hard to read for them), but I
don't think this "bare names appear in many contexts" is a solid
explanation.

A hypothesis I have is that many readers of the PEP have been scared of
these semantics because they have been laid bare when explaining them in
detail, but would never notice in day to day life, in the same way that
most Python users would never stop twice to look at the meaning of "a.b.c =
0", even if a semantic description requires us to describe that each of the
three names has a different role ("a" is a lookup in the current scopes,
"b" is a constant name for the purpose of reading attributes, and "c" is a
constant name for the purpose of writing attributes). But looking at the
details description of what's going on under the hood is scarier than the
intuitive look, and when people read the PEP they are looking under the
hood rather than looking at this as users. This is guesswork and could be
absolutely wrong, but I hope it helps read this with a different set of
eyes.



> --
> Greg
> ___
> 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/LMALNSPBLL3MHFOJHBGGO24IDS6CI5R3/
> 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/6VKTXLNWA6ZAXS6TQRT6Z3HS7F2OQLIL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The semantics of pattern matching for Python

2020-11-22 Thread Daniel Moisset
Others have replied with most of this covering my opinion but there's a
point I'd like to highlight here

On Fri, 20 Nov 2020 at 14:23, Mark Shannon  wrote:

> Hi Daniel,
>
> On 20/11/2020 10:50 am, Daniel Moisset wrote:
> >  (... snipping for brevity ...)
> >
> >  1. You mention a goal about "erroneous patterns" (which I'm still not
> > sure I agree on), and your proposal addresses that by forcing
> > classes to be explicit (via __atributes__ and __deconstruct__) about
> > what attributes are accepted as matches. This is against one design
> > principle that's not in your list but it was (at least implicitly)
> > in PEP622 and 634: "pattern matching must allow matching objects on
> > types not specifically designed for it"; this will allow to apply
> > this feature to classes that you can not modify (like instances
> > created by a 3rd party library ). That's why PEP634 relies on
> > getattr() ; that could be extended in the feature (providing some
> > override using attributes like yours) but that wouldn't be required
> > by default
>
> Why force pattern matching onto library code that was not designed for
> pattern matching? It seems risky.
>
> Fishing arbitrary attributes out of an object and assuming that the
> values returned by attribute lookup are equivalent to the internal
> structure breaks abstraction and data-hiding.
>
> An object's API may consist of methods only. Pulling arbitrary
> attributes out of that object may have all sorts of unintended
> side-effects.
>
> PEP 634 and the DLS paper assert that deconstruction, by accessing
> attributes of an object, is the opposite of construction.
> This assertion seems false in OOP.
>
>
I think your description about what you and I call OOP lies at the center
of why we're unlikely to agree on what's the best approach on class
patterns.

The Python I write and tend to use allows and encourages the use of the dot
operator (aka "Fishing arbitrary attributes out of an object") and the
libraries I use expose through it important parts of the API which
doesn't follow the style you mention where  "An object's API may consist of
methods only.". Of course I rely on properly documented attributes, like
datetime.date.year, Fractional.denominator, JSONDEcodeError.message (in the
stdlib) or fields I defined in my django models, or things like
requests.response.status_code (in 3rd party libraries that I used as is or
by extending). Those are all types of objects that I'd like the proposal to
allow as subjects of a match statement and attributes that I'd like to have
in lookups. Given that I can not force a lot of 3rd party libraries to add
a new special attribute `__attributes__`, our proposal relies on the
standard `getattr()` API (which is the core operation on Python object
model to doing most things with an object, even calling methods).

I've used other OOP languages within that style were attributes have to be
explicitly exposed, and even so that's disencouraged and they follow the
principle of "API=only methods". And I can imagine some people could choose
to write Python like that, even if I don't and most of the libraries I use
don't either. For people with that philosophy about OOP, our pattern
matching proposal will be horrible and useless and they can choose not to
use the match statement, ever. The argumentation behind the proposal is
implicitly based on the assumption that *most* Python developers consider
the dot operator one of the "natural" ways to expose object interfaces in
Python, even if it can pull attributes and use non-method APIs. If you
think that assumption is false, we'll have to agree to disagree but I don't
see how we could get to a common vision on how class patterns should behave.

(...)
> When we added the "with" statement, there was no attempt to force
> existing code to support it. We made the standard library support it,
> and let the community add support as and when it suited them.
>
> We should do the same with pattern matching.
>

With our proposal, nothing forces the existing code to support it, they
support it naturally using their existing attribute access API (through the
dot operator). One advantage that the with statement had is that it's quite
easy to wrap an object that wasn't designed to be used as context manager
in another that can (the stdlib even provides a common example of that with
contextlib.closing). Trying to use something like that (writing "match
wrapper(obj): ..." where obj doesn't support some match protocol and the
wrapper adds it) is non viable in pattern matching, because there are many
cases where the object that needs support might be many levels of
indirection (through item/key/attribute access) behind the subject

[Python-Dev] Re: The semantics of pattern matching for Python

2020-11-20 Thread Daniel Moisset
Hello again Mark, I took some time looking in more detail at your proposal,
and these are my thoughts. I'm writing with the assumption that this
proposal describes some "internal" representation of match statements which
is never exposed to the users (so I'd mostly steer away from
lexical/syntactic preferences).

My first general thought is that this is a useful way to describe and
discuss implementation, although I wouldn't wait on refinement of this to
choose whether to accept/reject PEP 634 (or 642, or your favourite
alternative), work can be done on parallel. It may be a good idea to wait
for your proposal to be refined before landing a specific implementation
into CPython (including how the chosen implementation, assuming it's
accepted, desugars into your semantics).

Going into more details, here's a list of thoughts on more specific points:


   1. You mention a goal about "erroneous patterns" (which I'm still not
   sure I agree on), and your proposal addresses that by forcing classes to be
   explicit (via __atributes__ and __deconstruct__) about what attributes are
   accepted as matches. This is against one design principle that's not in
   your list but it was (at least implicitly) in PEP622 and 634: "pattern
   matching must allow matching objects on types not specifically designed for
   it"; this will allow to apply this feature to classes that you can not
   modify (like instances created by a 3rd party library ). That's why PEP634
   relies on getattr() ; that could be extended in the feature (providing some
   override using attributes like yours) but that wouldn't be required by
   default
   2. We considered and discussed something similar to the __deconstruct__
   approach (as an override for getattr()), and also noted is potentially
   expensive, requiring to allocate an object and evaluate *all* attributes,
   even if only one is required. That is against the principle of " it should
   perform at least as well as an equivalent sequence of if, elif statements."
   3. You removed or patterns, and added multiple "case P" for each case
   body. This easily covers cases where the multiple options are at top level
   in the pattern, but if the or-pattern is in a subpattern you have to
   duplicate much of the outer context. And this "duplication" is actually
   exponential on the number of or patterns, so for matching the pattern
   "[0|1, 0|1, 0|1, 'foo'|'bar'|'baz']" you need to desugar this into 24 case
   clauses.
   4. Something else about decomposing patterns into multiple case clauses
   is that it makes it harder to express the constraint that all alternatives
   must bind the same variable.
   5. I found a bit confusing to read the multiple cases on top. It looks
   like C switch statements, which fall-through by default, but in a context
   where some case clauses do fall-through (if empty) and others aren't (if
   they have a body, even if it's "pass"). I know this is not user exposed
   syntax so it's not that important, but this made the description harder to
   read for me.
   6. Given the previous points, added to not seeing the gains of not
   putting the or patterns into the desugared version, I'd prefer it to be
   included in the desugaring.
   7. I think there's some surprising behaviour in the assignments being
   done after a successful match but before the guard is evaluated. In your
   proposal the guard has no access to the variables, so it has to be compiled
   differently (using $0, $1, ... rather than the actual names that appear in
   the expression). And if this guard calls a function which exposes those
   variables in any way (for example if the variable is in a closure) I think
   the behaviour may be unexpected /surprising; same if I stop a debugger
   inside that function and try to inspect the frame where the matching
   statement is.
   8. I like your implementation approach to capture on the stack and then
   assign. I was curious if you considered, rather than using a variable
   number of stack cells using a single object/dict to store those values. The
   compiler and the generated bytecode could end up being simpler, and you
   need less stack juggling and possibly no PEEK operation. a small list/array
   would suffice, but a dict may provide further debugging opportunities (and
   it's likely that a split table dict could make the representation quite
   compact). I know this is less performant but I'm also thinking of
   simplicity.
   9. I think your optimisation approaches are great, the spec was made lax
   expecting for people like you to come up with a proposal of this kind :) I
   don't think the first implementation of this should be required to
   optimize/implement things in a certain way, but if the spec is turned into
   implementation dependent and then fixed, it shouldn't break anything (it's
   like the change in dictionary order moving to "undefined/arbitrary" to
   "preserving insertion order") and can be done later one

Thanks 

[Python-Dev] Re: Questions about about the DLS 2020

2020-11-19 Thread Daniel Moisset
A notorious example here of the "not many" is this proposal (i.e. not part
of the language yet) for C++:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r0.pdf . I
think it's an interesting example given that this is a very mature
language, not originally designed with pattern matching in mind, where _ is
normally an identifier.

Best, D.

On Tue, 17 Nov 2020 at 19:30, Brett Cannon  wrote:

>
>
> On Mon, Nov 16, 2020 at 9:03 AM Tobias Kohn  wrote:
>
>> Hi Mark,
>>
>> Thank you for your interest and the questions.
>>
>>
>> 1.  This really comes down to how you look at it, or how you define
>> pattern matching.  The issue here is that the concept of pattern matching
>> has grown into a large and somewhat diverse flock of interpretations and
>> implementations (as a side note: interestingly enough, some of the only
>> universally agreed-upon standards are to use `_` as a wildcard and not to
>> mark names that capture/bind values---which are quite exactly the points
>> most fiercely debatted here).
>>
> How many of those languages added pattern matching *later* and not at the
> earliest stages of the language (if not from the beginning)? And for those
> that added it later, how many of those didn't already have a convention
> surrounding "_"? My suspicion is "not many" and "not many". 
>
> -Brett
> ___
> 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/VZHF7GJ637YULIU53MCCH26T4LWJ2YP6/
> 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/RBVIQ3WG4AFNJ7WKMNSXISR5X3LSJ2KO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The semantics of pattern matching for Python

2020-11-18 Thread Daniel Moisset
[sorry for the duplicate, meant to reply-all]

Thank you for this approach, I find it really helpful to put the
conversation in these terms (semantics and guiding principles).

This is not an answer to the proposal (which I've read and helps me
contextualize) but to your points below and how they apply to PEP-634. I'm
also answering personally, with a reasonable guess about what the other
authors of 634-636 would agree, but they may correct me if I'm wrong.

On Mon, 16 Nov 2020 at 14:44, Mark Shannon  wrote:

> (...)
> I believe that a pattern matching implementation must have the following
> properties:
>
> * The semantics must be precisely defined.
> * It must be implemented efficiently.
> * Failed matches must not pollute the enclosing namespace.
> * Objects should be able determine which patterns they match.
> * It should be able to handle erroneous patterns, beyond just syntax
> errors.
>
> PEP 634 and PEP 642 don't have *any* of these properties.
>

Let me answer this one by one:

1. "The semantics must be precisely defined":
If this happens in PEP634 I don't think it was intentional, and I'm pretty
sure the authors would be happy to complete any incompleteness that it has.
I would happily have a more accurate description (I drafted a non-official
one for a much earlier version of PEP-622,
https://github.com/dmoisset/notebook/blob/master/python/pep622/semantic-specs.md
).
Can you clarify where you see these imprecisions?

2. "It must be implemented efficiently":
I don't think "efficient implementation" was a priority in PEP634,
although I saw your proposal defines this as "same performance as the
equivalent if statement", and I'm quite sure that level of performance can
be achieved (if it isn't already by Brandt's implementation). Finding the
best way to optimise wasn't a priority, but I think if there was anything
in our implementation that would make optimisations harder we would
consider them as a change. Do you think anything like that has been
presented?

3. "Failed matches must not pollute the enclosing namespace":
This for me is one of the less-desirable parts of the proposal, and was
agreed more as a matter of practicality and an engineering tradeoff. If you
have a reasonable way of solving this (like putting matched variables in
the stack and popping it later) reasonably I'd be much happier putting that
in.

4. "Objects should be able determine which patterns they match."
This is something that you and I, and most of the authors of 622 agree on.
What we found out when discussing this is that we didn't have clear what
and how to open that customization. Some customization options added a lot
of complexity at the cost of performance, some others were very simple but
it wasn't clear that they would be actually useful, or extensible in the
future. This has a lot to do with this being a somewhat new paradigm in
Python, and our lack of knowledge on what the user community may do with it
beyond what we imagined. So the decision was "pattern matching as it is
presented without extensibility is useful, let's get this in, and once we
see how it is used in the wild we'll understand better what kind of
extensibility is valuable". For a crude analogy, imagine trying to get the
descriptor protocol right when the basic python object model was being
implemented. These things happened as different times as the use of the
language evolved, and my opinion is that customization of the match
protocol must follow a similar path.

5. "It should be able to handle erroneous patterns, beyond just syntax
errors."
I'll be answering this based on the example in your document, matching
RemoteCount(success=True,
count=count) where RemoteCount is a namedtuple. The code is likely an
error, and I'm in general all for reporting errors early, but the kind of
error detection proposed here is the kind of errors that python normally
ignore. I find that example really similar to the kind of error you could
make writing "if remcount.count == 3: ..." or going beyond this example
"maxelems = configfile.read(); if len(elems) == maxelems: ...". There are
many type errors that python ignores (especially related to equality), and
Python has already made the decision of allowing mixed type equality
comparisons everywhere, so why do you think pattern matching should be
different with respect to this? In my opinion trying to "fix" this (or even
agreeing if this is a bug or not) is a much more general issue unrelated to
pattern matching. Given the current status-quo I normally trust python type
checkers to help me with these errors, and I'd expect them to do the same
with the "erroneous" match statement.
If there are other examples you had in mind when you wrote this I'd also be
happy to discuss those.

I'll try to get some time to review your specific counterproposal later,
thanks for it.

Best,
Daniel

>
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to 

[Python-Dev] Re: PEP 617 -- New PEG parser for CPython

2020-10-08 Thread Daniel Moisset
In this case, you can use the old parser as an oracle, at least for python
3.8 syntax. The new parser should produce a syntax error if and only if the
old one does. And if it doesn't the AST should be the same I guess (I'm not
sue if the AST structure changed)

On Thu, 8 Oct 2020, 03:12 Terry Reedy,  wrote:

> On 10/6/2020 2:02 PM, Guido van Rossum wrote:
> > That's appreciated, but I think what's needed more is someone who
> > actually wants to undertake this project. It's not just a matter of
> > running a small script for hours -- someone will have to come up with a
> > way to fuzz that is actually useful for this particular situation
> > (inserting random characters in files isn't going to be very effective).
>
> Changes should be by token or broader grammatical construct.  However,
> the real difficulty in auto testing is the lack of a decision mechanism
> for correct output (code object versus SyntaxError) other than the tests
> being either designed or checked by parser experts.
>
> Classical fuzzing looks for some clearly wrong -- a crash -- rather than
> an answer *or* an Exception.  So yes, random fuzzing that does not pass
> known limits could be done to look for crashes.  But this is different
> from raising SyntaxError to reject wrong programs.
>
> Consider unary prefix operators:
>
> *a is a SyntaxError, because the grammar circumscribes the use of '*' as
> prefix.
>
> -'' is not, which might surprise some, but I presume the error not being
> caught until runtime, as a TypeError, is correct for the grammar as
> written.  Or did I just discover a parser bug?  Or a possible grammar
> improvement?
> (In other words, if I, even with my experience, tried grammar/parser
> fuzzing, I might be as much a nuisance as a help.)
>
> It would not necessarily be a regression if the grammar and parser were
> changed so that an obvious error like "- " were to be
> caught as a SyntaxError.
>
>
> > "(One area we have not explored extensively is rejection of all
> > wrong programs.
>
> I consider false rejection to be a bigger sin than false acceptance.
> Wrong programs, like "-''", are likely to fail at runtime anyway.  So
> one could test acceptance of randomly generated correct but not
> ridiculously big programs.  But I guess compiling the stdlib and other
> packages already pretty well covered this.
>
> >  We have unit tests that check for a certain number
> > of explicit rejections, but more work could be done, e.g. by using a
> > fuzzer that inserts random subtle bugs into existing code. We're
> > open to help in this area.)"
> > https://www.python.org/dev/peps/pep-0617/#validation
>
>
> --
> Terry Jan Reedy
> ___
> 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/FNMPQUDPZTX7E4CAGDENNFU6AQJJMW34/
> 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/D33DNLDR4Y6HCGL7K3WRDORNMCLDJ6D5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 (Structural Pattern Matching) questions

2020-08-06 Thread Daniel Moisset
Hi Mark,

As the specific author of that example (and the author of the big it had on
a previous version) let me clarify:

The change in semantics is intentional. I could be more explicit, and
preserve semantics, but I actually find very likely that the original code
does not support other sequences because it would make their code more
complicated (so it's a matter of opinion but for me it's a feature, not a
bug)

As for the previous fixed bug, of like to mentioned that I misread the
original code (I tend to use >= rather than > for those comparisons) so I
read "at least one element" rather than "more than one". Again, it may be
subjective taste but I find our version more readable in that respect and
less likely to be misinterpreted (making the bug easier to spot there)

Best,

Daniel



On Thu, 6 Aug 2020, 12:32 Mark Shannon,  wrote:

> Hi,
>
> I have two questions about PEP 622, as it stands.
>
> 1. Is the current version the final version?
>
> 2. Is the difference in semantics between the Django example and the
> proposed replacement deliberate or accidental?
>(The difference being the change in behaviour for sequences other
> than list or tuple).
>
> Cheers,
> Mark.
> ___
> 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/NQBL4S6WTM5647J2YKJNWM446WX3ELHO/
> 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/WA6HJBW4HQWL3ESYKH3PUWVE47TPJOXZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-08-06 Thread Daniel Moisset
Javascript hasn't it yet, but there is an active proposal for it in the
standardization committee: https://github.com/tc39/proposal-pattern-matching


On Wed, 5 Aug 2020 at 21:34, Luciano Ramalho  wrote:

> On Tue, Aug 4, 2020 at 1:37 PM Tobias Kohn  wrote:
> > And experience from other programming languages who took the leap to
> having
> > pattern matching shows that it quickly becomes a quite intuitive and
> easy to use feature.
>
> The languages I know about that have pattern matching had it from the
> start as a core feature.
>
> I am curious to learn about languages that adopted pattern matching
> later in their evolution.
>
> Cheers,
>
> Luciano
>
>
> >
> > Cheers,
> > Tobias
> >
> > P.S. Please excuse my late reply; I am currently on vacation.
> >
> >
> >
> > Quoting Larry Hastings :
> >
> >
> >
> > On 7/31/20 12:36 AM, Tobias Kohn wrote:
> >
> > And since pattern matching is really
> > a new feature to be introduced to Python, a feature that can
> > be seen in different lights, there is no 'Python-Programmer
> > intuition' that would apply in this case.
> >
> > It's not fair to say "intuition doesn't apply because it's new syntax".
> There are plenty of examples of intuition serving a Python programmer well
> when encountering new syntax.  A Python programmer's intuition is informed
> by existing syntax and conventions in the language.  When they see a new
> construct, its similarity to existing constructs can make understanding the
> new syntax quite intuitive indeed.
> >
> > Take for example list comprehensions.  Python 1 programmers hadn't seen
> >
> > a = [x for x in y]
> >
> > But they knew what square brackets meant in that context, it meant
> "creates a new list".  And they knew what "for x in y" meant, that meant
> iteration.  Understanding those separate two concepts, a Python 1
> programmer would be well on their way to guessing what the new syntax
> meant--and they'd likely be right.  And once they understood list
> comprehensions, the first time they saw generator expressions and set and
> dict comprehensions they'd surely intuit what those did immediately.
> >
> > The non-intuitiveness of PEP 622, as I see it, is that it repurposes
> what looks like existing Python syntax but frequently has wholly different
> semantics.  For example, a "class pattern" looks like it's calling a
> function--perhaps instantiating an object?--but the actual semantics and
> behavior is very different.  Similarly, a "mapping pattern" looks like it's
> instantiating a dict, but it does something very different, and has
> unfamiliar and seemingly arbitrary rules about what is permitted, e.g. you
> can't use full expressions or undotted-identifiers when defining a key.
> Add the "capture pattern" to both of these, and a Python programmer's
> intuition about what this syntax traditionally does will be of little help
> when encountering a PEP 622 match statement for the first time.
> >
> > Cheers,
> >
> >
> >
> > /arry
> >
> >
> >
> > ___
> > 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/2VRPDW4EE243QT3QNNCO7XFZYZGIY6N3/
> > Code of Conduct: http://python.org/psf/codeofconduct/
>
>
>
> --
> Luciano Ramalho
> |  Author of Fluent Python (O'Reilly, 2015)
> | http://shop.oreilly.com/product/0636920032519.do
> |  Technical Principal at ThoughtWorks
> |  Twitter: @ramalhoorg
> ___
> 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/PI44AV5C2F2IMO6PJSYVJOPXGQ62JMHQ/
> 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/FBBV7LEGZXMMNOW4DZQN6C4FOPT765T2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-12 Thread Daniel Moisset
Hey Larry, just to clarify on a single point you make:

On Sun, 12 Jul 2020 at 10:48, Larry Hastings  wrote:

> [ snip ]
> To address 2), bind '_' when it's used as a name in a pattern.
>
> This adds an extra reference and an extra store.  That by itself seems
> harmless.
>

This is not always just a store. for patterns like `[a, *_, b]` vs `[a,
*ignore_me, b]`, the current semantics mean that the matching process has
to make 2 calls to `__getitem__` on the match subject. The second case
(which would be equivalent to "remove special meaning on _") will have to
actually create a new list and copy most of the original one which can be
arbitrarily long, so this turns an O(1) operation into O(n).

> The existing implementation has optimizations here.  If that's important,
> we could achieve the same result with a little dataflow analysis to
> optimize away the dead store.  We could even special-case optimizing away
> dead stores *only* to '_' and *only* in match/case statements and all
> would be forgiven.
>
This might work, although it's quite different to what python does in
general (are you supposed to see the value of `_` in a debugger? or in
`locals()`?  )

Cheers,
D.
___
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/ROHP3JPDJPFYIOL2ILUAZRL7JHW46NHW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 railroaded through?

2020-07-07 Thread Daniel Moisset
On Tue, 7 Jul 2020 at 15:07, Rob Cliffe via Python-Dev <
python-dev@python.org> wrote:

> (...) Nor am I keen on "expressions" being interpreted
> differently after 'case' than elsewhere in Python.


Python already has "expressions" (intentional quotes) that are interpreted
differently depending on the context. `x` may mean "the value bound to x"
in code like `print(x)`, or "the name x inside some scope" when doing `x =
3`. `x[0]` may mean "calling `__getitem__(x, 0)` in the type of x" , or it
may mean a call to `__setitem__(x, 0, something)` instead if you do `for
x[0] in some_iter`.  `[a, *b]` may mean "build a list with a, and all the
elements that come from iterating b" in some contexts, in other it might
mean "extract one element from an iterator and bind it to a. Then build a
list with the other elements of the same iterator, put them into a new list
, and bind that to b" if you are doing `[a, *b] = myiter`.

Many people in this thread have argued that the double meaning in the PEP
might be confusing, but Python already has a double meaning in other
places. It's so NOT confusing, that people even forget that exists :) It
works because the two meanings are not completely unrelated, and that's
what PEP622 is trying to achieve.

It may be surprising the first time you read the PEP in the air. The
question to answer is if it will be confusing after we've seen this
statement half a dozen of times in our codebases.

Best,
D.




>   But I don't know
> what syntax (where necessary) to suggest.
>  I'm not keen on special treatment of the '_' variable, and would
> prefer to be able to use 'else:' after 'match'.
>
> Best wishes
> Rob Cliffe
>
> On 03/07/2020 15:56, Chris Angelico wrote:
> >
> > The PEP is still a draft and has not been accepted. Don't worry, the
> > normal process is still happening :)
> >
> > Having a reference implementation is a HUGE help, because people can
> > play around with it. There's a fork running an interactive playground
> > so you can go right now and get a feel for the way the syntax works.
> >
> > The implementation has *not* been merged into the CPython trunk. It's
> > not a fait accompli - it's a tool to help people evaluate the proposal
> > (and all of the different variants of the proposal as it evolves).
> >
> > Speaking with my PEP Editor hat on, I would be *thrilled* if more
> > proposals came with ready-to-try code. Only a very few have that
> > luxury, and a lot of the debating happens with nothing but theory -
> > people consider what they *think* they'd do, without actually being
> > able to try it out and see if it really does what they expect. Having
> > a reference implementation isn't necessary, of course, but it's
> > definitely a benefit and not a downside. Also, there HAVE been
> > proposals with full reference implementations that have ended up
> > getting rejected; it's not a guarantee that it'll end up getting
> > merged.
> >
> > Hope that lessens your fears a bit :)
> >
> > ChrisA
> > ___
> > 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/E5U5Z6RRWSWHGXTZEQ6CBPORVXS3CPWD/
> > 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/NWNG5KII3ZJAUZ2J7X7SFV2MIBORIDJR/
> 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/OAJZFHLBY6EF5RIOVQBSU4JWZ54CMIYZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Flexible assignment targets

2020-07-01 Thread Daniel Moisset
If I was to do this in Python, rather than the Rust way of forbidding
refutable patterns, I would put as a rule that the target must have at
least one variable to bind* . It makes sense in the context that the goals
of an assignment are the bindings it does, and the ValueError is an
accident that the binding may be impossible sometimes. It would fit better
with existing destructuring, and the python philosophy of trusting the
developer and protecting the semantics with a runtime check.

* only allowing the historical () I mentioned earlier in the thread for
compatibility with weird programs that no one ever wrote

On Wed, 1 Jul 2020 at 23:24, Devin Jeanpierre 
wrote:

> On Wed, Jul 1, 2020 at 11:31 AM Elliott Chen 
> wrote:
>
>> I guess it might work in a separate PEP, but I'm also a little worried
>> because the current PEP would make that impossible with its subtle
>> incompatibilities with the existing unpacking syntax. Or even more
>> inconsistent, if the assignment target syntax is extended to become similar
>> to the match syntax but still slightly different for backwards
>> compatibility.
>>
>
> In my view 1 = x is a sneaky degenerate case, and what we should really be
> asking is if it's cool to be able to do, say, (x, 0) = a compared with "x,
> y = a; if y != 0: raise ValueError".
>
> BTW, +100% to the idea that match should extend assignment semantics (e.g.
> to allow multiple clauses). The totally new match semantics have come up a
> lot when I discussed this PEP with my friends at work. Even if we get
> awkward corner cases out of unifying the two, the simplicity of only having
> one notion of lvalue, instead of two lvalue-like things, is IMO an
> overriding benefit. This is also more or less how match and assignment tend
> to work in the languages that have pattern matching, .
>
> If we are repulsed by "1 = x" and (x, 0) = y, one solution is to do what
> Rust did and forbid refutable patterns on the left-hand side of an
> assignment, but allow them on the left hand side of a match case. (With the
> historically-minded exception of list and tuple literals). This still makes
> match an extension of assignment (it's assignment + multiple cases +
> refutable patterns) and gives us the simplicity benefits, while forbidding
> "1 = x".
>
> -- Devin
> ___
> 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/IM6NZJSZHID46K3QYGG4GUJ5D6GMMX4P/
> 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/UK4BB72KOLGSUUYYJC5CN4PSMEP36XWV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Flexible assignment targets

2020-07-01 Thread Daniel Moisset
On Wed, 1 Jul 2020 at 15:50, Guido van Rossum  wrote:

> Before we all get a little too excited here, I think that allowing
> ```
> 1 = x
> ```
> as a sneaky way of writing
> ```
> assert x == 1
> ```
> would be a terrible mistake.
>

Well, we'll always have the sneaky way to check if an iterable is empty:

() = x

which admittedly would be useful for entries to the IOPPP (International
Obfuscated Python Program Pageant)


>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/WQCHP4A23CF7HSZTOMJUEFNC2MJPRIST/
> 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/BRY3FJK2IUPXLFUJXPVNS5KDS2ZALMYW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-30 Thread Daniel Moisset
Hi, thank you for the comments

On Tue, 30 Jun 2020 at 07:18, Greg Ewing 
wrote:

> On 29/06/20 8:47 am, Daniel Moisset wrote:
> > <
> https://github.com/dmoisset/notebook/blob/811bf66/python/pep622/understanding-pep-622.md>
>  .
>
>
> You seem to be trying to shoehorn all Python data structures into
> looking like alebraic types, for the sole purpose of being able to
> claim that PEP 622 is really about algebraic types rather than
> pattern matching.
>

There may be a bit of this, I like "unifying concepts". But if I have a
bias, I was heavily pushed by the writing on the PEP. Their inspirations
are explicitly Rust and Scala (which have a very strong "algebraic type"
core),, and in discussions I've seen the authors discuss F# and Haskell
(again with a strong algebraic type influence). If they started on "we were
inspired by C's and Javascript's switch statement and then added some extra
features" I would have a different vision that the focus is
multiple-choice-conditional and the rest are extras. If they mentioned
Javascript destructuring operations as inspiration I would think instead
that the focus is decomposing builtin types and the rest are extras. The
motivation starts discussing about isinstance() checks and extracting
attributes which sounds more like "we added this to have algebraic data
types and hey, now that we're here we can also include some unpacking and
have a switch statement too".

The goal of my notes was to read the PEP between lines, so there's some
personal guess and bias, but it's not out of the blue :)

I don't think that's a helpful way of looking at things. Pattern
> matching with destructuring is a more general concept. Algebraic
> types is just one of its applications.
>

I agree on this statement (except the first sentence :) )... what I'm
trying to say is that the PEP has some underlying algebraic type style and
making it explicit is a way to understand it with different eyes.


> I think your viewpoint is coloured by languages in which algebraic
> types play a much more central role than they do in Python. For
> example, in Haskell, the usual notation for lists is syntactic
> sugar for an algebraic type representing a linked list.
>

Haskell also does some shoe-horning... integers in haskell are supposed to
be an algebraic type made by the union of infinite constructors named "1",
"2", "3", ... :) Even if the implementation is nothing like that, this kind
of shoe-horning is useful allows you to have a coherent story and design,
so I'm looking for somehting close to that in Python.


> But Python lists are not linked lists, they're flexible-sized
> arrays, and you have to squint very hard indeed to see them as
> being fundamentally an algebraic type. Yet pattern matching on
> them makes perfectly good sense.
>

True.  And python has already had that for ages. I'm *guessing* intent here
again, but I believe that was included into the PEP because it was easy,
not because it was the main concern to address.

> returning by default an object __dict__ or some sort of mapping view
> > on the attributes could still be fine. It's not clear to me why the
> > "keys" of this structure are placed separately.
>
> I think the PEP explains the rationale behind the design of the
> matching protocol quite well. The goal is to make it as simple as
> possible to implement in the most common cases.
>

I have improved my understanding of this. I still find the protocol weak
(but mostly the match, not the matched_args) even for the cases that are
desired to be covered, but I'm already discussing those directly with the
authors.

> For me, there should be an instance method in object (that
> > subclasses  can override) that returns the algebraic structure of the
> value.
> > The PEP as-is creates different destructuring views depending on
> > which matching class you use (whicch I think relates to something
> > that was mentioned but not discussed a lot in the python-dev list
> > about Liskov sustitability).
> I think the PEP has this right. Liskov substitutability doesn't apply
> to constructors -- they're not methods, and the constructor of a
> subclass doesn't have to accept the same arguments as that of its
> base class. The same thing applies to deconstructors, since they have
> to mirror the signature of their corresponding constructors. (...)


You're right, it was not Liskov related, but the single argument default
behaviour. I was wrong about this.
___
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/ONVWLWDJZWW2KGCRZPFZ3XXVKTB2JTT7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-28 Thread Daniel Moisset
I've been going over the PEP this weekend, trying to get a
deeper understanding of what are its main ideas and consequences, and wrote
some notes. I'm not posting the notes directly to this list because it's a
bit of a long read, but I also tried to make it helpful as an analysis for
people involved in the discussion. So here's a link:
https://github.com/dmoisset/notebook/blob/811side
of thingsbf66/python/pep622/understanding-pep-622.md

.
I may update this in master, but for clarity I'm permalinking the current
version.

I'll soon switch to "proposing solutions" mode (rather than "analysis mode"
as this text is) soon, but needed to do this first, and hopefully this
helps someone else in this list organise ideas.

Best,

D.


On Tue, 23 Jun 2020 at 17:04, Guido van Rossum  wrote:

> I'm happy to present a new PEP for the python-dev community to review.
> This is joint work with Brandt Bucher, Tobias Kohn, Ivan Levkivskyi and
> Talin.
>
> Many people have thought about extending Python with a form of pattern
> matching similar to that found in Scala, Rust, F#, Haskell and other
> languages with a functional flavor. The topic has come up regularly on
> python-ideas (most recently yesterday :-).
>
> I'll mostly let the PEP speak for itself:
> - Published: https://www.python.org/dev/peps/pep-0622/ (*)
> - Source: https://github.com/python/peps/blob/master/pep-0622.rst
>
> (*) The published version will hopefully be available soon.
>
> I want to clarify that the design space for such a match statement is
> enormous. For many key decisions the authors have clashed, in some cases we
> have gone back and forth several times, and a few uncomfortable compromises
> were struck. It is quite possible that some major design decisions will
> have to be revisited before this PEP can be accepted. Nevertheless, we're
> happy with the current proposal, and we have provided ample discussion in
> the PEP under the headings of Rejected Ideas and Deferred Ideas. Please
> read those before proposing changes!
>
> I'd like to end with the contents of the README of the repo where we've
> worked on the draft, which is shorter and gives a gentler introduction than
> the PEP itself:
>
>
> # Pattern Matching
>
> This repo contains a draft PEP proposing a `match` statement.
>
> Origins
> ---
>
> The work has several origins:
>
> - Many statically compiled languages (especially functional ones) have
>   a `match` expression, for example
>   [Scala](
> http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html
> ),
>   [Rust](https://doc.rust-lang.org/reference/expressions/match-expr.html),
>   [F#](
> https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
> );
> - Several extensive discussions on python-ideas, culminating in a
>   summarizing
>   [blog post](
> https://tobiaskohn.ch/index.php/2018/09/18/pattern-matching-syntax-in-python/
> )
>   by Tobias Kohn;
> - An independently developed [draft
>   PEP](
> https://github.com/ilevkivskyi/peps/blob/pattern-matching/pep-.rst)
>   by Ivan Levkivskyi.
>
> Implementation
> --
>
> A full reference implementation written by Brandt Bucher is available
> as a [fork]((https://github.com/brandtbucher/cpython/tree/patma)) of
> the CPython repo.  This is readily converted to a [pull
> request](https://github.com/brandtbucher/cpython/pull/2)).
>
> Examples
> 
>
> Some [example code](
> https://github.com/gvanrossum/patma/tree/master/examples/) is available
> from this repo.
>
> Tutorial
> 
>
> A `match` statement takes an expression and compares it to successive
> patterns given as one or more `case` blocks.  This is superficially
> similar to a `switch` statement in C, Java or JavaScript (an many
> other languages), but much more powerful.
>
> The simplest form compares a target value against one or more literals:
>
> ```py
> def http_error(status):
> match status:
> case 400:
> return "Bad request"
> case 401:
> return "Unauthorized"
> case 403:
> return "Forbidden"
> case 404:
> return "Not found"
> case 418:
> return "I'm a teapot"
> case _:
> return "Something else"
> ```
>
> Note the last block: the "variable name" `_` acts as a *wildcard* and
> never fails to match.
>
> You can combine several literals in a single pattern using `|` ("or"):
>
> ```py
> case 401|403|404:
> return "Not allowed"
> ```
>
> Patterns can look like unpacking assignments, and can be used to bind
> variables:
>
> ```py
> # The target is an (x, y) tuple
> match point:
> case (0, 0):
> print("Origin")
> case (0, y):
> print(f"Y={y}")
> case (x, 0):
> print(f"X={x}")
> case (x, y):
> print(f"X={x}, Y={y}")
> case _:
> raise ValueError("Not a point")
> 

[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Daniel Moisset
This one is new but I think unrelated and unmentioned:

Why is the mapping match semantics non-strict about keys? Besides the
"asymmetry" with sequence matches, I think a strict match should be useful
sometimes (quickly deconstructing JSON data comes to my mind, where I want
to know that I didn't get unexpected keys). I cannot get that behaviour
with the current pep. But if we make key strictness the default, I can
always add **_ to my mapping pattern and make it non strict (that's
currently forbidden but the restriction can be lifted). Is there an
assumption (or even better, data evidence) that non-strict checks are much
much more common?

A similar but weaker argument can be made for class patterns (although I
can imagine non-strict matches *are* more common in that case).

Mostly but not completely unrelated to the above, and purely syntactic
sugar bikeshedding, but I think having "..." as an alias for "*_" or "**_"
(depending on context, and I'd say it's *both* inside a class pattern)
could make these patterns slightly more readable.

Best,
D.

On Wed, 24 Jun 2020 at 20:44, Guido van Rossum  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/STJSSAETMTUY7FK5AE53IM73Z2WORNYN/
> 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/DS26FCVJ2FCQBRK6OQEBIKYBZPXIIY5P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Daniel Moisset
Just a minor editorial thing on the PEP text:

The section https://www.python.org/dev/peps/pep-0622/#case-clauses presents
a simplified syntax. That one mentions "group_pattern", but the document
never mentions (in prose) what a group pattern is. It confused me until I
found the definition in the full grammar, which seems to refer to those
sequence patterns using () rather than []. Probably it makes more sense for
a quick read to remove the "| group_pattern" from the simplified grammar,
it looks more like an intermediate construct.

On Tue, 23 Jun 2020 at 17:04, Guido van Rossum  wrote:

> I'm happy to present a new PEP for the python-dev community to review.
> This is joint work with Brandt Bucher, Tobias Kohn, Ivan Levkivskyi and
> Talin.
>
> Many people have thought about extending Python with a form of pattern
> matching similar to that found in Scala, Rust, F#, Haskell and other
> languages with a functional flavor. The topic has come up regularly on
> python-ideas (most recently yesterday :-).
>
> I'll mostly let the PEP speak for itself:
> - Published: https://www.python.org/dev/peps/pep-0622/ (*)
> - Source: https://github.com/python/peps/blob/master/pep-0622.rst
>
> (*) The published version will hopefully be available soon.
>
> I want to clarify that the design space for such a match statement is
> enormous. For many key decisions the authors have clashed, in some cases we
> have gone back and forth several times, and a few uncomfortable compromises
> were struck. It is quite possible that some major design decisions will
> have to be revisited before this PEP can be accepted. Nevertheless, we're
> happy with the current proposal, and we have provided ample discussion in
> the PEP under the headings of Rejected Ideas and Deferred Ideas. Please
> read those before proposing changes!
>
> I'd like to end with the contents of the README of the repo where we've
> worked on the draft, which is shorter and gives a gentler introduction than
> the PEP itself:
>
>
> # Pattern Matching
>
> This repo contains a draft PEP proposing a `match` statement.
>
> Origins
> ---
>
> The work has several origins:
>
> - Many statically compiled languages (especially functional ones) have
>   a `match` expression, for example
>   [Scala](
> http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html
> ),
>   [Rust](https://doc.rust-lang.org/reference/expressions/match-expr.html),
>   [F#](
> https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
> );
> - Several extensive discussions on python-ideas, culminating in a
>   summarizing
>   [blog post](
> https://tobiaskohn.ch/index.php/2018/09/18/pattern-matching-syntax-in-python/
> )
>   by Tobias Kohn;
> - An independently developed [draft
>   PEP](
> https://github.com/ilevkivskyi/peps/blob/pattern-matching/pep-.rst)
>   by Ivan Levkivskyi.
>
> Implementation
> --
>
> A full reference implementation written by Brandt Bucher is available
> as a [fork]((https://github.com/brandtbucher/cpython/tree/patma)) of
> the CPython repo.  This is readily converted to a [pull
> request](https://github.com/brandtbucher/cpython/pull/2)).
>
> Examples
> 
>
> Some [example code](
> https://github.com/gvanrossum/patma/tree/master/examples/) is available
> from this repo.
>
> Tutorial
> 
>
> A `match` statement takes an expression and compares it to successive
> patterns given as one or more `case` blocks.  This is superficially
> similar to a `switch` statement in C, Java or JavaScript (an many
> other languages), but much more powerful.
>
> The simplest form compares a target value against one or more literals:
>
> ```py
> def http_error(status):
> match status:
> case 400:
> return "Bad request"
> case 401:
> return "Unauthorized"
> case 403:
> return "Forbidden"
> case 404:
> return "Not found"
> case 418:
> return "I'm a teapot"
> case _:
> return "Something else"
> ```
>
> Note the last block: the "variable name" `_` acts as a *wildcard* and
> never fails to match.
>
> You can combine several literals in a single pattern using `|` ("or"):
>
> ```py
> case 401|403|404:
> return "Not allowed"
> ```
>
> Patterns can look like unpacking assignments, and can be used to bind
> variables:
>
> ```py
> # The target is an (x, y) tuple
> match point:
> case (0, 0):
> print("Origin")
> case (0, y):
> print(f"Y={y}")
> case (x, 0):
> print(f"X={x}")
> case (x, y):
> print(f"X={x}, Y={y}")
> case _:
> raise ValueError("Not a point")
> ```
>
> Study that one carefully!  The first pattern has two literals, and can
> be thought of as an extension of the literal pattern shown above.  But
> the next two patterns combine a literal and a variable, and the
> variable is *extracted* from the target value (`point`).  The fourth

[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Daniel Moisset
[apologies for the duplicate to Guido, used reply instead of reply to all]

To summarize my previous unanswered post, I posted a +1 to the "defaulting
to binding vs interpreting NAME as a constant" is a dangerous default. And
I submitted a couple of alternate syntactic ways to denote "capture is
desired" (the angle brackets, and the capture object). I think both are
reasonably readable, and one of them doesn't even add any unusual syntax
(not even the "dot prefix")

As an elaboration on that, after reading the discussion and trying to not
repeat what has previously been said:


   - I think there's a mismatch between an assumption made by the authors
   vs what many of us are posting here, which is explicitly stated in "
   
https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern;
   : Quoting the PEP: «the name patterns are more common in typical code, so
   having special syntax for common case would be weird». Even if I think a
   popular use case would be analysing and deconstructing complex nested
   structures (like ASTs), I think roughly half of the uses will actually be
   for "the switch statement we never had", where all branches would be
   constants. I've been writing a lot of code like that these last couple of
   weeks, so I may be biased (although the PEP authors may have been writing
   AST visitors this last week and may be biased the other way ;-) )
  - As a sub point, I can understand if the PEP authors argue "match is
  not for that, use if/elif/dicts of functions in that case like you did
  before and ignore this PEP", but if that's the case, that should be
  explicit in the PEP.
   - I am fairly sure (as much as one can be of the future in these things)
   that with this PEP approved as is, linters will add new rules like "you
   have more than a top level name pattern, only the first one will match.
   Perhaps you wanted constant patterns?" and "your pattern captures shadow an
   existing name" and "a name you bound in a pattern isn't used inside the
   pattern". These will definitely help, but for me "how many new linter rules
   will be needed if this language change is introduced" is a good measure of
   how unelegant it is.
  - Perhaps arguing against myself, I know that, thanks to my regular
  usage of linters, I personally won't suffer much from this problem (once
  they get updated). But I also teach Python to people, and I feel that I'd
  have to add this to the list of "gotchas to avoid" if the PEP
passes as is.


Again, I can't write this email without saying that this feature is great,
that the effort put in this PEP is really palpable, that I'd love to find
the way to get it accepted, and that even if I'm normally conservative
upgrading python versions and waiting my environment to support it fully,
this will likely be the first time that I upgrade just for a language
feature :)


On Wed, 24 Jun 2020 at 20:44, Guido van Rossum  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/STJSSAETMTUY7FK5AE53IM73Z2WORNYN/
> 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/NZAQQOXM4K2G4ID4FNWZ6KRDEWFSWDMJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-24 Thread Daniel Moisset
Wow, this looks fantastic, I've wanted this for a long time! I really
appreciate the work that has been put here.

As a bit of context for this and future emails, I fury wanted to say:
* I'm strongly positive about this even if I propose changes
* I've explored a bit on my own how to do this, so I'm (painfully) aware of
some of the design tensions, in particular the "a pattern is neither an
expression(something that you'd fight on the RHS of an assignmen) nor a
target (something you'd find in the LHS of an assignment), but has a little
bit of both"

That being send, here are my comments (which I'll split into separate
emails so we can thread separately):

*The "We use a name token to denote a capture variable and special syntax
to denote matching the value of that variable" feels a bit like a foot-gun*

Other people had said this so, this is mostly a +1, but I wanted to provide
alternatives, and also reinforce that deciding in this way is much more
likely to cause mistakes than the opposite. The most likely mistake seems
for me to be using the normal instead of the "special" syntax (the dot
prefix); if i write "case constant" by mistake now, I'm getting 1) a match
when there likely wasn't one and 2) I clobbered my constant. Both are hard
to debug. If we had special syntax for capture and I wrote "case variable"
by mistake, I would likely get a NameError, which should be easier to
figure out.

I saw some of the rejected approaches (like capturing with $var) and I
found them visually ugly, so I want to put two others on the table, which I
think I found "reasonable":


   - 1.A: use angle brackets for capture:

match get_node():
case Node(value=, color=RED): print(f"a red node with value {x}")
case Node(value=, color=BLACK): print(f"a black node with value {x}")
case : print(f"This is a funny colored node with value {n.value}")

This agains adds new syntax like the original proposal, but I think it
makes the capture quite visible without feeling noisy; it reminds me of
metaparameters in the help for command line tools (i.e. "cp 
"). Even if we had this, I'm happy with "_" as a placeholder
(rather than "<_>"). It should be posible to have <*x> or <**x> in other
patterns (rather than * or **)... and I would probably be happy of
using standalone * and ** rather than *_ and **_ (this last suggestion
could work with the current syntax too).


   - 1.B. use a "capture object". No "new" syntax (syntax for patterns is
   new, but looks like other expressions):

match get_node() into c:
case Node(value=c.x, color=RED): print(f"a red node with value {c.x}")
case Node(value=c.x, color=BLACK): print(f"a black node with value
{c.x}")
case c.n: print(f"This is a funny colored node with value {c.n.value}")

The idea here is that instead of spreading captured names into the local
namespace, we only have a single capture object in the locals, and all
captures happen inside it. This also allows to syntactically (although not
in the grammar) to recognize what is a variable capture and what isn't.
This one is somewhat more verbose (specially if you use a longer name for
the "capture") but looks much more familiar to pythonistas (and to IDE
syntax highlighters ;-) ). I added the "into c" syntax without thinking too
much, perhaps using "as c" or "in c", or "match(c)" could be better, I
didn't want to stop much into that part before discussing the idea of using
a "capture object". The capture object is mostly an attribute placeholder
(I might like it to have an extra attribute to get the original matched
value which is generally useful and might be easier than using a walrus,
but this is a minor feature).

What does the rest of the community (and the original authors think about
these alternatives?


On Tue, 23 Jun 2020 at 17:04, Guido van Rossum  wrote:

> I'm happy to present a new PEP for the python-dev community to review.
> This is joint work with Brandt Bucher, Tobias Kohn, Ivan Levkivskyi and
> Talin.
>
> Many people have thought about extending Python with a form of pattern
> matching similar to that found in Scala, Rust, F#, Haskell and other
> languages with a functional flavor. The topic has come up regularly on
> python-ideas (most recently yesterday :-).
>
> I'll mostly let the PEP speak for itself:
> - Published: https://www.python.org/dev/peps/pep-0622/ (*)
> - Source: https://github.com/python/peps/blob/master/pep-0622.rst
>
> (*) The published version will hopefully be available soon.
>
> I want to clarify that the design space for such a match statement is
> enormous. For many key decisions the authors have clashed, in some cases we
> have gone back and forth several times, and a few uncomfortable compromises
> were struck. It is quite possible that some major design decisions will
> have to be revisited before this PEP can be accepted. Nevertheless, we're
> happy with the current proposal, and we have provided ample discussion in
> the PEP under the headings of Rejected Ideas and Deferred 

Re: [Python-Dev] PEP 594: update 1

2019-05-25 Thread Daniel Moisset
Hi, thanks for the work on this proposal, I think this is at least a tip of
the iceberg and a good start for the bigger question of how the stdlib
should evolve..

I think that the PEP should include an idea of what should happen if
existing stdlib pieces depend on this deprecated modules. For example,
email.mime.audio is part of a non-deprecated module but it depends on
sndhdr which is being planned for deprecation. Should that part of the
functionality be deprecated too? rewritten to not depend on the deprecated
module (but keep the pieces of relevant code? depend on optional 3rd party
modules and degrade if those are not available?

The sndhdr case is just an example but I can imagine there are others
(optparse is no longer schedule for removal in your PEP, but would have
been another case, being used by the profile module).

Best,
Daniel

On Tue, 21 May 2019 at 15:15, Christian Heimes  wrote:

> Hi,
>
> I have updated the PEP with feedback from discussions. The highlights are:
>
> * Deprecate parser module
> * Keep fileinput module
> * Elaborate why crypt and spwd are dangerous and bad
> * Improve sections for cgitb, colorsys, nntplib, and smtpd modules
> * The colorsys, crypt, imghdr, sndhdr, and spwd sections now list suitable
> substitutions.
> * Mention that socketserver is going to stay for http.server and
> xmlrpc.server
> * The future maintenance section now states that the deprecated modules
> may be adopted by Python community members.
>
> https://github.com/python/peps/compare/7799178a...2d536899?diff=unified#diff-ae358c21fa7968ee3b6c64479e051574
>
>
> I'll be traveling the next couple of days and will only have limited
> opportunities to respond on feedback.
>
> Christian
>
> ---
> PEP: 594
> Title: Removing dead batteries from the standard library
> Author: Christian Heimes 
> Status: Draft
> Type: Standards Track
> Content-Type: text/x-rst
> Created: 20-May-2019
> Post-History: 21-May-2019
>
>
> Abstract
> 
>
> This PEP proposed a list of standard library modules to be removed from the
> standard library. The modules are mostly historic data formats and APIs
> that
> have been superseded a long time ago, e.g. Mac OS 9 and Commodore.
>
>
> Rationale
> =
>
> Back in the early days of Python, the interpreter came with a large set of
> useful modules. This was often refrained to as "batteries included"
> philosophy and was one of the corner stones to Python's success story.
> Users didn't have to figure out how to download and install separate
> packages in order to write a simple web server or parse email.
>
> Times have changed. The introduction of the cheese shop (PyPI), setuptools,
> and later pip, it became simple and straight forward to download and
> install
> packages. Nowadays Python has a rich and vibrant ecosystem of third party
> packages. It's pretty much standard to either install packages from PyPI or
> use one of the many Python or Linux distributions.
>
> On the other hand, Python's standard library is piling up cruft,
> unnecessary
> duplication of functionality, and dispensable features. This is undesirable
> for several reasons.
>
> * Any additional module increases the maintenance cost for the Python core
>   development team. The team has limited resources, reduced maintenance
> cost
>   frees development time for other improvements.
> * Modules in the standard library are generally favored and seen as the
>   de-facto solution for a problem. A majority of users only pick 3rd party
>   modules to replace a stdlib module, when they have a compelling reason,
> e.g.
>   lxml instead of `xml`. The removal of an unmaintained stdlib module
>   increases the chances of a community contributed module to become widely
>   used.
> * A lean and mean standard library benefits platforms with limited
> resources
>   like devices with just a few hundred kilobyte of storage (e.g. BBC
>   Micro:bit). Python on mobile platforms like BeeWare or WebAssembly
>   (e.g. pyodide) also benefit from reduced download size.
>
> The modules in the PEP have been selected for deprecation because their
> removal is either least controversial or most beneficial. For example
> least controversial are 30 years old multimedia formats like ``sunau``
> audio format, which was used on SPARC and NeXT workstations in the late
> 1980ties. The ``crypt`` module has fundamental flaws that are better solved
> outside the standard library.
>
> This PEP also designates some modules as not scheduled for removal. Some
> modules have been deprecated for several releases or seem unnecessary at
> first glance. However it is beneficial to keep the modules in the standard
> library, mostly for environments where installing a package from PyPI is
> not
> an option. This can be cooperate environments or class rooms where external
> code is not permitted without legal approval.
>
> * The usage of FTP is declining, but some files are still