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.
|
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
|
||||||
==========
|
==========
|
||||||
|
|
Loading…
Reference in New Issue