Updated PEP 3125 from Jim Jewett.

This commit is contained in:
Georg Brandl 2007-05-04 19:26:28 +00:00
parent e20d2b0e11
commit bbbe63701a
1 changed files with 204 additions and 67 deletions

View File

@ -5,99 +5,236 @@ Last-Modified: $Date$
Author: Jim J. Jewett <JimJJewett@gmail.com>
Status: Draft
Type: Standards Track
Content-Type: text/plain
Content-Type: text/x-rst
Created: 29-Apr-2007
Post-History: 29-Apr-2007, 30-Apr-2007
Post-History: 29-Apr-2007, 30-Apr-2007, 04-May-2007
Abstract
========
Python initially inherited its parsing from C. While this has
been generally useful, there are some remnants which have been
less useful for python, and should be eliminated.
Python initially inherited its parsing from C. While this has been
generally useful, there are some remnants which have been less useful
for Python, and should be eliminated.
This PEP proposes elimination of terminal "\" as a marker for
line continuation.
Rationale for Removing Explicit Line Continuation
A terminal "\" indicates that the logical line is continued on the
following physical line (after whitespace).
Note that a non-terminal "\" does not have this meaning, even if the
only additional characters are invisible whitespace. (Python depends
heavily on *visible* whitespace at the beginning of a line; it does
not otherwise depend on *invisible* terminal whitespace.) Adding
whitespace after a "\" will typically cause a syntax error rather
than a silent bug, but it still isn't desirable.
The reason to keep "\" is that occasionally code looks better with
a "\" than with a () pair.
assert True, (
"This Paren is goofy")
But realistically, that parenthesis is no worse than a "\". The
only advantage of "\" is that it is slightly more familiar to users of
C-based languages. These same languages all also support line
continuation with (), so reading code will not be a problem, and
there will be one less rule to learn for people entirely new to
programming.
This PEP proposes elimination of terminal ``\`` as a marker for line
continuation.
Alternate proposal
Motivation
==========
Several people have suggested alternative ways of marking the line
end. Most of these were rejected for not actually simplifying things.
One goal for Python 3000 should be to simplify the language by
removing unnecessary or duplicated features. There are currently
several ways to indicate that a logical line is continued on the
following physical line.
The one exception was to let any unfished expression signify a line
continuation, possibly in conjunction with increased indentation
The other continuation methods are easily explained as a logical
consequence of the semantics they provide; ``\`` is simply an escape
character that needs to be memorized.
assert True, # comma implies tuple implies continue
"No goofy parens"
The objections to this are:
Existing Line Continuation Methods
==================================
- The amount of whitespace may be contentious; expression
continuation should not be confused with opening a new
suite.
- The "expression continuation" markers are not as clearly marked
in Python as the grouping punctuation "(), [], {}" marks are.
Parenthetical Expression - ``([{}])``
-------------------------------------
"abc" + # Plus needs another operand, so it continues
"def"
Open a parenthetical expression. It doesn't matter whether people
view the "line" as continuing; they do immediately recognize that the
expression needs to be closed before the statement can end.
"abc" # String ends an expression, so
+ "def" # this is a syntax error.
Examples using each of ``()``, ``[]``, and ``{}``::
- Guido says so. [1] His reasoning is that it may not even be
feasible. (See next reason.)
def fn(long_argname1,
long_argname2):
settings = {"background": "random noise",
"volume": "barely audible"}
restrictions = ["Warrantee void if used",
"Notice must be received by yesterday",
"Not responsible for sales pitch"]
- As a technical concern, supporting this would require allowing
INDENT or DEDENT tokens anywhere, or at least in a widely
expanded (and ill-defined) set of locations. While this is
in some sense a concern only for the internal parsing
implementation, it would be a major new source of complexity. [1]
Note that it is always possible to parenthesize an expression, but it
can seem odd to parenthesize an expression that needs parentheses only
for the line break::
assert val>4, (
"val is too small")
Triple-Quoted Strings
---------------------
Open a triple-quoted string; again, people recognize that the string
needs to finish before the next statement starts.
banner_message = """
Satisfaction Guaranteed,
or DOUBLE YOUR MONEY BACK!!!
some minor restrictions apply"""
Terminal ``\`` in the general case
----------------------------------
A terminal ``\`` indicates that the logical line is continued on the
following physical line (after whitespace). There are no particular
semantics associated with this. This form is never required, although
it may look better (particularly for people with a C language
background) in some cases::
>>> assert val>4, \
"val is too small"
Also note that the ``\`` must be the final character in the line. If
your editor navigation can add whitespace to the end of a line, that
invisible change will alter the semantics of the program.
Fortunately, the typical result is only a syntax error, rather than a
runtime bug::
>>> assert val>4, \
"val is too small"
SyntaxError: unexpected character after line continuation character
This PEP proposes to eliminate this redundant and potentially
confusing alternative.
Terminal ``\`` within a string
------------------------------
A terminal ``\`` within a single-quoted string, at the end of the
line. This is arguably a special case of the terminal ``\``, but it
is a special case that may be worth keeping.
>>> "abd\
def"
'abd def'
* Pro: Many of the objections to removing ``\`` termination were
really just objections to removing it within literal strings;
several people clarified that they want to keep this literal-string
usage, but don't mind losing the general case.
* Pro: The use of ``\`` for an escape character within strings is well
known.
* Contra: But note that this particular usage is odd, because the
escaped character (the newline) is invisible, and the special
treatment is to delete the character. That said, the ``\`` of
``\(newline)`` is still an escape which changes the meaning of the
following character.
Alternate Proposals
===================
Several people have suggested alternative ways of marking the line
end. Most of these were rejected for not actually simplifying things.
The one exception was to let any unfinished expression signify a line
continuation, possibly in conjunction with increased indentation.
This is attractive because it is a generalization of the rule for
parentheses.
The initial objections to this were:
- The amount of whitespace may be contentious; expression continuation
should not be confused with opening a new suite.
- The "expression continuation" markers are not as clearly marked in
Python as the grouping punctuation "(), [], {}" marks are::
# Plus needs another operand, so the line continues
"abc" +
"def"
# String ends an expression, so the line does not
# not continue. The next line is a syntax error because
# unary plus does not apply to strings.
"abc"
+ "def"
- Guido objected for technical reasons. [#dedent]_ The most obvious
implementation would require allowing INDENT or DEDENT tokens
anywhere, or at least in a widely expanded (and ill-defined) set of
locations. While this is of concern only for the internal parsing
mechanism (rather than for users), it would be a major new source of
complexity.
Andrew Koenig then pointed out [#lexical]_ a better implementation
strategy, and said that it had worked quite well in other
languages. [#snocone]_ The improved suggestion boiled down to:
The whitespace that follows an (operator or) open bracket or
parenthesis can include newline characters.
It would be implemented at a very low lexical level -- even before
the decision is made to turn a newline followed by spaces into an
INDENT or DEDENT token.
There is still some concern that it could mask bugs, as in this
example [#guidobughide]_::
# Used to be y+1, the 1 got dropped. Syntax Error (today)
# would become nonsense.
x = y+
f(x)
Requiring that the continuation be indented more than the initial line
would add both safety and complexity.
Open Issues
===========
* Should ``\``-continuation be removed even inside strings?
* Should the continuation markers be expanded from just ([{}]) to
include lines ending with an operator?
* As a safety measure, should the continuation line be required to be
more indented than the initial line?
References
==========
.. [#dedent] (email subject) PEP 30XZ: Simplified Parsing, van Rossum
http://mail.python.org/pipermail/python-3000/2007-April/007063.html
[1] PEP 30XZ: Simplified Parsing, van Rossum
http://mail.python.org/pipermail/python-3000/2007-April/007063.html
.. [#lexical] (email subject) PEP-3125 -- remove backslash
continuation, Koenig
http://mail.python.org/pipermail/python-3000/2007-May/007237.html
.. [#snocone] The Snocone Programming Language, Koenig
http://www.snobol4.com/report.htm
.. [#guidobughide] (email subject) PEP-3125 -- remove backslash
continuation, van Rossum
http://mail.python.org/pipermail/python-3000/2007-May/007244.html
Copyright
=========
This document has been placed in the public domain.
This document has been placed in the public domain.
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End:
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End: