Hacker News new | past | comments | ask | show | jobs | submit login
Python indentation: very nice explanation for the curious or skeptical (secnetix.de)
23 points by benhoyt on Sept 21, 2007 | hide | past | favorite | 27 comments



I never understood why some people are so adverse to python's indentation rules. But maybe that's because I was too young when I was introduced to python.


I think it's sort of presumed by the article, but there are a few things people worry about when they hear "significant whitespace"

-They remember pain of trying to find an error in a code, data, or config file that had significant whitespace. Consider the 'tab-delimited' spreadsheet format, for example. If you manually edit a tab-delimited list of numbers, and accidentally leave a space somewhere, the number might be read as a string.

-They've spent a lot of time dealing with HTML rendering, where whitespace gets mangled and cannot be trusted.

-They're afraid they won't be able to make their code readable.

-They're afraid that the whitespace rules will be complicated, requiring them to think constantly while adjusting to this newfangled way to delimit blocks.


-They've used Fortran 77 which requires 6 whitespaces before a normal statement, 5 + any character for line continuations, and which truncates silently (as in, without warning) any line longer than 72 characters.


Philosophically speaking, we live in a world where the number of spaces doesn't matter anymore (although it did matter in those pre-historic pre-Internet times). Spaces may be lost in HTML, in word processors or in an editor that accidentally wasn't tuned for Python. However neat and readable it is, just try to show your code, for example, on some minimalist web forum like this one. It's too bad you can't, isn't it?

It is also true that Python has survived already, but I doubt this concept would leak to new languages.

Upd: In other words, it's electronic typography that made the space character irrelevant.


Source code is still nearly universally viewed in non-proportional fonts.


- They don't like the idea that cut & paste of code snippets will break the code due to significant indentations. Counter-arguments include (1) you should probably beautify the code anyway and check for issues while doing it, (2) code snippets should be in modules with smallish functions.


That's actually a valid issue, and not really addressed by the article. Cutting and pasting does occasionally require some extra care.


My guess is that most people that don't like the indentation have never used it. It is notably more readable when looking at someone else's code, and makes wonderful use of whitespace.

Now if only there were some formatting standard to get rid of some of that parens in Lisp without loss of power.


Funny thing... the other day I tried converting some Lisp to Python as a demonstration, and discovered that the number of parens you get to remove depends largely on the programming style you're using. Mostly, they just get shifted around or replaced with brackets (or braces), and you have to add a lot of commas.

If you scan over http://norvig.com/python-lisp.html, you'll see a lot of opportunities to remove parens; but in fact many of those are not semantically identical.

In python, a block does not return a value.

    if a:f(x);else:g(y)
If you wanted it to return a value, you'd have to rewrite 'if' as a function and say something like:

     myif(a, [(f, x)], [(g, y)])
If you wanted to evolve python towards Lisp without having to add parens, I'd make it so indented blocks are actually expressions and automatically return a value to the defining block.

(Of course, the normal python way is to use "return" statements or side-effects, rather than writing an ad-hoc version of the lisp 'if')


Python 2.5 now lets you do:

 x = f(x) if a else g(y)
f() and g() aren't evaluated till they're needed.


That syntax looks like it's intended to communicate that f(x) is the normal result, and g(y) is exceptional. I wouldn't want to use it unless that's what I intended to communicate. It also looks like you would need to put parens around the "if" expression if you were to use it within a more complex expression, e.g

 2 + (f(x) if a else g(y)) + 3


And before Python 2.5, people usually used this idiom:

    x = a and f(x) or g(y)
If you know the idiom, I think this is more readable (conditional is on the left), though it has the drawback of using completely nonsensical keywords.


Another drawback I just noticed is that if f(x) returns false, you'll get g(y) even if a is true.


I don't think the keywords are nonsensical.

   (or (and a (f x))
       (g y))


Thanks, I didn't know that. That makes parenthesis optional unless you need to break precedence rules.


There are plenty of ways to represent a Lisp parse tree without using parens. The only thing is, by the time you know Lisp well enough to implement one, you've begun to like the parens.


Totally true. Plus you can have editors "present" the lisp tree however you like to see it (ie "whitespace" or parens !). Although I practice, I don't know if anyone really writes code without the parens (for the reason you say).


I use it every day and still don't like it - I miss Lisp.


I had the chance to meet up with Guido at one of the Linux conferences in 1999, back before Python was all that popular. Very nice guy, but something I said then still stands true, in my opinion:

The white space issue doesn't really matter. Except for a few specialized areas like template creation, where Python is just not a natural fit.

That's one of the things I like about Rails - Ruby may not be the absolute perfect language for scripting web templates (maybe Tcl is?:-) but it's good enough, and it's useful without some of the weird hacks that the Python guys use to do templates.


I'm sure you know that the idea of using code in templates is controversial anyway. But I do like it, and Mako, imo, solves the issue with Python very well.

    % for row in rows:
        * Here is a row: ${row}
    % endfor
http://www.makotemplates.org/

That's kind of 'hackish', but not bad at all if you ask me.

Compared to an ERB snippet it is about the same (though you'd probably use each and a block here in Ruby.

   <% for row in row %>
      * <%= row %>
   <% end %>


<snipped code example, what kind of mark-up is valid here anyway?>

Anyway, I don't like the notation for programming, but I love it for HTML: http://haml.hamptoncatlin.com/


mt


Hey I said I was sorry what is with the repeat downmoding? Karma police, jeez...


?


mt = me too (to me)


Ah, thanks for enlightening me.


thanks for the heads up, sorry for the mistake.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: