PEP for experimental/provisional features

Reading the latest discussion about PEP 622/634-636 on the Python Dev mailing list, I've noticed there appears to be confusion about what `__future__` imports are supposed to be used for. Multiple people in that thread (and probably elsewhere in one of the many many threads about these PEPs) have suggested including pattern matching as a "provisional" or "experimental" feature that is enabled by an import from `__future__`. I don't want to discuss whether `__future__` is the correct place for this however (and I also don't want to discuss PEP 622/634-636 specifically). Instead I'd like to propose a `__provisional__` namespace (or whatever color you favor for your bike shed) for new language features/ standard library modules that might undergo breaking changes over a couple of subsequent python releases. This is similar to how many applications start in a version V0.1 and undergo changes until they mature and reach V1.0. From the user perspective this would allow more "adventurous" users to play with the latest features (with the clear warning attached that they might have to adapt their own code over subsequent python releases) while anyone else can just ignore the new feature for now. From the perspective of the language designers the advantage I see is that they can get a first version of a feature out to real users to collect feedback on whether the feature is used as they imagined it being used and change/iterate the design if need be. It is simply unrealistic to get something like `asyncio` or PEP 622/634-636 perfect and feature complete on the first try or otherwise wait indefinitely until something is ready. Some thoughts what `__provisional__` SHOULD and SHOULD NOT be used for: - `__provisional__` SHOULD be useable at the users own discretion (e.g. no use of provisional features in the standard library etc. ) - `__provisional__` SHOULD be a place for features with a vast design space that need to "ripen" as use cases are explored (`asyncio` would have been the poster child candidate for `__provisional__`) - features SHOULD only be placed in `__provisional__` if there is a clear commitment to the feature (the general feature is accepted by the SC before being included in `__provisional__`). `__provisional__` SHOULD NOT be a place where contentious PEPs are thrown into willy-nilly and postpone the decision of whether to accept a PEP or not. Otherwise users would not only have to deal with changes to a feature (they obviously showed interest in using) but also with complete removal/deprecation. - `__provisional__` SHOULD only be used for features that are additive to the language and don't change existing code (which is what imho. what `__future__` is for). - `__provisional__` SHOULD have a clearly defined process (timelines etc.) Alternative ideas that have been mentioned (in threads about PEP 622/634-636 and elsewhere) and why I personally don't think they are sufficient: - "just throw together a library that parses strings and uses `eval`, put it on pypi to see how that goes": For features that require new syntax this just doesn't work imho. Using `pep622_lib.match("put your match statement here")` is a very poor substitute for trying this out due to the influence design choices such as keywords, indentation etc. have on usability. Examples for this are syntax highlighting, autocomplete/autoindent/autoformat and linting which you just don't get this way. - various degrees of: "solve the issue of contention over new languages features once and for all by introducing macros/preprocessors to the language": Against this I have just my personal plea "please don't turn python into lisp/c++".

To clarify, the point of __provisional__ would be to enable some syntactical feature in the language that should not be considered stable? I'm not sure I see a reason to use this for a new module or package in stdlib for example; a docstring or perhaps some decorator like @provisional could indicate a class or function is not ready for prime time. If I'm correct, then the contract of __provisional__ would be: * here's a new language feature you can use * it's subject to change in future releases; you'll need to change your code accordingly if it changes * because it's language change, it's unlikely you can conditionally choose which syntax to use based on the version of Python being used * you enable it explicitly and accept the instability of the language feature Paul On Sun, 2021-02-07 at 13:14 +0000, sascha.schlemmer--- via Python-ideas wrote:

Thats the gist of it, yes. One example that comes to mind from PEP 622/634-636 would be the special casing of `True`, `False` to use identity (`is True`) for comparison and not equality (`== True`). As far as I remember this was not in PEP622 originally and if it were released this way would have been impossible to change later.

To clarify, the point of __provisional__ would be to enable some syntactical feature in the language that should not be considered stable? I'm not sure I see a reason to use this for a new module or package in stdlib for example; a docstring or perhaps some decorator like @provisional could indicate a class or function is not ready for prime time. If I'm correct, then the contract of __provisional__ would be: * here's a new language feature you can use * it's subject to change in future releases; you'll need to change your code accordingly if it changes * because it's language change, it's unlikely you can conditionally choose which syntax to use based on the version of Python being used * you enable it explicitly and accept the instability of the language feature Paul On Sun, 2021-02-07 at 13:14 +0000, sascha.schlemmer--- via Python-ideas wrote:

Thats the gist of it, yes. One example that comes to mind from PEP 622/634-636 would be the special casing of `True`, `False` to use identity (`is True`) for comparison and not equality (`== True`). As far as I remember this was not in PEP622 originally and if it were released this way would have been impossible to change later.
participants (2)
-
Paul Bryan
-
sascha.schlemmer@me.com