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:
parent
be31ca3251
commit
e7003f09f9
|
@ -145,15 +145,6 @@ Security Implications
|
|||
|
||||
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
|
||||
=========
|
||||
|
||||
|
@ -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
|
||||
syntactic sugar should be applied universally.
|
||||
|
||||
===================================================================== =============== ================ ============== ==============
|
||||
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
|
||||
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
|
||||
===================================================================== =============== ================ ============== ==============
|
||||
===================================================================== =============== ================ ============= ==============
|
||||
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
|
||||
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
|
||||
===================================================================== =============== ================ ============= ==============
|
||||
|
||||
.. _a: https://github.com/joshuabambrick/polars/pull/1
|
||||
.. _b: https://github.com/joshuabambrick/fastapi/pull/1
|
||||
.. _c: https://github.com/joshuabambrick/rich/pull/1
|
||||
.. _d: https://github.com/joshuabambrick/httpx/pull/1
|
||||
|
||||
Based on this, we note that the ``f(x=x)`` keyword argument pattern is
|
||||
widespread, accounting for 10-20% of all keyword argument uses.
|
||||
Based on this, we note that the ``f(x=x)`` keyword argument pattern is
|
||||
widespread, accounting for anywhere from 15% to just below half of all keyword
|
||||
argument uses depending on the codebase.
|
||||
|
||||
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:
|
||||
|
||||
* 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.
|
||||
* The proposed syntax closely matches the f-string debug ``f'{var=}'`` syntax
|
||||
(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>`__
|
||||
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
|
||||
==============
|
||||
|
||||
|
@ -264,10 +293,10 @@ However, we object that:
|
|||
positional or named. The ``*`` could easily be missed in a long argument list
|
||||
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
|
||||
follow the ``*``. If so, then their relative position will be inconsistent but
|
||||
if not, then an arbitrary grouping is enforced between different types of
|
||||
keyword arguments and reordering would be necessary if only one name was
|
||||
changed.
|
||||
follow the ``*``. If so, then their relative position will be confusingly
|
||||
arbitrary, but if not, then an arbitrary grouping is enforced between
|
||||
different types of keyword arguments and reordering of arguments would be
|
||||
necessary if only one name (the argument or its value) was changed.
|
||||
* The use of ``*`` in function calls is established and this proposal would
|
||||
introduce a new effect which could cause confusion. For example,
|
||||
``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
|
||||
argument
|
||||
* 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
|
||||
visually on mouseover and enable a ``Ctrl+Click`` (or ``Cmd+Click``) to the
|
||||
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
|
||||
'''''''''''''
|
||||
|
||||
|
@ -479,7 +520,8 @@ Reference Implementation
|
|||
========================
|
||||
|
||||
`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
|
||||
==========
|
||||
|
|
Loading…
Reference in New Issue