Structure using whitespace vs logical whitespace

Discussion in 'Python' started by cmdrrickhunter@yaho.com, Dec 15, 2008.

  1. Guest

    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.
    Python's choice to give semantic meaning to whitespace prevents me
    from doing such things. What was once reserved for logical use is now
    used syntactically. 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, but how can I convince them that "it just
    works better" when I have this construct which I want to use but
    can't.

    Has anybody found a way to emulate this behavior? 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).

    PS. In my opinion the solution would be to have the option of entering
    a "whitespace insensitive" mode which uses C style {} and ;. The
    token to enter it could be as complicated as you want (in fact, it may
    make sense to make it complicated to discourage use unless it's really
    advantageous). I'd sugest {{ and }} or something bigger like {={ }
    =}. Only two problems: 1) I'm sure it would offend Guido's sense of
    language aesthetics 2) I'm sure the idea has been hashed over on this
    newsgroup to death... hence prefering a workaround instead.
    , Dec 15, 2008
    #1
    1. Advertising

  2. MRAB Guest

    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.
    > Python's choice to give semantic meaning to whitespace prevents me
    > from doing such things. What was once reserved for logical use is now
    > used syntactically. 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, but how can I convince them that "it just
    > works better" when I have this construct which I want to use but
    > can't.
    >
    > Has anybody found a way to emulate this behavior? 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).
    >
    > PS. In my opinion the solution would be to have the option of entering
    > a "whitespace insensitive" mode which uses C style {} and ;. The
    > token to enter it could be as complicated as you want (in fact, it may
    > make sense to make it complicated to discourage use unless it's really
    > advantageous). I'd sugest {{ and }} or something bigger like {={ }
    > =}. Only two problems: 1) I'm sure it would offend Guido's sense of
    > language aesthetics 2) I'm sure the idea has been hashed over on this
    > newsgroup to death... hence prefering a workaround instead.
    >

    You could use the "with" statement:

    class xml_element(object):
    def __init__(self, text):
    self.text = text
    def __enter__(self):
    xmlWriter.BeginElement(self.text)
    def __exit__(self, *args):
    xmlWriter.EndElement()

    with xml_element("parent"):
    with xml_element("child"):
    xmlWriter.Characters("subtext")
    MRAB, Dec 15, 2008
    #2
    1. Advertising

  3. Marek_SP Guest

    On 15 Gru, 18:14, MRAB <> wrote:
    > 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.
    > > Python's choice to give semantic meaning to whitespace prevents me
    > > from doing such things.  What was once reserved for logical use is now
    > > used syntactically.  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, but how can I convince them that "it just
    > > works better" when I have this construct which I want to use but
    > > can't.

    >
    > > Has anybody found a way to emulate this behavior?  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).

    >
    > > PS. In my opinion the solution would be to have the option of entering
    > > a "whitespace insensitive" mode which uses C style {} and ;.  The
    > > token to enter it could be as complicated as you want (in fact, it may
    > > make sense to make it complicated to discourage use unless it's really
    > > advantageous).  I'd sugest {{ and }} or something bigger like {={ }
    > > =}.  Only two problems: 1) I'm sure it would offend Guido's sense of
    > > language aesthetics  2) I'm sure the idea has been hashed over on this
    > > newsgroup to death... hence prefering a workaround instead.

    >
    > You could use the "with" statement:
    >
    > class xml_element(object):
    >      def __init__(self, text):
    >          self.text = text
    >      def __enter__(self):
    >          xmlWriter.BeginElement(self.text)
    >      def __exit__(self, *args):
    >          xmlWriter.EndElement()
    >
    > with xml_element("parent"):
    >      with xml_element("child"):
    >          xmlWriter.Characters("subtext")


    Yep, I think that's what Guido was thinking about while adding `with`
    statements. They're great at grouping code logically. Before I used
    `if True:` to do this but it wasn't good looking.
    Marek_SP, Dec 15, 2008
    #3
  4. Terry Reedy Guest

    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
    Terry Reedy, Dec 15, 2008
    #4
  5. Guest

    On Dec 15, 11:10 am, Terry Reedy <> wrote:
    > > In general, I'm using indentation to show logical flow through code.

    >
    > That, of course, is what Python does.
    >

    Python does NOT use indentation to show logical flow. It uses it to
    show syntactical flow. The XML writer is the perfect example of a
    case where they are different. In most cases, syntactic flow is close
    enough to logical flow. There are a few cases where you can 'draw a
    picture' of the algorithm in code if you are whitespace insensitive.

    I've not used the "with" keyword before, and it does seem to handle
    this troublesome case quite well. I learned python before it was
    around, and never really studied it hard enough. I'll have to
    investigate what other tricks can be done with it.

    I'm a big fan of the rule "make the 90% easy and the remaining 10%
    possible." Whitespace sensitivity makes the 90% easy, and just from
    the looks of it, the 'with' command and whitespace insensitive
    expressions give the remaining 10%. And I do like the automated
    support for "finally" clauses when using 'with'

    Thanks for the help, everyone!
    , Dec 15, 2008
    #5
  6. On Mon, 15 Dec 2008 12:27:12 -0800, wrote:

    > On Dec 15, 11:10 am, Terry Reedy <> wrote:
    >> > In general, I'm using indentation to show logical flow through code.

    >>
    >> That, of course, is what Python does.
    >>

    > Python does NOT use indentation to show logical flow. It uses it to
    > show syntactical flow.


    What the heck is "syntactical flow"? Of course Python uses indentation
    for logical flow -- the indentation reflects the program logic.

    > The XML writer is the perfect example of a case where they are
    > different.


    No the program flow there is just some linear calls to methods. It's the
    XML structure that is not reflected by the indentation, the program flow
    is represented just fine here.

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Dec 15, 2008
    #6
  7. > 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.


    Well, XML beeing just an example.. but still for XML in Python you
    probably want to use some XML templating library like Genshi. And for
    other stuff there are probably similar sollutions.


    --
    дамјан ( http://softver.org.mk/damjan/ )

    war is peace
    freedom is slavery
    restrictions are enablement
    Дамјан ГеоргиевÑки, Dec 16, 2008
    #7
  8. En Mon, 15 Dec 2008 14:29:31 -0200,
    <> escribió:

    > PS. In my opinion the solution would be to have the option of entering
    > a "whitespace insensitive" mode which uses C style {} and ;. The
    > token to enter it could be as complicated as you want (in fact, it may
    > make sense to make it complicated to discourage use unless it's really
    > advantageous). I'd sugest {{ and }} or something bigger like {={ }
    > =}. Only two problems: 1) I'm sure it would offend Guido's sense of
    > language aesthetics 2) I'm sure the idea has been hashed over on this
    > newsgroup to death... hence prefering a workaround instead.


    It's a hidden feature, already implemented. Try:

    from __future__ import braces


    --
    Gabriel Genellina
    Gabriel Genellina, Dec 16, 2008
    #8
  9. Ken Seehart Guest

    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.
    >

    Yes, I hate that too. IMO Newsgroup and email clients should not remove
    indentation.
    > In general, I'm using indentation to show logical flow through code.
    > Python's choice to give semantic meaning to whitespace prevents me
    > from doing such things. What was once reserved for logical use is now
    > used syntactically. 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.
    >

    When I first learned python I was occasionally bothered by this. Since
    then I have gotten used
    to it and would not have it any other way. I certainly would not
    consider changing the language
    for this. I consider the benefits of a uniform meaning of whitespace
    and the corresponding
    consistency of indentation style, as well as the lack of punctuation, to
    be well worth the price.
    Also, I have found over the years that, for reasons described below,
    that this "price" effectively
    drops to zero.
    > 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, but how can I convince them that "it just
    > works better" when I have this construct which I want to use but
    > can't.
    >

    I disagree with the generalization that "All newbies to Python have
    trouble with the idea...". I
    would say that perhaps most newbies that have experience with whitespace
    neutral languages
    experience some initial discomfort, which is expected for any change
    from what one is used to.
    I suspect that very few people who are new to programming dislike
    whitespace sensitivity.
    > Has anybody found a way to emulate this behavior? 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).
    >

    This would depend on the specific case. In general, if you are writing
    lots of code that contains
    structure other than program control structure, you probably are missing
    an opportunity to use a
    data-driven approach.

    In other words, ideally the structure in your python code should be
    /only /program control structure,
    in which case the indentation will be exactly where you would want it to
    be. For that other 10%,
    you probably should code your content as data (either in an external
    file or as data literals in your
    code).

    The case in point is your example:

    xmlWriter.BeginElement("parent");
    ----xmlWriter.BeginElement("child");
    ----------xml.Writer.Characters("subtext");
    ----xmlWriter.EndElement();
    xmlWriter.EndElement();

    I would use a template system such as Genshi instead, so that kind of
    structure would not need
    to be in my python code in the first place.

    I know that this xmlWriter code is just an example, but I think that the
    principle I am describing
    really does apply more or less universally. If you are expressing
    nested structure other than
    program control structure, you should be expressing your structure as data.

    Here's another solution to your example that is more generally
    applicable to other situations:

    content = (element, "parent", [
    (element, "child", [
    (characters, "subtext"),
    ] ),
    ] )

    do_something_with(content)

    (Sorry if the above indentation has been removed by evil software....)

    In this case I have made the code data-driven, but include the data in
    my python code. This
    means you have the extra task of implementing *do_something_with()* but
    that is usually a
    trivial task, and worth the effort IMO because it makes the structure
    more readable and easier
    to modify. It also separates content from implementation, which is also
    a really good idea. For
    example, if at some point in the future I decide to use something else
    instead of *xmlWriter *to
    process the data, I can do so by changing the implementation of
    *do_something_with()*.
    > PS. In my opinion the solution would be to have the option of entering
    > a "whitespace insensitive" mode which uses C style {} and ;. The
    > token to enter it could be as complicated as you want (in fact, it may
    > make sense to make it complicated to discourage use unless it's really
    > advantageous). I'd sugest {{ and }} or something bigger like {={ }
    > =}. Only two problems: 1) I'm sure it would offend Guido's sense of
    > language aesthetics 2) I'm sure the idea has been hashed over on this
    > newsgroup to death... hence prefering a workaround instead.
    >

    A definitive "Yes" to both 1 and 2 :) And I wouldn't even consider my
    proposed solutions to
    be "workarounds" with respect to the alleged problem of syntactical
    whitespace. I would want
    to use the same approach in C or Java simply because I prefer a
    data-driven approach where
    appropriate. Python's container literals make it particularly easy to
    express data in your code.
    It just so happens that there is a high correlation between the
    temptation to use indentation for
    non-programmatic structure and the appropriateness of a data-driven
    implementation.

    The problem with adding redundant syntactical forms (such as your
    proposed {{...}}), is that it
    complicates the language. This has two effects:

    1. In order to master the language you have to learn more (mastering the
    language includes the
    ability to read other peoples code as well as writing new code).

    2. It produces greater variance in style based on personal preference.
    Generally, code is easier
    to read when everyone uses consistent style.

    One of the things that people like about python is the relative
    infrequency of special characters.
    This gives python a certain flavor. I happen to like this flavor a
    lot. Some people don't, and I
    recommend Perl to them. But switching between two distinct dialects of
    python does not seem
    like a wise idea.

    I hope this helps.

    Ken Seehart
    Ken Seehart, Dec 16, 2008
    #9
  10. Lie Ryan Guest

    On Mon, 15 Dec 2008 08:29:31 -0800, 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.
    > Python's choice to give semantic meaning to whitespace prevents me from
    > doing such things. What was once reserved for logical use is now used
    > syntactically. 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, but how can I convince them that "it just works better"
    > when I have this construct which I want to use but can't.
    >
    > Has anybody found a way to emulate this behavior? 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).
    >
    > PS. In my opinion the solution would be to have the option of entering a
    > "whitespace insensitive" mode which uses C style {} and ;. The token to
    > enter it could be as complicated as you want (in fact, it may make sense
    > to make it complicated to discourage use unless it's really
    > advantageous). I'd sugest {{ and }} or something bigger like {={ } =}.
    > Only two problems: 1) I'm sure it would offend Guido's sense of language
    > aesthetics 2) I'm sure the idea has been hashed over on this newsgroup
    > to death... hence prefering a workaround instead.


    It's possible (although no real python programmers would do it) to use a
    code preprocessor that would search for special marked sections in which
    spacing would be ignored and punctuations or end-of-block marker would be
    used to determine spacings.
    Lie Ryan, Dec 16, 2008
    #10
  11. Eric Brunel Guest

    On Tue, 16 Dec 2008 10:00:32 +0100, Gabriel Genellina
    <> wrote:

    > En Mon, 15 Dec 2008 14:29:31 -0200,
    > <> escribió:
    >
    >> PS. In my opinion the solution would be to have the option of entering
    >> a "whitespace insensitive" mode which uses C style {} and ;. The
    >> token to enter it could be as complicated as you want (in fact, it may
    >> make sense to make it complicated to discourage use unless it's really
    >> advantageous). I'd sugest {{ and }} or something bigger like {={ }
    >> =}. Only two problems: 1) I'm sure it would offend Guido's sense of
    >> language aesthetics 2) I'm sure the idea has been hashed over on this
    >> newsgroup to death... hence prefering a workaround instead.

    >
    > It's a hidden feature, already implemented. Try:
    >
    > from __future__ import braces


    I was almost shocked so I tried it. It's much clearer now... ;-)
    --
    python -c "print ''.join([chr(154 - ord(c)) for c in
    'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
    Eric Brunel, Dec 16, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oli Filth
    Replies:
    9
    Views:
    3,314
    Uncle Pirate
    Jan 17, 2005
  2. Excluded_Middle

    Pointers to structure and array of structure.

    Excluded_Middle, Oct 24, 2004, in forum: C Programming
    Replies:
    4
    Views:
    735
    Martin Ambuhl
    Oct 26, 2004
  3. Replies:
    7
    Views:
    473
    Mike Treseler
    Jul 12, 2007
  4. MRAB
    Replies:
    3
    Views:
    369
  5. Ricky
    Replies:
    6
    Views:
    970
    Phil Carmody
    Apr 15, 2010
Loading...

Share This Page