Why whitespace denotation of blocks doesn't work.

Ted Drain ted.drain at jpl.nasa.gov
Tue Jun 20 11:33:21 EDT 2000


The one thing that I really hate about the white space blocking is when
you have to reformat because of a code change.  This is something that has
hit me quite a few times.  

I'll write some code, and as I start debugging/prototyping/etc etc, I find
that I have to enclose some existing code in a control block (if,etc). 
With C/C++, I just put the code in brace, tell xemacs to re-indent the
block, and everything's good.  With Python, I have to hand edit everything
because the editor can't figure out how to do the indentation after I've
inserted the control block.  Once you get a few nested indentation blocks,
this gets very confusing and leads to bugs that are hard to find (code
that did work suddenly doesn't).

I love Python, but I'd really prefer to have open/close brackets for the blocks.

Ted


In article <394ac7ea.609024015 at nntp.interaccess.com>,
olczyk at interaccess.com wrote:

>After using Python for a while I've come to the conclusion that
>using whitespaces to determine the begining and ending of blocks
>is bad for three reasons.
>
>Before I list those three reasons let me make two points. People say
>that the indentation requirements don't matter because you generally
>indent the same way. That may be true, but do you think it is a good
>idea to make conventions requirements ( remember that conventions
>start flame wars )? The second is that modern editors with good
>indentation rules ( like emac's python mode ) make indentation based
>coding easy. The thing is that by doing this you are abrogating
>control flow to the editor. When it was the editor indenting code
>which was well defined then there was no problem. By having
>the code depend on indentation, and the editor do the indentation
>for you, you give the editor responsiblity in how the code will flow.
>
>Now on to my points.
>1) The first is rather stylistic and may not appeal to most, but I
>have often found it useful. When debugging code I often put in
>code to help me figure out whats happening. I also avoid indenting
>such code so that it easy to remember where it is later when I want to
>take it out. An example ( assuming I use begin and end to denote
>blocks ):
>
>def Average():
>begin 
>      sum=0
>print "number of numbers=",len(numbers) #illegal
>i=0
>      for n in  numbers:
>      begin
>print "n=", n #illegal
>            sum=sum+n
>print "sum=",sum #illegal
> i=i+1                     #illegal
>if sum>MaxNumber*I:#illegal
>begin                     #illegal    
>  print "sum is too large"#illegal
>end                        #illegal
>     end
>     if len(numbers)!=0:
>     begin
>        return sum/len(numbers) 
>     end
>     return 0
>end
>
>You can immediately see code that you used for debugging and remove
>it. However right now writing code that way makes it illegal.
>
>2) You can easily insert a tab introducing a bug.  Consider the
>following code ( similar to a bug I recently fixed ):
>
>def FindInvoice(idnum): 
>      for invoice in invoices:
>            if invoice.id=idnum:
>              return invoice
>            return None # should be indented one less tab.
>
>....
>
>for lines in file.readline():
>     idnum=lines[:6]
>     invoice=FindInvoice(idnum)
>     if not invoice:
>              invoice=InvoiceClass(idnum)
>         invoices.append(invoice)
>....
>Initially the line in error was indented correctly, but someplace
>along the line the extra tab was introduced. A lot of effort then had
>to go in to finding this bug. With begin...end or braces this is less
>likely to happen.
>
>3) Finally. Python is a language where it is almost easy to write
>extensible programs. To illistrate what I mean consider this example
>of a python program I recently wrote:
>There is a C++ project which involves many project files and workspace
>files ( the project files are roughly equivalent to makefiles, the
>workspace files primarily are used to couple projects and define
>dependencies ). Version 1 simply read all the project files and 
>generated a call to compile each one with all different configuartions
>(debug , release, alpha, beta etc..) . Since this built everything
>even if it was already built, and since this had to be run several
>times ( sometimes compiles would fail because a project that the
>present project was dependent on wasn't compiled ), I made version
>two. Version 2 read the workspace file and organised the projects
>into workspaces. Version 3 passed the string to a second script so
>that the second script could figure out if this was something that
>should be built ( for example whether a standard Win32 build or a
>WinCE build should be done ). Version 4 tracked dependencies more
>carefully ( it did a topological sort and orgainsied the build
>according to it ). Since the core stuff should be built first, I had
>to find out a way to figure out which was core. I used a definition of
>the core stuff is the stuff with the longest chain of dependencies.
>That was Version 5.
>
>As you can see I started with a simple program and made it more
>complex as I went on.  That's what I mean by extendible. Python is
>almost good at it. Almost. But that damned code indentation dependence
>backs its ugly head. In the process of extending code, I have to move
>blocks of code around. Sometimes put it in a loop, sometimes add an if
>clause to the top. Sometimes extract code into a subroutine. That
>means that I have to reindent the block. So as I reindent I have to
>try to remember how the indenting went. Something I stink at. 
>Emacs also doesn't reindent correctly. So I have to go through the
>code, and try to figure out how it works. This distracts from my 
>rewrite ( this also applies to refactorings ). I would rather think
>about how new code is supposed to work rather than how old code
>is supposed to work.
>
>Anyway I hope this causes TPTB to think about how blocks should be
>handled in Pyhton 3000.

-- 
Ted Drain   Jet Propulsion Laboratory    Ted.Drain at jpl.nasa.gov



More information about the Python-list mailing list