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? 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-behavio... 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] I can see no good reason for adding undefined behaviour. It doesn't help anyone. 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. Implementation -------------- My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981 Such complex control flow should be handled during compilation, rather than in the interpreter. Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of the language. It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour. We have spent quite a lot of effort over the last few years streamlining the interpreter. Adding these extremely complex instructions would be a big backward step. Cheers, Mark.
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 <mark@hotpy.org> 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-behavio...
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 multiple statements must be equal to the outcome of operations executed serially, but in practice databases can find more efficient non-serial executions with the same outcome. The PEP specifies semantics, not how the implementation must behave. Implementation
--------------
My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981
Such complex control flow should be handled during compilation, rather than in the interpreter. Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of the language. It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour.
We have spent quite a lot of effort over the last few years streamlining the interpreter. Adding these extremely complex instructions would be a big backward step.
What you say about this sounds very reasonable to me, although I don't understand who it is a "Concern with PEP 634". The implementation is not part of the PEP, and I'm pretty sure all parties here (the PEP authors, the PEP critics, the SC) would be more than happy to see this implementation improving. I'm pretty sure we both have presented these ideas before so I'm not expecting any of us to change our minds at this point, but I'm leaving this reply here for future reference in case other people want to have the different positions on this discussion Best, D.
Hi Daniel, On 06/02/2021 7:47 pm, Daniel Moisset wrote:
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 <mark@hotpy.org <mailto:mark@hotpy.org>> 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.
You seem to be jumping on my use of the word "can't". I should have said "Why *doesn't* PEP 634 use the object model?" As for unpacking, it builds on iteration in a way that is clear and precise. For example, I can desugar: a, b = t into: try: __tmp = iter(t) except TypeError: raise TypeError("cannot unpack non-iterable ...") try: __tmp_a = next(__tmp) __tmp_b = next(__tmp) except StopIteration: raise ValueError("not enough values ...") try: next(__tmp) except StopIteration: pass else: raise raise ValueError("too many values ...") a = __tmp_a; b = __tmp_b Noting that variables starting "__tmp" are invisible. Why not do something similar for PEP 634?
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)
I don't see how this is relevant. It is the semantics of PEP 634 as proposed that concerns me.
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-behavio...
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 existence of a few cases of undefined behaviour (e.g. race conditions) does not excuse adding a whole lot more. Especially when there is no good reason.
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)
No it doesn't. It is an impediment to performance for the reasons I give here:
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).
What is this mythical "smart compiler". Are you expecting some research breakthrough to solve this or an existing algorithm? If the latter, then what algorithm?
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 multiple statements must be equal to the outcome of operations executed serially, but in practice databases can find more efficient non-serial executions with the same outcome. The PEP specifies semantics, not how the implementation must behave.
I'm puzzled by that last sentence. Isn't that what semantics are? The meaning of something. How the implementation behaves determines the meanings of programs. If the individual steps in a sequence have observable side-effects, then it changes the semantics to remove, add to, or reorder those side-effects. All of the operations you propose using to implement pattern matching potentially have side effects.
Implementation --------------
My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981
Such complex control flow should be handled during compilation, rather than in the interpreter. Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of the language. It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour.
We have spent quite a lot of effort over the last few years streamlining the interpreter. Adding these extremely complex instructions would be a big backward step.
What you say about this sounds very reasonable to me, although I don't understand who it is a "Concern with PEP 634". The implementation is not part of the PEP, and I'm pretty sure all parties here (the PEP authors, the PEP critics, the SC) would be more than happy to see this implementation improving.
You say that the implementation is not part of the PEP, but what happens if the PEP is accepted? The implementation then become parts of CPython, which is the de-facto specification of Python, and because the PEP is not precisely defined, the implementation becomes the de-factor specification of pattern matching in Python. You say that you would be happy to see the implementation improving. Are you going to do it? If not, then who? If you can't do it now, then at least explain what optimisations are proposed. Cheers, Mark.
I'm pretty sure we both have presented these ideas before so I'm not expecting any of us to change our minds at this point, but I'm leaving this reply here for future reference in case other people want to have the different positions on this discussion
Best, D.
On Sat, 6 Feb 2021 at 19:54, Daniel Moisset <dfmoisset@gmail.com> wrote:
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 <mark@hotpy.org> 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)
I find that particular section of the PEP unsatisfying. The illustrated protocol seems to be much more complex than anything I would have imagined. The thing that I find jarring about this PEP is that it seems to make positional arguments second class to keyword arguments and attributes at the same time as suggesting an equivalence that doesn't really exist between keyword arguments and attributes. I raised something related previously: https://mail.python.org/archives/list/python-dev@python.org/thread/V6UC7QEG4... If I have a class that takes positional arguments like p = Point2D(x, y) (example from the PEP) then in order to match it I have to define attributes for x and y and the matcher will use p.x and p.y to match against the "arguments" in `case Point2D(a, b)`. The PEP proposes to use __match_args__ == ['x', 'y'] in order to translate the argument positions 0 and 1 (of a and b) into attributes x and y and then use getattr to compare them in the matching protocol. It is very likely though that the Point2D class can efficiently return a tuple of positional arguments like (x, y) that could be compared more directly against (a, b) without any need for *attributes* to be involved. I would have expected that __match_args__ would be used in reverse to the way the PEP proposes: to translate keyword arguments from the pattern to positional arguments on the object rather than positional arguments in the pattern to attributes on the object. The PEP says:
Late in the design process, however, it was realized that the need for a custom matching protocol was much less than anticipated. Virtually all the realistic (as opposed to fanciful) uses cases brought up could be handled by the built-in matching behavior, although in a few cases an extra guard condition was required to get the desired effect.
The PEP introduces many special cases for builtin types rather than a general extensible mechanism that can work for builtin types as well as user-defined types. That means it can handle various common cases but misses out on others. Referring to the thread I linked above mentioning sympy if I have a class like Add with instances like Add(x, y, z), Add(x, y, z, t) etc. It would seem very natural to me that I should be able to match against that but it isn't possible to do that directly because there is no way in PEP 622 to handle variadic arguments when matching against a user defined class. The PEP makes it possible to match variadic-ish "arguments" with builtins like tuple, list, etc but that is done with special casing rather than with a protocol that can be applied equally to user defined types. Personally I would be happier with the PEP if it had a clear protocol such that builtin types could support the protocol in an efficient and natural way. If a protocol works well for builtin types then that suggests that it can work well in general. If the only way to make this work for builtin types is to give them special-case support then that points to a deficiency in the protocol. -- Oscar
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.) (At https://www.python.org/dev/peps/pep-0634/, there's no indication that this option was considered.) On 06.02.2021 18:44, 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?
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-behavio...
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]
I can see no good reason for adding undefined behaviour. It doesn't help anyone.
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.
Implementation --------------
My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981
Such complex control flow should be handled during compilation, rather than in the interpreter. Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of the language. It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour.
We have spent quite a lot of effort over the last few years streamlining the interpreter. Adding these extremely complex instructions would be a big backward step.
Cheers, Mark. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/HC6XDUAS... Code of Conduct: http://python.org/psf/codeofconduct/
-- Regards, Ivan
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road. Kind regards, Steve On Sat, Feb 6, 2021 at 8:15 PM Ivan Pozdeev via Python-Dev < python-dev@python.org> wrote:
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.)
(At https://www.python.org/dev/peps/pep-0634/, there's no indication that this option was considered.)
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
On 06.02.2021 18:44, Mark Shannon wrote: 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?
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-behavio...
Python has, in general, been strict about not having undefined behaviour. Having defined semantics means that you can reason about programs, even
[This is not unique to Python, it is really only C and C++ that have areas of undefined behaviour]
I can see no good reason for adding undefined behaviour. It doesn't help anyone.
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.
Implementation --------------
My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981
Such complex control flow should be handled during compilation, rather
Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of
It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour.
We have spent quite a lot of effort over the last few years streamlining
non-idiomatic ones. than in the interpreter. the language. the interpreter.
Adding these extremely complex instructions would be a big backward step.
Cheers, Mark. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/HC6XDUAS... Code of Conduct: http://python.org/psf/codeofconduct/
-- Regards, Ivan _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/OGXG4TIZ... Code of Conduct: http://python.org/psf/codeofconduct/
Who said "__future__"? I said "3rd-party library". Independent from the CPython project. Maybe even a few of them -- to try out conflicting visions that emerged in the discussions. On 06.02.2021 23:58, Steve Holden wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road.
Kind regards, Steve
On Sat, Feb 6, 2021 at 8:15 PM Ivan Pozdeev via Python-Dev <python-dev@python.org <mailto:python-dev@python.org>> wrote:
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.)
(At https://www.python.org/dev/peps/pep-0634/ <https://www.python.org/dev/peps/pep-0634/>, there's no indication that this option was considered.)
On 06.02.2021 18:44, 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? > > 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-behavio... <https://www.python.org/dev/peps/pep-0634/#side-effects-and-undefined-behavio...> > > 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] > > I can see no good reason for adding undefined behaviour. It doesn't help anyone. > > 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. > > > Implementation > -------------- > > My main concern with the implementation is that it does too much work into the interpreter. > Much of that work can and should be done in the compiler. > For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: > https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981 <https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981> > > Such complex control flow should be handled during compilation, rather than in the interpreter. > Giant instructions like MATCH_CLASS are likely to have odd corner cases, > and may well have a negative impact on the performance of the rest of the language. > It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour. > > We have spent quite a lot of effort over the last few years streamlining the interpreter. > Adding these extremely complex instructions would be a big backward step. > > > Cheers, > Mark. > _______________________________________________ > Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> > To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@python.org> > https://mail.python.org/mailman3/lists/python-dev.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/HC6XDUAS... <https://mail.python.org/archives/list/python-dev@python.org/message/HC6XDUAS...> > Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
-- Regards, Ivan _______________________________________________ Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@python.org> https://mail.python.org/mailman3/lists/python-dev.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/OGXG4TIZ... <https://mail.python.org/archives/list/python-dev@python.org/message/OGXG4TIZ...> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
-- Regards, Ivan
Hello, On Sun, 7 Feb 2021 00:00:41 +0300 Ivan Pozdeev via Python-Dev <python-dev@python.org> wrote:
Who said "__future__"?
Other people said __future__. And yet other said "it's ok the way it is, it's better to have it like that then keep not having it". And yet other said something else (multiple else's).
I said "3rd-party library". Independent from the CPython project. Maybe even a few of them -- to try out conflicting visions that emerged in the discussions.
Such libraries exist for decade(s). MacroPy is a venerable, well-known macro-capabilities-for-Python solution, which offers a kind of pattern matching: https://macropy3.readthedocs.io/en/latest/pattern.html . There're a bunch of other, grep github. https://github.com/MegaIng/syntax-extensions-pep634 specifically advertises itself as pure-Python implementation of PEP634 (using a newer macro library), though I'm not sure how well it's development. It also of course represents the right way to develop Python - in Python itself. Sadly, "C" in "CPython" is stuck too deep in many minds... Bottom line is however: given the decade(s) old history of pattern matching in *Python* (usual warning: don't mix up Python and CPython!), arguing that very resourceful attempt to add pattern matching to the reference implementation (that's where *CPython* finally pops up), should be flushed down the toilet and the Python community should be brought back into decade-long waiting state without a reference implementation for pattern matching - umm, suggesting that doesn't seem to be very productive.
On 06.02.2021 23:58, Steve Holden wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road.
Kind regards, Steve
On Sat, Feb 6, 2021 at 8:15 PM Ivan Pozdeev via Python-Dev <python-dev@python.org <mailto:python-dev@python.org>> wrote:
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.)
(At https://www.python.org/dev/peps/pep-0634/ <https://www.python.org/dev/peps/pep-0634/>, there's no indication that this option was considered.)
[] -- Best regards, Paul mailto:pmiscml@gmail.com
On 07.02.2021 0:24, Paul Sokolovsky wrote:
Hello,
On Sun, 7 Feb 2021 00:00:41 +0300 Ivan Pozdeev via Python-Dev <python-dev@python.org> wrote:
Who said "__future__"? Other people said __future__. And yet other said "it's ok the way it is, it's better to have it like that then keep not having it". And yet other said something else (multiple else's).
I said "3rd-party library". Independent from the CPython project. Maybe even a few of them -- to try out conflicting visions that emerged in the discussions. Such libraries exist for decade(s). MacroPy is a venerable, well-known macro-capabilities-for-Python solution, which offers a kind of pattern matching: https://macropy3.readthedocs.io/en/latest/pattern.html . There're a bunch of other, grep github.
https://github.com/MegaIng/syntax-extensions-pep634 specifically advertises itself as pure-Python implementation of PEP634 (using a newer macro library), though I'm not sure how well it's development. It also of course represents the right way to develop Python - in Python itself. Sadly, "C" in "CPython" is stuck too deep in many minds...
Bottom line is however: given the decade(s) old history of pattern matching in *Python* (usual warning: don't mix up Python and CPython!), arguing that very resourceful attempt to add pattern matching to the reference implementation (that's where *CPython* finally pops up), should be flushed down the toilet and the Python community should be brought back into decade-long waiting state without a reference implementation for pattern matching - umm, suggesting that doesn't seem to be very productive.
That's not the impression I got from looking through the discussiuon and the PEP. I don't see references to any of those existing implementations anywhere in the PEP as well as a summary of various existing approaches and solutions, their pros and cons etc. which the proposal proper would derive its particulars from. Both the PEPs and the discussion look like they are trying to write the functionality completely from sctratch, by the seat of their pants. And from how much discord there is about syntax and semantics, I conclude that these are far from being well-established and practice-proven. So if the existing solutions really have a "decades-long history" as you claim, that history must be spectacularly uneventful -- which suggests that the feature is either in low demand or was ultimately proven by practice to be inadequate for real-world use.
On 06.02.2021 23:58, Steve Holden wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road.
Kind regards, Steve
On Sat, Feb 6, 2021 at 8:15 PM Ivan Pozdeev via Python-Dev <python-dev@python.org <mailto:python-dev@python.org>> wrote:
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.)
(At https://www.python.org/dev/peps/pep-0634/ <https://www.python.org/dev/peps/pep-0634/>, there's no indication that this option was considered.)
[]
-- Regards, Ivan
Hello, On Sun, 7 Feb 2021 04:53:43 +0300 Ivan Pozdeev <vano@mail.mipt.ru> wrote:
On 07.02.2021 0:24, Paul Sokolovsky wrote:
Hello,
On Sun, 7 Feb 2021 00:00:41 +0300 Ivan Pozdeev via Python-Dev <python-dev@python.org> wrote:
Who said "__future__"? Other people said __future__. And yet other said "it's ok the way it is, it's better to have it like that then keep not having it". And yet other said something else (multiple else's).
I said "3rd-party library". Independent from the CPython project. Maybe even a few of them -- to try out conflicting visions that emerged in the discussions. Such libraries exist for decade(s). MacroPy is a venerable, well-known macro-capabilities-for-Python solution, which offers a kind of pattern matching: https://macropy3.readthedocs.io/en/latest/pattern.html . There're a bunch of other, grep github.
https://github.com/MegaIng/syntax-extensions-pep634 specifically advertises itself as pure-Python implementation of PEP634 (using a newer macro library), though I'm not sure how well it's development. It also of course represents the right way to develop Python - in Python itself. Sadly, "C" in "CPython" is stuck too deep in many minds...
Bottom line is however: given the decade(s) old history of pattern matching in *Python* (usual warning: don't mix up Python and CPython!), arguing that very resourceful attempt to add pattern matching to the reference implementation (that's where *CPython* finally pops up), should be flushed down the toilet and the Python community should be brought back into decade-long waiting state without a reference implementation for pattern matching - umm, suggesting that doesn't seem to be very productive.
That's not the impression I got from looking through the discussiuon and the PEP.
I pretty closely followed "second half" of patter matching discussion - after it became clear that there're a lot of criticism (and I shared some criticism too). And I've got somewhat different impression than yours.
I don't see references to any of those existing implementations anywhere in the PEP as well as a summary of various existing approaches and solutions, their pros and cons etc. which the proposal proper would derive its particulars from.
Well, a PEP is not "annals of Python history as related to area XXX". It's a proposal for a specific change. Which should have good argumentation, but still doesn't have to start with "When the Earth was ball of flame, ...". There can be "too much" too. You can see that very well with pattern matching proposal: its started as PEP622, but was deemed too long and wide-scoped, and split into *three* of PEP634/PEP635/PEP636 - all to ease community review. There was also a proposal to add "other possible options" to PEP622, which was rejected, and spawned into separate PEP642. So, there quite a work was done, and saying "it's not enough" is not helpful and not appreciating of authors' efforts (pretty titanic efforts from mere Python user PoV).
Both the PEPs and the discussion look like they are trying to write the functionality completely from sctratch, by the seat of their pants.
The authors of the PEPs are definitely aware of pre-history of pattern matching in Python. Heck, that's why they went ahead with their proposal - because they know that people wanted pattern matching in Python for decades! Designing "completely from scratch" isn't a bad choice in situation with multiple choices and complex enough systems. And it wasn't "completely from scratch", on multiple occasions authors said "that's done similar to pattern matching in other languages". Authors of alternative patmatching impls also provided feedback (I'm not sure how well that was heard).
And from how much discord there is about syntax and semantics,
And that's where my impressions differ. There's a strong sentiment that various aspects of pattern matching could "easily" be made better right from the start than described in PEP634/PEP635/PEP636. But from people who're interested in pattern matching, there're hardly valuation like "PEP634 is so bad that we'd rather punish ourselves and live without it, than with PEP634". If anything, PEP642 showed that things can be much worse. And it's ironic, because it exactly started with "small obvious improvements to PEP634", but decided to replay the "road to hell is paved with good intentions" proverb, and from small obvious things went to pretty tangled speculations.
I conclude that these are far from being well-established and practice-proven. So if the existing solutions really have a "decades-long history" as you claim, that history must be spectacularly uneventful -- which suggests that the feature is either in low demand or was ultimately proven by practice to be inadequate for real-world use.
Let me continue the story of MacroPy. His authors barely maintains it. Because for many years his primary language is Scala. That's not exception, but a very visible pattern - many advanced Python users end not being Python users. And we're end with the community of "Pattern matching? Never heard." Don't trust such voices. Trust voices of people who use multiple languages, but *still* return to Python to make it better ("better"? to "stand well against other languages" is a better term). PEP634 was written by such people. It's pretty ungrateful to suggest that Python doesn't need their effort, among the situation when pattern matching is becoming the norm in the programming language space. -- Best regards, Paul mailto:pmiscml@gmail.com
Good luck in your quest. Kind regards, Steve On Sat, Feb 6, 2021 at 9:00 PM Ivan Pozdeev <vano@mail.mipt.ru> wrote:
Who said "__future__"? I said "3rd-party library". Independent from the CPython project. Maybe even a few of them -- to try out conflicting visions that emerged in the discussions. On 06.02.2021 23:58, Steve Holden wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road.
Kind regards, Steve
On Sat, Feb 6, 2021 at 8:15 PM Ivan Pozdeev via Python-Dev < python-dev@python.org> wrote:
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.)
(At https://www.python.org/dev/peps/pep-0634/, there's no indication that this option was considered.)
On 06.02.2021 18:44, 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?
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-behavio...
Python has, in general, been strict about not having undefined
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]
I can see no good reason for adding undefined behaviour. It doesn't help anyone.
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.
Implementation --------------
My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981
Such complex control flow should be handled during compilation, rather
Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of
behaviour. than in the interpreter. the language.
It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour.
We have spent quite a lot of effort over the last few years streamlining the interpreter. Adding these extremely complex instructions would be a big backward step.
Cheers, Mark. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/HC6XDUAS... Code of Conduct: http://python.org/psf/codeofconduct/
-- Regards, Ivan _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/OGXG4TIZ... Code of Conduct: http://python.org/psf/codeofconduct/
-- Regards, Ivan
On Sat, Feb 6, 2021 at 6:04 PM Steve Holden <steve@holdenweb.com> wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road.
This is really unfortunate. I agree this is a huge language change and it should only be approved with some mechanism requiring explicit opt-in (such as __future__ import) AND it should be documented as provisional for several releases, like asyncio was (and remember: the asyncio API had lots of breaking changes and prompted the addition of the async/await keywords, a great improvement that forced the renaming of the very fundamental async function from the original API). Scala is recognized as an overly complex language [1], in part because the designers like to experiment with new features all the time. It's not a great benchmark for Python IMHO, but if we are going to leverage the new PEG parser with huge language choices changes more often than we have in the past, then we should consider adopting the feature toggles like the Scala compiler [2], so that individual teams can decide which features they want to use and which they don't. [1] https://www.thoughtworks.com/radar/languages-and-frameworks/scala-the-good-p... [2] https://docs.scala-lang.org/overviews/compiler-options/index.html (look for options with the -language prefix) Cheers, Luciano
Kind regards, Steve
On Sat, Feb 6, 2021 at 8:15 PM Ivan Pozdeev via Python-Dev <python-dev@python.org> wrote:
With such a large new area of functionality that's at odds with existing syntax and semantics and a lack of clear vision and agreement, it sounds like this would be better first added as a 3rd-party library to let the syntax and semantics mature. (To allow new syntax, it'll probably be parsing strings in that special syntax.)
(At https://www.python.org/dev/peps/pep-0634/, there's no indication that this option was considered.)
On 06.02.2021 18:44, 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?
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-behavio...
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]
I can see no good reason for adding undefined behaviour. It doesn't help anyone.
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.
Implementation --------------
My main concern with the implementation is that it does too much work into the interpreter. Much of that work can and should be done in the compiler. For example, deep in the implementation of the MATCH_CLASS instruction is the following comment: https://github.com/brandtbucher/cpython/blob/patma/Python/ceval.c#L981
Such complex control flow should be handled during compilation, rather than in the interpreter. Giant instructions like MATCH_CLASS are likely to have odd corner cases, and may well have a negative impact on the performance of the rest of the language. It is a lot easier to reason about a sequence of simple bytecodes, than one giant one with context-dependent behaviour.
We have spent quite a lot of effort over the last few years streamlining the interpreter. Adding these extremely complex instructions would be a big backward step.
Cheers, Mark. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/HC6XDUAS... Code of Conduct: http://python.org/psf/codeofconduct/
-- Regards, Ivan _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/OGXG4TIZ... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/DJJLEMZ7... 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
On Sun, Feb 7, 2021 at 8:14 AM Luciano Ramalho <luciano@ramalho.org> wrote:
On Sat, Feb 6, 2021 at 6:04 PM Steve Holden <steve@holdenweb.com> wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance. No point going down that road.
This is really unfortunate.
I agree this is a huge language change and it should only be approved with some mechanism requiring explicit opt-in (such as __future__ import)
How will a __future__ import help here? Are there syntactic or behavioural changes that would be worth applying to some modules and not others? The entire point of a __future__ import is to maintain backward compatibility by, for instance, not introducing a keyword, unless it is explicitly requested. What advantage would there be here?
AND it should be documented as provisional for several releases, like asyncio was (and remember: the asyncio API had lots of breaking changes and prompted the addition of the async/await keywords, a great improvement that forced the renaming of the very fundamental async function from the original API).
Documenting as "provisional" means that its behaviour can change. Again, how will that make things easier here? ChrisA
On Sat, Feb 6, 2021 at 6:23 PM Chris Angelico <rosuav@gmail.com> wrote:
How will a __future__ import help here? Are there syntactic or behavioural changes that would be worth applying to some modules and not others? The entire point of a __future__ import is to maintain backward compatibility by, for instance, not introducing a keyword, unless it is explicitly requested. What advantage would there be here?
The fact that a __future__ import only affects a single module is precisely the point: we may not want the feature in our code initially, but maybe we don't mind using third-party libraries that use it. A __future__ import would make clear to all that the feature is experimental, and maybe there could be __future__ imports for different parts of the proposal.
AND it should be documented as provisional for several releases, like asyncio was (and remember: the asyncio API had lots of breaking changes and prompted the addition of the async/await keywords, a great improvement that forced the renaming of the very fundamental async function from the original API).
Documenting as "provisional" means that its behaviour can change. Again, how will that make things easier here?
Telling everyone that the behaviour can change allows you to change the behaviour if you realize the behavior is unhelpful in some way. Again, that's just a huge feature and I believe we should consider one or more ways of making its adoption gradual and to make it easier to fix oversights if needed. Best, Luciano
ChrisA _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/VC3IV5XD... 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
On Sat, 2021-02-06 at 22:00 -0300, Luciano Ramalho wrote:
A __future__ import would make clear to all that the feature is experimental, and maybe there could be __future__ imports for different parts of the proposal.
That's not my understanding. My understanding is __future__ is meant for features that potentially break existing code, and allows code to opt-in in a release earlier than when it will behave that way by default. From what I can tell with this PEP, existing code can continue working the way it always has. Paul
Hello, On Sun, 7 Feb 2021 01:17:31 +0000 Paul Bryan <pbryan@anode.ca> wrote:
On Sat, 2021-02-06 at 22:00 -0300, Luciano Ramalho wrote:
A __future__ import would make clear to all that the feature is experimental, and maybe there could be __future__ imports for different parts of the proposal.
That's not my understanding. My understanding is __future__ is meant for features that potentially break existing code, and allows code to opt-in in a release earlier than when it will behave that way by default. From what I can tell with this PEP, existing code can continue working the way it always has.
And that's not understanding of the majority of Python users. For majority of "mere" users, __future__ is a marker that something new (and thus experimental, for these categories are again equivalent for most users) is being used in the current module. So, "from __future__ import with_statement" didn't mean to people "you can't use variable named 'with' in this module" (because majority of people never used such a variable name, so didn't care), but instead meant "this module uses the new 'with' statement, keep your ear sharp". And the current excuses go along the lines of "now that we've got a parser with exponential memory usage, we can use __future__ like... umm, never". Don't do that, keep using __future__ like it always was - to mark experimental features.
Paul
-- Best regards, Paul mailto:pmiscml@gmail.com
That’s incorrect. __future__ is used when something new and *incompatible* is being introduced (and the old way is being deprecated at the same time). For experimental modules we use the term provisional. There’s no official term for experimental syntax (since we’ve never had any), but we could call that provisional as well. On Sat, Feb 6, 2021 at 22:44 Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Sun, 7 Feb 2021 01:17:31 +0000 Paul Bryan <pbryan@anode.ca> wrote:
On Sat, 2021-02-06 at 22:00 -0300, Luciano Ramalho wrote:
A __future__ import would make clear to all that the feature is experimental, and maybe there could be __future__ imports for different parts of the proposal.
That's not my understanding. My understanding is __future__ is meant for features that potentially break existing code, and allows code to opt-in in a release earlier than when it will behave that way by default. From what I can tell with this PEP, existing code can continue working the way it always has.
And that's not understanding of the majority of Python users. For majority of "mere" users, __future__ is a marker that something new (and thus experimental, for these categories are again equivalent for most users) is being used in the current module.
So, "from __future__ import with_statement" didn't mean to people "you can't use variable named 'with' in this module" (because majority of people never used such a variable name, so didn't care), but instead meant "this module uses the new 'with' statement, keep your ear sharp".
And the current excuses go along the lines of "now that we've got a parser with exponential memory usage, we can use __future__ like... umm, never".
Don't do that, keep using __future__ like it always was - to mark experimental features.
Paul
-- Best regards, Paul mailto:pmiscml@gmail.com _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/2O3ZSLNO... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido (mobile)
Hello, On Sat, 6 Feb 2021 23:05:19 -0800 Guido van Rossum <guido@python.org> wrote:
That’s incorrect. __future__ is used when something new and *incompatible* is being introduced (and the old way is being deprecated at the same time). For experimental modules we use the term provisional. There’s no official term for experimental syntax (since we’ve never had any), but we could call that provisional as well.
Thanks, I'm aware. Thus the nature of my proposal is: redefine (extend) cases when __future__ is used, e.g. when a PEP itself says something like "There're many more could be done, but good things come in pieces, and wise men know when to stand back and relax before continuing. So, see ya next time!" My argument that such usage of __future__ would correspond more to the expectations of the Python end users ("feature is not fully developed yet, and there could be small incompatible changes going forward").
On Sat, Feb 6, 2021 at 22:44 Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Sun, 7 Feb 2021 01:17:31 +0000 Paul Bryan <pbryan@anode.ca> wrote:
On Sat, 2021-02-06 at 22:00 -0300, Luciano Ramalho wrote:
A __future__ import would make clear to all that the feature is experimental, and maybe there could be __future__ imports for different parts of the proposal.
That's not my understanding. My understanding is __future__ is meant for features that potentially break existing code, and allows code to opt-in in a release earlier than when it will behave that way by default. From what I can tell with this PEP, existing code can continue working the way it always has.
And that's not understanding of the majority of Python users. For majority of "mere" users, __future__ is a marker that something new (and thus experimental, for these categories are again equivalent for most users) is being used in the current module.
So, "from __future__ import with_statement" didn't mean to people "you can't use variable named 'with' in this module" (because majority of people never used such a variable name, so didn't care), but instead meant "this module uses the new 'with' statement, keep your ear sharp".
And the current excuses go along the lines of "now that we've got a parser with exponential memory usage, we can use __future__ like... umm, never".
Don't do that, keep using __future__ like it always was - to mark experimental features.
Paul
-- Best regards, Paul mailto:pmiscml@gmail.com _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/2O3ZSLNO... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido (mobile)
-- Best regards, Paul mailto:pmiscml@gmail.com
On Sun, Feb 7, 2021 at 6:25 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Sat, 6 Feb 2021 23:05:19 -0800 Guido van Rossum <guido@python.org> wrote:
That’s incorrect. __future__ is used when something new and *incompatible* is being introduced (and the old way is being deprecated at the same time). For experimental modules we use the term provisional. There’s no official term for experimental syntax (since we’ve never had any), but we could call that provisional as well.
Thanks, I'm aware. Thus the nature of my proposal is: redefine (extend) cases when __future__ is used, e.g. when a PEP itself says something like "There're many more could be done, but good things come in pieces, and wise men know when to stand back and relax before continuing. So, see ya next time!"
My argument that such usage of __future__ would correspond more to the expectations of the Python end users ("feature is not fully developed yet, and there could be small incompatible changes going forward").
But future directives are not for things that aren't fully developed yet. What gives people this idea? For example, Python 2 code can say "from __future__ import print_function" or "division". Was the print function in a provisional state, with incompatible changes coming? No. Was the division operator redefined? No. The directives cause compilation changes (removing a keyword, using a different division operator) that were backward incompatible *at launch* but they haven't changed since. In fact, part of the promise of __future__ is that it WILL remain compatible - you can write "from __future__ import nested_scopes" in a modern Python script, and the behaviour will be exactly correct. If you want a directive to put at the top of a script that says that new features are being used, I'd suggest something like this: #!/usr/bin/env python3.9 or whatever version you require. ChrisA
Hello, On Sun, 7 Feb 2021 19:09:14 +1100 Chris Angelico <rosuav@gmail.com> wrote:
On Sun, Feb 7, 2021 at 6:25 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Sat, 6 Feb 2021 23:05:19 -0800 Guido van Rossum <guido@python.org> wrote:
That’s incorrect. __future__ is used when something new and *incompatible* is being introduced (and the old way is being deprecated at the same time). For experimental modules we use the term provisional. There’s no official term for experimental syntax (since we’ve never had any), but we could call that provisional as well.
Thanks, I'm aware. Thus the nature of my proposal is: redefine (extend) cases when __future__ is used, e.g. when a PEP itself says something like "There're many more could be done, but good things come in pieces, and wise men know when to stand back and relax before continuing. So, see ya next time!"
My argument that such usage of __future__ would correspond more to the expectations of the Python end users ("feature is not fully developed yet, and there could be small incompatible changes going forward").
But future directives are not for things that aren't fully developed yet. What gives people this idea?
For example, Python 2 code can say "from __future__ import print_function" or "division". Was the print function in a provisional state, with incompatible changes coming? No.
So, you're saying that, by the benevolence of divine providence, most (can you truly vouch for "all" and provide evidence?) features so far added to __future__ never were changed (enough). From that, you derive the conclusion that only things that can never change can be added to __future__. (You can even point to a yellowish paper where something like that is written). But that vision doesn't much correspond to reality. The world is dynamic and ever-changing. It's good luck that simple print() function never changed beyond its original definition and "/" for ints wasn't cast back to return ints. But pattern matching is much more complex than that, and knowing that there were definitely bugfixes for both print() and "/", we can estimate that pattern matching will need only more, including some externally-visible fixes. So, for as long as there was (and is!) "from __future__ import with_statement", there can also be "from __future__ import match_statement".
Was the division operator redefined? No. The directives cause compilation changes (removing a keyword, using a different division operator) that were backward incompatible *at launch* but they haven't changed since. In fact, part of the promise of __future__ is that it WILL remain compatible - you can write "from __future__ import nested_scopes" in a modern Python script, and the behaviour will be exactly correct.
All that would point that we need something like "from __experimental__ import ...". But I don't go that far. I think that existing __future__ is good enough for the purpose.
If you want a directive to put at the top of a script that says that new features are being used, I'd suggest something like this:
#!/usr/bin/env python3.9
or whatever version you require.
That doesn't say that this particular module uses experimental pattern matching feature. It also has a side effect of pinning a script to a particular executable, which may not yet exist on some users' systems, or already not exists on other users' systems.
ChrisA
-- Best regards, Paul mailto:pmiscml@gmail.com
On Sun, Feb 7, 2021 at 7:54 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
So, you're saying that, by the benevolence of divine providence, most (can you truly vouch for "all" and provide evidence?) features so far added to __future__ never were changed (enough).
No, I'm saying that the __future__ directive is not for the purpose of allowing subsequent changes. It is completely unrelated to any future changes, it is a matter of bringing the future *now*.
From that, you derive the conclusion that only things that can never change can be added to __future__. (You can even point to a yellowish paper where something like that is written).
Uhh well, that's not quite right; everything is subject to change. But those changes are the domain of the subsequent proposals, not the __future__ directive. The statement in a Py2 program "from __future__ import unicode_literals" was not for the purpose of permitting PEP 393 or PEP 414, both of which changed Unicode strings in Python 3.
But that vision doesn't much correspond to reality. The world is dynamic and ever-changing. It's good luck that simple print() function never changed beyond its original definition and "/" for ints wasn't cast back to return ints. But pattern matching is much more complex than that, and knowing that there were definitely bugfixes for both print() and "/", we can estimate that pattern matching will need only more, including some externally-visible fixes.
So? If there are changes to be made, then let a subsequent proposal make those changes.
All that would point that we need something like "from __experimental__ import ...". But I don't go that far. I think that existing __future__ is good enough for the purpose.
Maybe that would be useful, if the match statement were deemed to be an experimental feature. That's not the current proposal. Are you proposing that this be done, and if so, why?
If you want a directive to put at the top of a script that says that new features are being used, I'd suggest something like this:
#!/usr/bin/env python3.9
or whatever version you require.
That doesn't say that this particular module uses experimental pattern matching feature. It also has a side effect of pinning a script to a particular executable, which may not yet exist on some users' systems, or already not exists on other users' systems.
Yes. If that's not what you want, then what IS it you want? Do you need a comment saying "# this code uses the match statement" or "# this code uses str.removeprefix" or "# this code uses positional-only parameters"? What is gained by such directives? I'm done arguing about this. Every time this PEP comes up, it gets yet another round of the same arguments and I keep getting suckered into answering them again. When will I learn... ChrisA
Hello, On Sun, 7 Feb 2021 20:02:48 +1100 Chris Angelico <rosuav@gmail.com> wrote:
On Sun, Feb 7, 2021 at 7:54 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
So, you're saying that, by the benevolence of divine providence, most (can you truly vouch for "all" and provide evidence?) features so far added to __future__ never were changed (enough).
No, I'm saying that the __future__ directive is not for the purpose of allowing subsequent changes. It is completely unrelated to any future changes, it is a matter of bringing the future *now*.
And nobody says that there will be *incompatible* changes to the pattern matching, just that previous experience, and discussion of the PEP622/PEP634 shows that there's a probability of that (higher than usual). In that regard, it may be due to warn users about what pattern matching is - a novelty. And among mechanisms Python already has for that, __future__ seems like the best fit (because users already treat it like that, regardless of what format definition is).
From that, you derive the conclusion that only things that can never change can be added to __future__. (You can even point to a yellowish paper where something like that is written).
Uhh well, that's not quite right; everything is subject to change. But those changes are the domain of the subsequent proposals, not the __future__ directive. The statement in a Py2 program "from __future__ import unicode_literals" was not for the purpose of permitting PEP 393 or PEP 414, both of which changed Unicode strings in Python 3.
If everything is subject to change, then perhaps we can accept usage of __future__ to introduce initial pattern matching implementation. But its purpose is not to enable pattern matching per se, just to keep early adopters in loop that it's a novel feature, subject to change.
But that vision doesn't much correspond to reality. The world is dynamic and ever-changing. It's good luck that simple print() function never changed beyond its original definition and "/" for ints wasn't cast back to return ints. But pattern matching is much more complex than that, and knowing that there were definitely bugfixes for both print() and "/", we can estimate that pattern matching will need only more, including some externally-visible fixes.
So? If there are changes to be made, then let a subsequent proposal make those changes.
Yes, and let's communicate the possibility that future proposals will very likely be there (there're already, e.g. PEP642), and they may make slight incompatible changes - by requiring early adopters to use "from __future__ import ...".
All that would point that we need something like "from __experimental__ import ...". But I don't go that far. I think that existing __future__ is good enough for the purpose.
Maybe that would be useful, if the match statement were deemed to be an experimental feature. That's not the current proposal. Are you proposing that this be done, and if so, why?
Me - not. Someone else proposed to use __future__. I jumped on that idea because I think it's a good compromise with both people who say "patmatching misses some things, like merge it with them already" and who say "there's seem to be discord, let's not merge until it's cleared". Needless to say, user who like/want patmatching, shouldn't feel upset about __future__ either. And it's a responsible act overall to warn early adopters, again. So, now let me ask you - I guess you're not against patmatching, but seem to be concerned with __future__. Why, beyond pure language-lawyering matters ("there's a county bill of 1873 which says __future__ isn't used like that").
If you want a directive to put at the top of a script that says that new features are being used, I'd suggest something like this:
#!/usr/bin/env python3.9
or whatever version you require.
That doesn't say that this particular module uses experimental pattern matching feature. It also has a side effect of pinning a script to a particular executable, which may not yet exist on some users' systems, or already not exists on other users' systems.
Yes. If that's not what you want, then what IS it you want? Do you need a comment saying "# this code uses the match statement" or "# this code uses str.removeprefix" or "# this code uses positional-only parameters"? What is gained by such directives?
A more formal'ish "contract" between developers and users which says "We ship you a new cool feature! But, there can be some changes going forward yet." __future__ (among existing means) satisfies that, a comment - no.
I'm done arguing about this. Every time this PEP comes up, it gets yet another round of the same arguments and I keep getting suckered into answering them again. When will I learn...
Don't take that personally, the issue is developers vs endusers gap, and the discussion happens again and again in the hope to reach minds of the developers.
ChrisA
-- Best regards, Paul mailto:pmiscml@gmail.com
On Sun, Feb 07, 2021 at 12:32:40PM +0300, Paul Sokolovsky wrote:
And nobody says that there will be *incompatible* changes to the pattern matching, just that previous experience, and discussion of the PEP622/PEP634 shows that there's a probability of that (higher than usual).
Fine. The time to involve `__future__` is if and when such incompatible changes are to be made, not for every new feature "just in case".
In that regard, it may be due to warn users about what pattern matching is - a novelty.
Every new feature is a novelty. Who are these users that you have in mind that are sophisticated enough to be using pattern matching and future imports, but not sophisticated enough to realise that it is new in version 3.10 (or whatever version it ends up being)? We don't need to "warn users" that new features are new features. They will already know it is new, until such time that it's no longer new.
If everything is subject to change, then perhaps we can accept usage of __future__ to introduce initial pattern matching implementation. But its purpose is not to enable pattern matching per se, just to keep early adopters in loop that it's a novel feature, subject to change.
I don't believe that there is any proposal to make pattern matching subject to change beyond the usual evolution of the language. I don't think that there is anything provisional about the feature. But even if there is, that still doesn't make it necessary to "warn" uses of the feature by use of future imports. Paul, your argument is that "early adopters" of new features need to be protected from hypothetical future changes that don't exist yet. Why should only early adopters get that benefit? Don't the rest of us deserve protection from hypothetical future changes that don't exist yet? from __past__ import for_loops, import "just in case" some hypothetical future change affects for loops and imports. How else will we know that our code uses for loops and imports? /s -- Steve
On Sat, Feb 06, 2021 at 10:00:16PM -0300, Luciano Ramalho wrote:
On Sat, Feb 6, 2021 at 6:23 PM Chris Angelico <rosuav@gmail.com> wrote:
How will a __future__ import help here? Are there syntactic or behavioural changes that would be worth applying to some modules and not others? The entire point of a __future__ import is to maintain backward compatibility by, for instance, not introducing a keyword, unless it is explicitly requested. What advantage would there be here?
The fact that a __future__ import only affects a single module is precisely the point: we may not want the feature in our code initially, but maybe we don't mind using third-party libraries that use it.
It's not compulsory to use syntactic features if your code doesn't need them. I have many scripts and modules that don't use while loops, or try...except blocks, or with statements. A feature doesn't need to be a `__future__` import for you to just not use it.
A __future__ import would make clear to all that the feature is experimental,
It certainly would not. There is nothing experimental about `__future__` imports. I cannot think of a single example of an experimental feature added via the future mechanism: https://docs.python.org/3/library/__future__.html -- Steve
Hello, On Sun, 7 Feb 2021 13:21:08 +1100 Steven D'Aprano <steve@pearwood.info> wrote:
On Sat, Feb 06, 2021 at 10:00:16PM -0300, Luciano Ramalho wrote:
On Sat, Feb 6, 2021 at 6:23 PM Chris Angelico <rosuav@gmail.com> wrote:
How will a __future__ import help here? Are there syntactic or behavioural changes that would be worth applying to some modules and not others? The entire point of a __future__ import is to maintain backward compatibility by, for instance, not introducing a keyword, unless it is explicitly requested. What advantage would there be here?
The fact that a __future__ import only affects a single module is precisely the point: we may not want the feature in our code initially, but maybe we don't mind using third-party libraries that use it.
It's not compulsory to use syntactic features if your code doesn't need them. I have many scripts and modules that don't use while loops, or try...except blocks, or with statements.
A feature doesn't need to be a `__future__` import for you to just not use it.
Right, and the talk is about the opposite - early adopters of PEP634-style pattern matching should mark the modules in which they *use* PEP-634-style pattern matching, so it will be easy in the future to spot such modules, if we get updated pattern matching style.
A __future__ import would make clear to all that the feature is experimental,
It certainly would not. There is nothing experimental about `__future__` imports. I cannot think of a single example of an experimental feature added via the future mechanism:
All features added via __future__ were new, and thus experimental. For example, they contained long trail of bugs and issues, which were haunting their users for a long time, but at least the users knew what to expect, seeing the __future__ import. Sadly, the converse is not true - not all new and experimental features were added using it, which caused users additional frustration in dealing with them. The proposal is to mend that sad practice, and consistently use __future__ imports for experimental things (e.g. those which are "good enough to go in, but definitely not fully ready, from the perspective of 5-year timeframe of the language evolution"). A complimentary proposal is for "CPython core developers" to redefine in their minds what __future__ import means, to look at it from PoV of the end users, not from PoV of a Python language lawyer, throwing links to formal docs which miss updates to correspond to the actual programming language/software project reality. -- Best regards, Paul mailto:pmiscml@gmail.com
On Sun, Feb 07, 2021 at 09:58:03AM +0300, Paul Sokolovsky wrote:
A feature doesn't need to be a `__future__` import for you to just not use it.
Right, and the talk is about the opposite - early adopters of PEP634-style pattern matching should mark the modules in which they *use* PEP-634-style pattern matching, so it will be easy in the future to spot such modules, if we get updated pattern matching style.
Because `grep "from __future__ import match"` is easier than `grep "match:"` ?
All features added via __future__ were new, and thus experimental.
They were new, they were not experimental.
For example, they contained long trail of bugs and issues, which were haunting their users for a long time, but at least the users knew what to expect, seeing the __future__ import.
Paul, that is bullshit. I use that in the technical sense: http://www2.csudh.edu/ccauthen/576f12/frankfurt__harry_-_on_bullshit.pdf Please just stop. There was no "long trial of bugs and issues" involving (e.g.) unicode literals, true division, nested scopes, print as a function etc; there may have been a few enhancements for the with statement, e.g. the long running desire to be able to parenthesise context managers. In the context of the Python community, "experimental" has a specific meaning: features which are intentionally documented as having an unstable API which may be subject to change. But I'm pretty sure you know that. It absolutely does not refer to the addition of a new stable feature, or the normal process of discovering impementation bugs, enhancement requests, or even the occasional unforeseen problem which may need resolving. But I'm pretty sure you know that too. I don't know what users you have in mind if you think that every new feature needs to go through a redundant and pointless future import. Users who get paid by the line, and adding that one extra line of code earns them an extra dollar? Users who love unnecessary boilerplate at the top of every file? Users who don't interact with beginners who don't understand why they can't use the new feature? Users who want to impose an extra burden on the entire community, starting with the core devs who have to implement the unnecessary future import, and going on all the way down to every single coder who says to themselves "Oh, I forgot the future import!" when their code fails. Future imports were designed carefully and thoughtfully as a mechanism to gradually introduce **backwards incompatible** syntactic changes. They are not there just to add friction to every single new syntactic feature. -- Steve
On 7/02/21 9:58 am, Steve Holden wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance.
__future__ is for things that are changing in incompatible ways. This is an entirely new feature that doesn't conflict with anything existing, so it doesn't need __future__. -- Greg
On Sat, Feb 6, 2021 at 9:34 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
__future__ is for things that are changing in incompatible ways. This is an entirely new feature that doesn't conflict with anything existing, so it doesn't need __future__.
The initial pattern matching syntax and semantics with its many corner cases may be incompatible with a future way of doing pattern matching that is better. Best, Luciano
-- Greg _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/T3CJQWO7... 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
On Sat, 2021-02-06 at 22:05 -0300, Luciano Ramalho wrote:
The initial pattern matching syntax and semantics with its many corner cases may be incompatible with a future way of doing pattern matching that is better.
Then that future incompatible way should be marked with __future__, not this PEP implementation. Paul
Hello, On Sun, 07 Feb 2021 13:32:17 +1300 Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
On 7/02/21 9:58 am, Steve Holden wrote:
My suggestion that it be introduced via __future__ due to its contentious nature met immediate resistance.
__future__ is for things that are changing in incompatible ways. This is an entirely new feature that doesn't conflict with anything existing, so it doesn't need __future__.
We rented a time machine, went to the future (multiple plausible futures, as modern time machines allow, unlike the older crippled linear models, as shown in 1980is movies), saw that there were many good things missed, some requiring slightly incompatible changes, and decided to use __future__ right away.
-- Greg
-- Best regards, Paul mailto:pmiscml@gmail.com
participants (12)
-
Chris Angelico
-
Daniel Moisset
-
Greg Ewing
-
Guido van Rossum
-
Ivan Pozdeev
-
Luciano Ramalho
-
Mark Shannon
-
Oscar Benjamin
-
Paul Bryan
-
Paul Sokolovsky
-
Steve Holden
-
Steven D'Aprano