PEP 638: Correct punctuation (accd'ing to "Gregg Ref. Man., 11th Ed.") (#1654)
* Correct numerous punctuation errors (see "Gregg Reference Manual, 11th Edition" for definition of correct punctuation). Also fix a few clumsy usages.
This commit is contained in:
parent
59baefd540
commit
3586e2004f
64
pep-0638.rst
64
pep-0638.rst
|
@ -29,7 +29,7 @@ Motivation
|
||||||
==========
|
==========
|
||||||
|
|
||||||
New language features can be controversial, disruptive and sometimes divisive.
|
New language features can be controversial, disruptive and sometimes divisive.
|
||||||
Python is now sufficiently powerful and complex, that many proposed additions
|
Python is now sufficiently powerful and complex, that many proposed additions
|
||||||
are a net loss for the language due to the additional complexity.
|
are a net loss for the language due to the additional complexity.
|
||||||
|
|
||||||
Although a language change may make certain patterns easy to express,
|
Although a language change may make certain patterns easy to express,
|
||||||
|
@ -38,7 +38,7 @@ harder to learn and harder to understand.
|
||||||
Python was once described as `Python Fits Your Brain`__,
|
Python was once described as `Python Fits Your Brain`__,
|
||||||
but that becomes less and less true as more and more features are added.
|
but that becomes less and less true as more and more features are added.
|
||||||
|
|
||||||
Because of the high cost of adding a new feature,
|
Because of the high cost of adding a new feature,
|
||||||
it is very difficult or impossible to add a feature that would benefit only
|
it is very difficult or impossible to add a feature that would benefit only
|
||||||
some users, regardless of how many users, or how beneficial that feature would
|
some users, regardless of how many users, or how beneficial that feature would
|
||||||
be to them.
|
be to them.
|
||||||
|
@ -47,17 +47,17 @@ The use of Python in data science and machine learning has grown very rapidly
|
||||||
over the last few years.
|
over the last few years.
|
||||||
However, most of the core developers of Python do not have a background in
|
However, most of the core developers of Python do not have a background in
|
||||||
data science or machine learning.
|
data science or machine learning.
|
||||||
This makes it extremely difficult for the core developers to determine if a
|
This makes it extremely difficult for the core developers to determine whether a
|
||||||
language extension for machine learning is worthwhile.
|
language extension for machine learning is worthwhile.
|
||||||
|
|
||||||
By allowing language extensions to be modular and distributable, like libraries,
|
By allowing language extensions to be modular and distributable, like libraries,
|
||||||
domain specific extensions can be implemented without negatively impacting
|
domain-specific extensions can be implemented without negatively impacting
|
||||||
users outside of that domain.
|
users outside of that domain.
|
||||||
A web developer is likely to want a very different set of extensions from
|
A web developer is likely to want a very different set of extensions from
|
||||||
a data scientist.
|
a data scientist.
|
||||||
We need to let the community develop their own extensions.
|
We need to let the community develop their own extensions.
|
||||||
|
|
||||||
Without some form of user defined language extensions,
|
Without some form of user-defined language extensions,
|
||||||
there will be a constant battle between those wanting to keep the
|
there will be a constant battle between those wanting to keep the
|
||||||
language compact and fitting their brains, and those wanting a new feature
|
language compact and fitting their brains, and those wanting a new feature
|
||||||
that suits their domain or programming style.
|
that suits their domain or programming style.
|
||||||
|
@ -70,8 +70,7 @@ Improving the expressiveness of libraries for specific domains
|
||||||
|
|
||||||
Many domains see repeated patterns that are difficult or impossible
|
Many domains see repeated patterns that are difficult or impossible
|
||||||
to express as a library.
|
to express as a library.
|
||||||
Macros can allow those patterns to be expressed in a more concise and less error
|
Macros can express those patterns in a more concise and less error-prone way.
|
||||||
prone way.
|
|
||||||
|
|
||||||
Trialing new language features
|
Trialing new language features
|
||||||
''''''''''''''''''''''''''''''
|
''''''''''''''''''''''''''''''
|
||||||
|
@ -90,14 +89,14 @@ features were still being fixed many years after they were released.
|
||||||
Long term stability for the bytecode interpreter
|
Long term stability for the bytecode interpreter
|
||||||
''''''''''''''''''''''''''''''''''''''''''''''''
|
''''''''''''''''''''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
Historically new language features have been implemented by naive compilation
|
Historically, new language features have been implemented by naive compilation
|
||||||
of the AST into new, complex bytecode instructions.
|
of the AST into new, complex bytecode instructions.
|
||||||
Those bytecodes have often had their own internal flow-control, performing
|
Those bytecodes have often had their own internal flow-control, performing
|
||||||
operations that that could, and should, have been done in the compiler.
|
operations that that could, and should, have been done in the compiler.
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
until recently flow control within the ``try``-``finally`` and ``with``
|
until recently flow control within the ``try``-``finally`` and ``with``
|
||||||
statements was managed by complicated bytecodes with context dependent semantics.
|
statements was managed by complicated bytecodes with context-dependent semantics.
|
||||||
The control flow within those statements is now implemented in the compiler, making
|
The control flow within those statements is now implemented in the compiler, making
|
||||||
the interpreter simpler and faster.
|
the interpreter simpler and faster.
|
||||||
|
|
||||||
|
@ -111,10 +110,10 @@ Rationale
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Python is both expressive and easy to learn;
|
Python is both expressive and easy to learn;
|
||||||
it is widely recognized as the easiest to learn widely-used programming language.
|
it is widely recognized as the easiest-to-learn, widely used programming language.
|
||||||
However, it is not the most flexible. That title belongs to lisp.
|
However, it is not the most flexible. That title belongs to lisp.
|
||||||
|
|
||||||
Because lisp is homoiconic, meaning that lisp programs are lisp data-structures,
|
Because lisp is homoiconic, meaning that lisp programs are lisp data structures,
|
||||||
lisp programs can be manipulated by lisp programs.
|
lisp programs can be manipulated by lisp programs.
|
||||||
Thus much of the language can be defined in itself.
|
Thus much of the language can be defined in itself.
|
||||||
|
|
||||||
|
@ -168,7 +167,7 @@ Semantics
|
||||||
Compilation
|
Compilation
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
Upon encountering a ``macro`` during translation to bytecode,
|
Upon encountering a ``macro`` during translation to bytecode,
|
||||||
the code generator will look up the macro processor registered for the macro,
|
the code generator will look up the macro processor registered for the macro,
|
||||||
and pass the AST, rooted at the macro to the processor function.
|
and pass the AST, rooted at the macro to the processor function.
|
||||||
The returned AST will then be substituted for the original tree.
|
The returned AST will then be substituted for the original tree.
|
||||||
|
@ -196,11 +195,11 @@ They support the following syntax:
|
||||||
|
|
||||||
"from!" dotted_name "import" name [ "as" name ]
|
"from!" dotted_name "import" name [ "as" name ]
|
||||||
|
|
||||||
The ``import!`` macro performs a compile time import of ``dotted_name``
|
The ``import!`` macro performs a compile-time import of ``dotted_name``
|
||||||
to find the macro processor, then registers it under ``name``
|
to find the macro processor, then registers it under ``name``
|
||||||
for the scope currently being compiled.
|
for the scope currently being compiled.
|
||||||
|
|
||||||
The ``from!`` macro performs a compile time import of ``dotted_name.name``
|
The ``from!`` macro performs a compile-time import of ``dotted_name.name``
|
||||||
to find the macro processor, then registers it under ``name``
|
to find the macro processor, then registers it under ``name``
|
||||||
(using the ``name`` following "as", if present)
|
(using the ``name`` following "as", if present)
|
||||||
for the scope currently being compiled.
|
for the scope currently being compiled.
|
||||||
|
@ -225,7 +224,7 @@ A macro processor is defined by a four-tuple, consisting of
|
||||||
* ``func`` must be a callable that takes ``len(additional_names)+1`` arguments, all of which are abstract syntax trees, and returns a single abstract syntax tree.
|
* ``func`` must be a callable that takes ``len(additional_names)+1`` arguments, all of which are abstract syntax trees, and returns a single abstract syntax tree.
|
||||||
* ``kind`` must be one of the following:
|
* ``kind`` must be one of the following:
|
||||||
|
|
||||||
* ``macros.STMT_MACRO`` A statement macro where the body of the macro is indented. This is the only form which is allowed to have additional names.
|
* ``macros.STMT_MACRO`` A statement macro where the body of the macro is indented. This is the only form allowed to have additional names.
|
||||||
* ``macros.SIBLING_MACRO`` A statement macro where the body of the macro is the next statement is the same block. The following statement is moved into the macro as its body.
|
* ``macros.SIBLING_MACRO`` A statement macro where the body of the macro is the next statement is the same block. The following statement is moved into the macro as its body.
|
||||||
* ``macros.EXPR_MACRO`` An expression macro.
|
* ``macros.EXPR_MACRO`` An expression macro.
|
||||||
|
|
||||||
|
@ -286,7 +285,7 @@ Two new AST nodes will be needed to express macros, ``macro_stmt`` and ``macro_e
|
||||||
|
|
||||||
_fields = "name", "args"
|
_fields = "name", "args"
|
||||||
|
|
||||||
In addition, macro processors will needs a means to express control flow or side effecting code, that produces a value.
|
In addition, macro processors will needs a means to express control flow or side-effecting code, that produces a value.
|
||||||
To support this, a new ast node, called ``stmt_expr``, that combines a statement and expression will be added.
|
To support this, a new ast node, called ``stmt_expr``, that combines a statement and expression will be added.
|
||||||
This new ast node will be a subtype of ``expr``, but include a statement to allow side effects.
|
This new ast node will be a subtype of ``expr``, but include a statement to allow side effects.
|
||||||
It will be compiled to bytecode by compiling the statement, then compiling the value.
|
It will be compiled to bytecode by compiling the statement, then compiling the value.
|
||||||
|
@ -300,7 +299,7 @@ It will be compiled to bytecode by compiling the statement, then compiling the v
|
||||||
Hygiene and debugging
|
Hygiene and debugging
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Macros processors will often need to create new variables.
|
Macro processors will often need to create new variables.
|
||||||
Those variables need to named in such as way as to avoid contaminating the original code and other macros.
|
Those variables need to named in such as way as to avoid contaminating the original code and other macros.
|
||||||
No rules for naming will be enforced, but to ensure hygiene and help debugging, the following naming scheme is recommended:
|
No rules for naming will be enforced, but to ensure hygiene and help debugging, the following naming scheme is recommended:
|
||||||
|
|
||||||
|
@ -318,13 +317,13 @@ Examples:
|
||||||
Examples
|
Examples
|
||||||
''''''''
|
''''''''
|
||||||
|
|
||||||
Compile time checked data structures
|
Compile-time-checked data structures
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
It is common to encode tables of data in Python as large dictionaries.
|
It is common to encode tables of data in Python as large dictionaries.
|
||||||
However, these can be hard to maintain and error prone.
|
However, these can be hard to maintain and error prone.
|
||||||
Macros allow this data to be written in a more readable format.
|
Macros allow such data to be written in a more readable format.
|
||||||
Then, at compile time, it can be verified and converted to an efficient format.
|
Then, at compile time, the data can be verified and converted to an efficient format.
|
||||||
|
|
||||||
For example, suppose we have a two dictionary literals mapping codes to names,
|
For example, suppose we have a two dictionary literals mapping codes to names,
|
||||||
and vice versa.
|
and vice versa.
|
||||||
|
@ -355,10 +354,10 @@ would become:
|
||||||
"blue" = 2
|
"blue" = 2
|
||||||
"green" = 3
|
"green" = 3
|
||||||
|
|
||||||
Domain specific extensions
|
Domain-specific extensions
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Where I see macros having real value is in specific domains, not in general purpose language features.
|
Where I see macros having real value is in specific domains, not in general-purpose language features.
|
||||||
|
|
||||||
For example, parsers.
|
For example, parsers.
|
||||||
Here's part of a parser definition for Python, using macros:
|
Here's part of a parser definition for Python, using macros:
|
||||||
|
@ -366,7 +365,7 @@ Here's part of a parser definition for Python, using macros:
|
||||||
::
|
::
|
||||||
|
|
||||||
choice! single_input:
|
choice! single_input:
|
||||||
NEWLINE
|
NEWLINE
|
||||||
simple_stmt
|
simple_stmt
|
||||||
sequence!:
|
sequence!:
|
||||||
compound_stmt
|
compound_stmt
|
||||||
|
@ -381,7 +380,7 @@ It would be simpler and more reliable for them to get the AST directly:
|
||||||
::
|
::
|
||||||
|
|
||||||
from! my.jit.library import jit
|
from! my.jit.library import jit
|
||||||
|
|
||||||
jit!
|
jit!
|
||||||
def func():
|
def func():
|
||||||
...
|
...
|
||||||
|
@ -389,9 +388,9 @@ It would be simpler and more reliable for them to get the AST directly:
|
||||||
Matching symbolic expressions
|
Matching symbolic expressions
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
When matching something representing syntax, such a Python ``ast`` node, or a ``sympy`` expression,
|
When matching something representing syntax, such a Python ``ast`` node, or a ``sympy`` expression,
|
||||||
it is convenient to match against the actual syntax, not the data structure representing it.
|
it is convenient to match against the actual syntax, not the data structure representing it.
|
||||||
For example, a calculator could be implemented using a domain specific macro for matching syntax:
|
For example, a calculator could be implemented using a domain-specific macro for matching syntax:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -409,7 +408,7 @@ For example, a calculator could be implemented using a domain specific macro for
|
||||||
return calculate(a) * calculate(b)
|
return calculate(a) * calculate(b)
|
||||||
case! a / b:
|
case! a / b:
|
||||||
return calculate(a) / calculate(b)
|
return calculate(a) / calculate(b)
|
||||||
|
|
||||||
Which could be converted to:
|
Which could be converted to:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -431,7 +430,7 @@ Which could be converted to:
|
||||||
a, b = $$match_4_0.left, $$match_4_0.right
|
a, b = $$match_4_0.left, $$match_4_0.right
|
||||||
return calculate(a) / calculate(b)
|
return calculate(a) / calculate(b)
|
||||||
|
|
||||||
Zero cost markers and annotations
|
Zero-cost markers and annotations
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Annotations, either decorators or PEP 3107 function annotations, have a runtime cost
|
Annotations, either decorators or PEP 3107 function annotations, have a runtime cost
|
||||||
|
@ -443,7 +442,7 @@ even if they serve only as markers for checkers or as documentation.
|
||||||
def foo(...):
|
def foo(...):
|
||||||
...
|
...
|
||||||
|
|
||||||
can be replaced with the zero cost macro:
|
can be replaced with the zero-cost macro:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -454,14 +453,14 @@ can be replaced with the zero cost macro:
|
||||||
Protyping language extensions
|
Protyping language extensions
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Although macros would be most valuable for domain specific extensions, it is possible to
|
Although macros would be most valuable for domain-specific extensions, it is possible to
|
||||||
demonstrate possible language extensions using macros.
|
demonstrate possible language extensions using macros.
|
||||||
|
|
||||||
f-strings:
|
f-strings:
|
||||||
..........
|
..........
|
||||||
|
|
||||||
The f-string ``f"..."`` could be implemented as macro as ``f!("...")``.
|
The f-string ``f"..."`` could be implemented as macro as ``f!("...")``.
|
||||||
Which is not quite as nice to read, but would still be useful for experimenting with.
|
Not quite as nice to read, but would still be useful for experimenting with.
|
||||||
|
|
||||||
Try finally statement:
|
Try finally statement:
|
||||||
......................
|
......................
|
||||||
|
@ -472,7 +471,7 @@ Try finally statement:
|
||||||
body
|
body
|
||||||
finally!:
|
finally!:
|
||||||
closing
|
closing
|
||||||
|
|
||||||
Would be translated roughly as:
|
Would be translated roughly as:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -583,4 +582,3 @@ CC0-1.0-Universal license, whichever is more permissive.
|
||||||
fill-column: 70
|
fill-column: 70
|
||||||
coding: utf-8
|
coding: utf-8
|
||||||
End:
|
End:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue