2006-04-29
Bitten by Python whitespace rules
Earlier this week I made a mistake involving the Python whitespace rules, for the first time in the 2 years I have been programming in Python.
The code I wrote was something like this:
for ...: for ...: foo() bar()
The mistake was that the bar()
call was intended to be
in the outer loop, not the inner loop, and so should have been one
indentation level higher. The resulting bug took a while to track
down.
As usual, I wrote this code in emacs, in the python mode. Like
other programming language modes in emacs, the python mode does automatic
indenting. It knows that the colon at the end of a for
line (and other lines introducing compound statements) means that the
indent level should be increased for the following line. It also
knows that some statements, such as break
,
return
, etc., must end a compound statement, and so when
it sees one of these statements, it reduces the indent level for the
following line. But in cases like the code above, there is no way for
it to know when a compound statement finishes, except when you hit
backspace to tell it to go up an indent level.
This python indentation support is a convenient aid. But as I discovered,
it does leave room for error. I suspect that when I was originally typing
the code, I did put the bar()
call at the right level. But
later I came back to make some changes in the surrounding code, and I
probably introduced the error then.
I don't recall ever making a similar mistake mistake in C and C-like languages (certainly not in the 13 years that emacs has been my usual editor). The language structure of those languages allows automatic indentation to be 100% accurate. And because you can trust the automatic indentation, a natural error-correcting feedback loop arises: You type code with the desired structure, the editor indents accordingly, and the indentation makes it very clear if the structure is really as expected.
(It is theoretically possible for bugs to arise due to indentation mistakes such as:
if (...) foo(); bar();
Or:
if (...); foo();
But in my experience, with an editor that does automatic indentation, these errors never happen.)
I certainly don't intend to stop using python because of this. But the omission of an explicit terminator for compound statements seems like a mistake. If a tiny bit more typing and explicit structure allow me to rely on the editor to indent correctly, that seems like a good trade.
04 May 2006 22:27
Comment from Lalanda
Nope. Not a word understood by me.