PEP 736: Add 'How to Teach This' (#3838)

* Minor improvements

* Expand How to Teach This

* Fix explanation of f(*,x)

* Move How to Teach This

* Remove comment about syntax highlighting

* Clarify 'one name'

* Address comments

* Highlighting other references

* Add comment about extending the AST node attributes

* Clarify logic in case of expanding syntax on mouseover

* Fix list format

* Address willingc comments

* Retain 'a very simple' for discussion

* Add 'relatively straightforward'
This commit is contained in:
Joshua Bambrick 2024-06-22 19:09:07 +01:00 committed by GitHub
parent be31ca3251
commit e7003f09f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 67 additions and 25 deletions

View File

@ -145,15 +145,6 @@ Security Implications
There are no security implications for this change. There are no security implications for this change.
How to Teach This
=================
Programmers may learn about this feature as an optional abbreviated syntax where
keyword arguments are taught. The
`Python Glossary <https://docs.python.org/3/glossary.html#term-argument>`__ and
`Tutorial <https://docs.python.org/3/tutorial/controlflow.html#keyword-arguments>`__
may be updated accordingly.
Prior Art Prior Art
========= =========
@ -200,21 +191,22 @@ The purpose of this exercise was to compute statistics about the prevalence of
this pattern and should not be interpreted as a recommendation that the proposed this pattern and should not be interpreted as a recommendation that the proposed
syntactic sugar should be applied universally. syntactic sugar should be applied universally.
===================================================================== =============== ================ ============== ============== ===================================================================== =============== ================ ============= ==============
Statistic `polars <a_>`__ `fastapi <b_>`__ `rich <c_>`__ `httpx <d_>`__ Statistic `polars <a_>`__ `fastapi <b_>`__ `rich <c_>`__ `httpx <d_>`__
===================================================================== =============== ================ ============== ============== ===================================================================== =============== ================ ============= ==============
Number of keyword arguments of the form ``f(x=x)`` at invocation 1,654 1,408 566 759 Number of keyword arguments of the form ``f(x=x)`` at invocation 1,654 1,408 566 759
Percentage of keyword arguments of the form ``f(x=x)`` at invocation 15.83% 28.11% 15.74% 45.13% Percentage of keyword arguments of the form ``f(x=x)`` at invocation 15.83% 28.11% 15.74% 45.13%
Lines saved 170 35 62 117 Lines saved 170 35 62 117
===================================================================== =============== ================ ============== ============== ===================================================================== =============== ================ ============= ==============
.. _a: https://github.com/joshuabambrick/polars/pull/1 .. _a: https://github.com/joshuabambrick/polars/pull/1
.. _b: https://github.com/joshuabambrick/fastapi/pull/1 .. _b: https://github.com/joshuabambrick/fastapi/pull/1
.. _c: https://github.com/joshuabambrick/rich/pull/1 .. _c: https://github.com/joshuabambrick/rich/pull/1
.. _d: https://github.com/joshuabambrick/httpx/pull/1 .. _d: https://github.com/joshuabambrick/httpx/pull/1
Based on this, we note that the ``f(x=x)`` keyword argument pattern is Based on this, we note that the ``f(x=x)`` keyword argument pattern is
widespread, accounting for 10-20% of all keyword argument uses. widespread, accounting for anywhere from 15% to just below half of all keyword
argument uses depending on the codebase.
Proposed Syntax Proposed Syntax
=============== ===============
@ -224,7 +216,7 @@ different forms [1]_ [2]_ [3]_ [4]_ [5]_, [6]_ we have opted to advocate
for the ``f(x=)`` form for the following reasons: for the ``f(x=)`` form for the following reasons:
* This feature has been proposed frequently over a ten year period with the * This feature has been proposed frequently over a ten year period with the
``f(x=)`` or ``f(=x)`` being by far the most common syntax [1]_ [2]_ [6]_. ``f(x=)`` or ``f(=x)`` being by far the most common syntax [1]_ [2]_ [6]_.
This is a strong indicator that it is the obvious notation. This is a strong indicator that it is the obvious notation.
* The proposed syntax closely matches the f-string debug ``f'{var=}'`` syntax * The proposed syntax closely matches the f-string debug ``f'{var=}'`` syntax
(established Pythonic style) and serves an almost identical purpose. (established Pythonic style) and serves an almost identical purpose.
@ -238,6 +230,43 @@ for the ``f(x=)`` form for the following reasons:
* `A poll of Python developers <https://discuss.python.org/t/syntactic-sugar-to-encourage-use-of-named-arguments/36217/130>`__ * `A poll of Python developers <https://discuss.python.org/t/syntactic-sugar-to-encourage-use-of-named-arguments/36217/130>`__
indicates that this is the most popular syntax among those proposed. indicates that this is the most popular syntax among those proposed.
How to Teach This
=================
To ease the communication of and search for this feature, it may also be
valuable to provide this feature with a name, such as 'keyword argument
shorthand'.
Keen Python developers will likely hear about this feature through typical
information channels, such as newsboards, social media, mailing lists, online
forums, or word of mouth. Many more will encounter this feature while reading
code and noting the omission of the value in a keyword argument at invocation,
violating their expectations. We should ensure such developers have easy access
to documentation that explains the semantics of this feature and that this
documentation is easy to find when searching. For example, the
`Python Glossary <https://docs.python.org/3/glossary.html#term-argument>`__ and
`Tutorial <https://docs.python.org/3/tutorial/controlflow.html#keyword-arguments>`__
may be updated accordingly and reasonable keywords may be used to help with
search discoverability.
`A StackOverflow question <https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/>`__
could be written to help explain this feature to those searching for an
explanation.
A teacher may explain this feature to new Python programmers as, "where you see
an argument followed by an equals sign, such as ``f(x=)``, this represents a
keyword argument where the name of the argument and its value are the same. This
can be written equivalently in the expanded notation, ``f(x=x)``." Depending on
a student's background, a teacher might further compare this to equivalent
syntax in other languages or Python's f-string syntax ``f"{x=}"``.
To understand this, a student of Python would need to be familiar with the
basics of functions in addition to the existing keyword argument syntax.
Given that this feature is a relatively straightforward syntactic sugar, it is
reasonable that a student who possesses a grasp of keyword arguments will be
able to absorb this concept quickly. This is evidenced by the success of the
f-string syntax as well as similar features in other languages (see
`Prior Art`_).
Rejected Ideas Rejected Ideas
============== ==============
@ -264,10 +293,10 @@ However, we object that:
positional or named. The ``*`` could easily be missed in a long argument list positional or named. The ``*`` could easily be missed in a long argument list
and named arguments may be read as positional or vice versa. and named arguments may be read as positional or vice versa.
* It is unclear whether keyword arguments for which the value was not elided may * It is unclear whether keyword arguments for which the value was not elided may
follow the ``*``. If so, then their relative position will be inconsistent but follow the ``*``. If so, then their relative position will be confusingly
if not, then an arbitrary grouping is enforced between different types of arbitrary, but if not, then an arbitrary grouping is enforced between
keyword arguments and reordering would be necessary if only one name was different types of keyword arguments and reordering of arguments would be
changed. necessary if only one name (the argument or its value) was changed.
* The use of ``*`` in function calls is established and this proposal would * The use of ``*`` in function calls is established and this proposal would
introduce a new effect which could cause confusion. For example, introduce a new effect which could cause confusion. For example,
``f(a, *x, y)`` would mean something different than ``f(a, *, x, y)``. ``f(a, *x, y)`` would mean something different than ``f(a, *, x, y)``.
@ -455,12 +484,24 @@ One option is to:
* Jump to the argument in the function definition if the caret/cursor is on the * Jump to the argument in the function definition if the caret/cursor is on the
argument argument
* Jump to the definition of the elided variable if the caret/cursor is on the * Jump to the definition of the elided variable if the caret/cursor is on the
character following the ``=`` in our proposed syntax. character following the ``=`` in our proposed syntax
Another, potentially complementary, option would be to expand the syntax Another, potentially complementary, option would be to expand the syntax
visually on mouseover and enable a ``Ctrl+Click`` (or ``Cmd+Click``) to the visually on mouseover and enable a ``Ctrl+Click`` (or ``Cmd+Click``) to the
definition of the variable. definition of the variable.
Highlighting other references
'''''''''''''''''''''''''''''
IDEs frequently highlight matching code references to the value at the current
caret/cursor position. With this shorthand syntax, when the caret/cursor is on
the argument name it may be valuable to either:
* Highlight both references to the argument and its value reflecting the fact
that this name now refers to both
* Visually expand the syntax on mouseover (as above) and apply established
highlighting logic according to the cursor
Rename symbol Rename symbol
''''''''''''' '''''''''''''
@ -479,7 +520,8 @@ Reference Implementation
======================== ========================
`A proposed implementation <https://github.com/Hels15/cpython/tree/last-build>`_ `A proposed implementation <https://github.com/Hels15/cpython/tree/last-build>`_
for cpython has been provided by @Hels15. for cpython has been provided by @Hels15. We will extend this implementation to
add an AST node attribute indicating for keywords whether the value was elided.
References References
========== ==========