[Python-ideas] An Alternate Suite Delineation Syntax For Python? (was Re: [Python-Dev] [PATCH] Adding braces to __future__)

Nick Coghlan ncoghlan at gmail.com
Sat Dec 10 06:06:13 CET 2011


A more appropriate way to phrase this suggestion would be one that
clearly states the problems with the status quo and explores them,
rather than assuming an answer, and indulging in a long rambling
diatribe against those that will shout you down for adding nothing new
to the discussion.

Step 1: post to the right mailing list (i.e. python-ideas, not python-dev)

Step 2: don't assume the conclusion in the subject line. Ask a
question, don't state an imperative. For example: "An Alternate Suite
Delineation Syntax For Python?"

Step 3: respect the time of others, by trimming your message to its core essence

For example:

An Alternate Suite Delineation Syntax For Python?
=================================================

Python's whitespace based delineation of suites is one of its greatest
strengths. It aligns what the human reader perceives with what the
computer is actually executing, reducing the frequency of semantic
errors due to mismatches between the use of separate block delimiters
and the human readable indentation.

However, this benefit comes at quite a high price: it is effectively
impossible to embed arbitrary Python statements into any environment
where leading whitespace is *not* significant, including Python's own
expression syntax.

It can be argued that this restriction has led directly to the
introduction of "expression friendly" variants of several Python top
level constructs (for example, lambda expressions, conditional
expressions and as a contributing factor in creating the various forms
of comprehension).

It is also one of the reasons Python-based templating languages almost
always create their own custom syntax - embedding Python's own
whitespace sensitive statement syntax into environments where leading
whitespace is either ignored or forms a significant part of the
template output is a formidable challenge.

In other languages, this kind of issue is handled by using explicit
suite and statement delimiters (often braces and semi-colons,
respectively) to allow full suites to be used as expressions.

While Python uses braces for another purpose (dictionary and set
definitions), it is already the case that semi-colons (';') can be
used as statement terminators, both optionally at the end of any
simple statement, and also to combine multiple simple statements into
a single larger statement (e.g. "x += y; print(x)").

It seems that this existing feature could be combined with a
brace-based notation to create an unambiguous "suite expression"
syntax that would enjoy the same semantics as ordinary Python suites
(i.e. doesn't create a new scope, doesn't directly affect control
flow), but allows *all* Python statements to be embedded inside
expressions.

Currently, the character sequence "{:" is a Syntax Error: you are
attempting to end a compound statement header line while an opening
brace remains unmatched, or else trying to build a dictionary without
specifying the key value. This creates an opportunity to re-use braces
for a suite expression syntax without conflicting with their use for
set and dictionary construction.

Specifically, it should be possible to create a variant of the
top-level Python syntax that:
  1. Explicitly delimits suites using the notation "{:" to open the
suite and "}" to end it
  2. Requires the use of ";" to separate simple statements (i.e.
newline characters would not end a statement, since we would be inside
an expression)
  3. Requires that all subordinate suites also be suite expressions
(i.e. leading whitespace would not be significant, since we would be
inside an expression)
  4. Returns the value of the last statement in the suite as the
result of the suite expression (since return statements would affect
the containing scope)
  5. Anonymous class and function definitions would be permitted in a
suite expression (but accepting only a suite expression instead of an
ordinary suite)

(Ruby block notation and C's comma expressions are pretty much direct
inspiration for the above list)

Some examples:

  Raise expressions:

    x = y if y is not None else {: raise ValueError("y must not be None!")}

  Try expressions:

    x = {: try {: y.hello} except AttributeError {: "world!"}}

  With expressions:

    data = {: with open(fname) as f {: f.read()}}

  Embedded assignments:
    if {: m = pat.search(data); m is not None}:
        # do something with m
    else:
        # No match!

  In-order conditional expressions:
    {: if a {:b} else {:c}}

  One-liner accumulator function:
    def acc(n) {: s=n; return {: def (i) {: nonlocal s; s += i; return s}}}

Cheers,
Nick.

P.S. I actually think the above idea is kinda cryptic and ugly. It is,
however, extraordinarily powerful, especially when it comes to
embedding Python code inside other environments that may not be
friendly to significant leading whitespace.

Applying the excellent set of criteria suggested by Mike Meyer:

1. What's the use case? Cleanly embedding arbitrary Python statements
inside environments that are not generally sensitive to leading
whitespace, such as templating languages, Python expressions and
Python strings.
2. Does it make such code more readable? Yes, I believe it does, by
providing "one obvious way to do it". Currently there are a mish-mash
of alternatives out there (or else people give up and use something
else entirely, like Javascript).
3. Does it encourage writing unreadable code? Perhaps. You certainly
end up with a lot of braces, colons and semi-colons floating around.
However, that's also something that can be addressed by style guides -
if people are using the embedded syntax when the indented syntax would
work fine, the problem isn't really due to the embedded syntax, it's
due to people not caring about maintainability.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list