249 lines
7.4 KiB
ReStructuredText
249 lines
7.4 KiB
ReStructuredText
PEP: 3125
|
||
Title: Remove Backslash Continuation
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: Jim J. Jewett <JimJJewett@gmail.com>
|
||
Status: Rejected
|
||
Type: Standards Track
|
||
Content-Type: text/x-rst
|
||
Created: 29-Apr-2007
|
||
Post-History: 29-Apr-2007, 30-Apr-2007, 04-May-2007
|
||
|
||
|
||
Rejection Notice
|
||
================
|
||
|
||
This PEP is rejected. There wasn't enough support in favor, the
|
||
feature to be removed isn't all that harmful, and there are some use
|
||
cases that would become harder.
|
||
|
||
|
||
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.
|
||
|
||
This PEP proposes elimination of terminal ``\`` as a marker for line
|
||
continuation.
|
||
|
||
|
||
Motivation
|
||
==========
|
||
|
||
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 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.
|
||
|
||
|
||
Existing Line Continuation Methods
|
||
==================================
|
||
|
||
|
||
Parenthetical Expression - ``([{}])``
|
||
-------------------------------------
|
||
|
||
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.
|
||
|
||
Examples using each of ``()``, ``[]``, and ``{}``::
|
||
|
||
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"]
|
||
|
||
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
|
||
https://mail.python.org/pipermail/python-3000/2007-April/007063.html
|
||
|
||
.. [#lexical] (email subject) :pep:`3125` -- remove backslash
|
||
continuation, Koenig
|
||
https://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
|
||
https://mail.python.org/pipermail/python-3000/2007-May/007244.html
|
||
|
||
|
||
Copyright
|
||
=========
|
||
|
||
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:
|