Indentation and grouping proposal

R Wentworth rhww at erols.com
Sun Jun 6 22:57:41 EDT 1999


I am reasonably fond of Python's grouping-via-indentation 
paradigm.  Even so, it occurs to me that there may be
legitimate reasons to consider adding a feature to allow
non-indentation-based grouping.

I might envision this being done via the introduction
of two new tokens, e.g., "_{" and "}_".  These would
have the following significance:

    _{  if it is preceded by non-whitespace:
            ends the current logical line and
            begins a new one
        acts like an INDENT token, but the entry it
            pushes onto the indentation stack is
            not a positive integer
        disables interpretation of indentation until
            matching }_ is reached

    }_  ends the current logical line
        acts like a DEDENT token, and pops the top entry
            (which must not be a positive integer)
            off the indentation stack
    
    As a slight extension of the feature, it should be legal to
    use _{ }_ to enclose the outermost set of statements in
    an interpretation unit.  This is in addition to using _{ }_
    to enclose statements that constitute a "suite" that is part
    of an "if" or "def" or "class" statement.

The intent behind adding this feature would be as follows:

1)  Simplifies the task of dealing with Python code 
    in non-standard contexts, e.g., when embedded in a
    free-form language like HTML.

2)  Could help make Python more popular by providing
    an alternative for those many (arguably misguided)
    souls whose main pet peeve about Python is the
    grouping-via-indentation paradigm.

3)  May make code generation marginally simpler.

############################################################

Here are some usage examples.

Legal but pointless, with no new functionality:

    if good: _{
        print "Spam!"
        print "Spam!"
    }_
    print "Yum."

Legal but with pointlessly irregular indentation:

    if good:
    _{
        print "Spam!"
            print "Spam!"
    }_
    print "Yum."

Previously impossible, a one-line version:

    if good: _{ print "Spam!"; print "Spam!" }_  print "Yum."
    
Prettier looking Python embedded in Python (indentation within string
would previously have been illegal):

    statements = '''if good: _{
                print "Spam!"
                print "Spam!"
            }_
            print "Yum." '''
    exec(statements)
            
The last two examples are relevant to embedding in HTML as well
(using a fictitious inclusion syntax):

    Tasty? <!--#pycode if good: _{ print "Spam!"; print "Spam!" }_  print "Yum." -->

    Tasty? <!--#pycode if good: _{ 
                           print "Spam!"
                           print "Spam!"
                       }_
                       print "Yum." -->

Or, using an even more speculative syntax, something which would be
horrendously awkward without this new feature:

    Tasty? 
    <!--#pycode if good: _{ --> 
    Spam! Spam!
    <!--#pycode }_ -->
    Yum.

Up until now, I have not used the subfeature that would
allow _{ }_ to surround the outermost level of code. Taking this 
into account, formatting improvements cited above become possible 
even if there is no "if" or the like involved, e.g.:

    statements = ''' _{ print "Spam!"
                        print "Spam!" }_ '''
    exec(statements)

Here is a code generation example.  Consider the following
rather goofy code:

    n = 0
    print "Computing ceiling(log_2(x))"
    if x <= 1:
        print "Got it!"
        print `n`
    else:
        n = n + 1
        x = x/2
        if x <= 1:
            print "Got it!"
            print `n`
        else:
            n = n + 1
            x = x/2
            if x <= 1:
                print "Got it!"
                print `n`
            else:
                n = n + 1
                x = x/2
                if x <= 1:
                    print "Got it!"
                    print `n`
                else:
                    n = n + 1
                    x = x/2
                    print "I give up."

This code contains four repeated blocks which are identical
except for indentation level.  If we were to try to generate
this code verbatim, we would need to carefully adjust the
indentation level each time we inserted the block.  But with
the _{ }_ feature we could do the following:

    start = '''_{ n = 0
                  print "Computing ceiling(log_2(x))"
               '''
    atom = '''if x <= 1: _{
                  print "Got it!"
                  print `n` }_
              else: _{
                  n = n + 1
                  x = x/2
                  '''
    end = '''print "I give up." }_ }_ }_ }_ }_'''
    code = start + atom + atom + atom + end
    exec(code)

In this version, the indentation in the generated code is
sloppy and meaningless -- but it does the right thing
without as much effort as would have been required previously.

############################################################

A few comments on the choice of symbols used to implement
this new functionality...

Selection criteria would sensibly include:

1)  Syntactically unambiguous; need to choose something that
    currently constitutes illegal syntax.

2)  Should suggest grouping to folks who are used to C, Perl, etc.

3)  Should be reasonably aesthetic.

4)  Not excessively difficult to type.

Here are a few options, and associated comments:

     {  }    Not available -- in use for dictionaries.

    \{ \}    Gets ugly if code needs to be enclosed in a string
             (in Python or another language)

    (@ @)    Could work, but arguably graceless and unfamiliar

    -{ }-    Likely to be confusing even if technically unambiguous.

    {_ _}    Syntactically confusing, as "_" is a legal identifier name,
	     and an identifier could be the first or last thing in a
             dictionary expression.

    .{ }.    Visually as close as possible to { } and perhaps easier
             to type than some alternatives? Perhaps viable?
             (Could be confusing to name these tokens in error messages
             or textual discussion?)

    _{ }_    Probably viable?

############################################################

I haven't looked at the Python parser, but naively, this sort
of "enhancement" would seem to be relatively easy.  If there were
official blessing for the concept, I'd be willing to look into
doing the necessary work.

Robert Wentworth
rhww at erols.com




More information about the Python-list mailing list