Structure using whitespace vs logical whitespace

Terry Reedy tjreedy at udel.edu
Mon Dec 15 19:10:19 CET 2008


cmdrrickhunter at yaho.com wrote:
> I've been trying to search through the years of Python talk to find an
> answer to this, but my Googlefu is weak.
> 
> In most languages, I'll do something like this
> 
> xmlWriter.BeginElement("parent");
> ----xmlWriter.BeginElement("child");
> ----------xml.Writer.Characters("subtext");
> ----xmlWriter.EndElement();
> xmlWriter.EndElement();
> 
> Where the dashes are indentation (since some newsgroup handlers don't
> do tabs well).  XML writing is just an example.
> 
> In general, I'm using indentation to show logical flow through code.

That, of course, is what Python does.

> Python's choice to give semantic meaning to whitespace prevents me
> from doing such things.

You, of course, also want to giving semantic meaning to whitespace, but 
one that happens to be different from Python's.  'Logical control flow' 
versus 'output text structure'.

 > What was once reserved for logical use is now used syntactically.

False opposition.

> In 90% of cases, its not needed, and whitespace
> significance seems to be pretty effective.  In that last 10%, however,
> I've been frustrated many times.
> 
> I've been using python for a few years, and gotten around this in one
> way or another, but now I want to get other who work with me to pick
> up Python.  All newbies to Python have trouble with the idea of
> whitespace sensitivity,

Absolutely not true.  Python's indentation is +/- the same as what 
people routinely (but usually optionally) do when writing other 
algorithmic languages, including most pseudocode.  It also mimics 
standard outline mode and other structured text (as you with to do).

I choose Python in part *because* it has a standard mandated indentation 
scheme versus the multiple optional schemes of C programmers.  Enough of 
the endless C whitespace wars.

I strongly suggest that you not project *your* troubles onto others. 
Let them come upon it by themselves -- or not.

> but how can I convince them that "it just works better"

The tradeoff is between personal flexibility (a loss to you) and 
uniformity across programs (you can read *any* Python program and 
understand the meaning of the indentation).  Someone who does not see 
the latter as a gain perhaps should not use Python.

 > when I have this construct which I want to use but can't.

Yet

> Has anybody found a way to emulate this behavior?

New question: this answer has perhaps been posted before.
For your example, write a context manager 'Element'
(possible in 2.5+, but I use 3.0).

class Element():
     def __init__(self, item):
         self.item = item
     def __enter__(self):
         print('<element type="%s">' % self.item)
     def __exit__(self, t,v,tb):
         print('</element>')

# Then

with Element('parent'):
     with Element('child'):
         print("subtext")

# prints

<element type="parent">
<element type="child">
subtext
</element>
</element>

Of course, the element class(es) could be in a module with global indent 
and delta, methods that add and subtract the delta as appropriate, and a 
print function that prepends the current indent to get something like

<element type="parent">
   <element type="child">
     subtext
   </element>
</element>

To me, this Python-style construct is better.  You get the Element 
closure written 'for free'.  Less need to match indent levels, no 
possibility of forgetting closures. If there are multiple container 
elements with different closures, you get the right one automatically 
and cannot mismatch.

> I've often done it
> by opening an expression for the whole thing, but there's a lot of
> tasks where a single expression just isn't sufficient (such as things
> with assignment).

I do not understand this without a concrete example.

> PS. In my opinion the solution would be to have the option of entering
> a "whitespace insensitive" mode which uses C style {} and ;.

I think the above is much better ;-).

And yes, such ideas have been discussed and rejected.

Terry Jan Reedy




More information about the Python-list mailing list