Indentation voodoo in Python
Python is my favourite language this month1. The fact it requires indentation helps newbie programmers, but offends many experienced programmers’ sensibilities. Today I found a good article on some indentation myths, including tabs-vs-spaces, compiler-side details, and when whitespace doesn’t matter.
- Last month’s was Javascript. Take that performance-lovers! [↩]
Feb 25 2008
2:20 pm
Pedantic quote:
> To be exact, you cannot safely mix tabs and spaces in C either …
Not a helpful argument, as you can safely mix tabs/spaces in C/C++. It may read like shit (or it may not), but it will compile just fine. Not to say that it’s a good idea to mix them, but many editors/IDEs make it easy too.
Python’s approach, however bad this guy’s argument, is perfectly sane. And Python code is almost always damned readable too.
Feb 25 2008
3:08 pm
“/* Warning: bogus C code! */
if (some condition)
if (another condition)
do_something(fancy);
else
this_sucks(badluck);
Either the indentation is wrong, or the program is buggy, because an “else” always applies to the nearest “if”, unless you use braces. This is an essential problem in C and C++. Of course, you could resort to always use braces, no matter what, but that’s tiresome and bloats the source code, and it doesn’t prevent you from accidentally obfuscating the code by still having the wrong indentation.”
Yes, the program is either indented wrong, or buggy, but braces doesn’t bloat if you did:
if (cond == a){
if (cond == b) do(this);
else die;
}
It’s not the best style, but boohoo, no bloat from braces. Besides, as a programmer, you are _supposed_ to know the logic, and program accordingly.
“you cannot mix tab and spaces…”
Precisely! and I was handed with a python source code that HAD indentation that has mixed tabs and spaces. If you use a console based text-editor, good luck getting it to tell you whether it’s a tab or space by default.
Turns out that just because the lexer can generate a dedent by itself, it doesn’t mean you can write a handy app that would clean up mixed-indentation due to a clearly marked ending of a block. Python, by using indent for blocks, makes it easy to parse, given clean data, but much harder to deal with.
If people do run into style problems in C, they just “man indent”, and despite a rather horrific mixing of indent characters (tabs and spaces), it will clean it up.
By forcing the indent, it fixes a minor human program (which should be caught during testing / using a debugger), with a problem that is much harder to deal with. Tabs and Spaces are not normally rendered; although a decent text editor can render Tabs separately, people who are thoroughly confused by code could pastebin it and the problem may not show up (depending on how many spaces are used).
And this has nothing to do with how schizophrenic python is when you’re trying to access list elements that may be other lists. Apparently, many things are copy-by-value, but some, because of performance reasons, are copy-by-reference. But which policy is enforced is not immediately clear.
I can assure you that I have to deal with Python enough times to hate it. If the point of using Python is to make it easy for programmers, Ruby (the language, not RoR) is IMO better than Python for that anyways, even if its own problems taken into account. Python is inconsistent: It tries to be fast, but not fast; It tries to be a scripting language, but doesn’t have some of the basic functions (try reversing a string in Python sometime); It hides pointers, but it has pointer related policy (see copy-by-reference rant above). Their OOP sucks almost at the same level as C++ OOP suck syntatically (how many times do I have to write “self” in the function signature?).
Feb 25 2008
4:52 pm
@mx: Python compiles fine if you mix tabs and spaces, assuming your tabstop is 4 (if I recall.) It works in theory, but is playing with fire
@Calyth: Why doesn’t find/replace “\t” with ” ” work for fixing Python that has tabs and spaces? To avoid this problem, python has a flag -t to raise a warning whenever tabs and spaces are mixed. I think they should have it on by default.
Feb 26 2008
10:24 am
Yes, Python can compile fine in the mixed case (though unwise), but that’s not the point. The linked article’s arguments are piss-poor, annoying if you know better. Weak logic will not win over people who can think.
Really, the argument should be that whitespace delimitation works a lot better than intuition suggests, and that it causes fewer problems in reality than the wankers whine about. But that will always be true about any language. If you hear complaints about the little things, it’s likely the person has missed the real knowledge.
What does Python teach us? That pristine looking code really makes a difference, and that you can get reasonable performance in a dynamic language. Is Python the best language? (It would be absurd to answer that either way. It’s a good tool, isn’t that enough?)
Feb 26 2008
1:33 pm
@Calyth:
These are always the examples that you drag out. You can’t reverse a String in Python- well, it’s a big omission but it’s not the end of the world. Do you have lots of other examples?
Python is a general purpose language. It has a lot of useful features, and it doesn’t specialize too deeply in any one domain- like, say, PHP in the web domain or Perl in the.. Perl domain. It has it’s quirks- like *any* language- but it’s not onerous to use.
If you condemn any language you encounter for not being perfect, you’re never going to be a happy coder.
Feb 27 2008
12:06 am
Hi Calyth, Curtis.
Here is one way to reverse a string in Python:
>>> a = ‘abcde’
>>> a[::-1]
‘edcba’
>>>
Calyth, Pythons design is influenced by the observation that code is read much more than it is written, and that code maintenance often takes more effort than the initial code release.
If you don’t ‘buy into’ the above then you are likely to be dismissive of a lot of the design decisions made in Python.
Your statement “as a programmer, you are _supposed_ to know the logic” makes me think that you are not one to think of the lifetime costs of software but are merely concerned with the short term. As a programmer you are expected to write clear and concise logic that will be easy for you to read in six months time or for others to maintain. Python tries to make that easy.
On your defence of the C style else clause and indentation, I would reject a C program in which the indentation did not match the logic – what defence could a programmer give? The fact that it is acceptable to the compiler is not a good reason. If a programmer uses indent to indent his code before review is up to the programmer, but I would think that a competent programmer would take pains to use logical indentation schemes without needing indent
- Paddy.
Feb 27 2008
11:19 am
Thanks for the ultra-concise string reversal example Paddy! The more I code Python, the more of those little “Pythonic” ways of doing things I learn, and they make the whole thing a lot more worthwhile. If you just write C code using Python, it’s not as useful.
Oct 4 2008
10:48 pm
I have long thought Python offered some compelling features, but I absolutely hate the indentation “feature”. I have never read a compelling argument for it, yet most of the arguments against it seem valid. When I say that I’ve never read a compelling argument, I mean in regards to indentation as a language feature. Every argument is about the readability of the code. Rather than saddling the language and its users with that requirement, the original author should have just written an editor that *forced* his style of indentation. Anyone who liked it could have used his editor. I always use the editor to indent my code. It’s fast, convenient, allows easy cut and paste, etc. I do sometimes open files where the code is not correctly indented, and it does make it difficult to follow, so I enter two keystrokes and all is fixed (in Vim). I much prefer this way to make the code readable.
Oct 5 2008
12:03 am
I think the two main aspects of it that can’t be simulated with an IDE is the readability/conciseness are not having to read or type punctuation to delimit blocks, and everybody being on the same indenting style. For me indenting style is one of those “I don’t care, as long as it’s consistent” things.
One solution I’ve thought of before is a language that stores block information in an intermediate form, and an IDE that reads and writes that format but allows you to specify what indentation format or punctuation you’d like to see. The biggest problem with this would be the line numbers not matching up without some weird workarounds.