An Alternate Suite Delineation Syntax For Python? (was Re: [Python-Dev] [PATCH] Adding braces to __future__)
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@gmail.com | Brisbane, Australia
participants (19)
-
Bruce Leban
-
Ethan Furman
-
Greg Ewing
-
Guido van Rossum
-
Jeremy Sanders
-
Jim Jewett
-
Masklinn
-
Massimo Di Pierro
-
Mathias Panzenböck
-
Matt Joiner
-
Mike Meyer
-
MRAB
-
Nick Coghlan
-
Oleg Broytman
-
Paul Moore
-
Ron Adam
-
Steven D'Aprano
-
Terry Reedy
-
Yuval Greenfield