Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I know that I use python because of how easy it is to code. I can focus wholly, totally on the logic of my code without ever worrying about if I misplaced a semi-colon or left out some weird punctuation.

Python frees me to code and not worry about things that get in the way of coding. That's why it's eating other language's lunches, the freedom is almost intoxicating.



It's ironic that you say that, given that if you don't get the whitespace correct, you'll have a syntax error. That's one of the big reason Python rubs me the wrong way: white space is semantic.


Getting the indentation right should be the least of your worries if you have a good editor (and don't do something like mix spaces and tabs, which I think everyone is in general agreement with across all languages).

When was the last time that you manually typed out 4 (or 2, or 8, etc) spaces to indent a line of code vs. just hitting tab and letting the editor handle inserting those spaces (or the editor automatically indenting when you hit enter on the previous line)?

As an aside, all of the people that I've met in person that get red in the face over the idea of white space being semantic are the sort of people that write code like this:

  sub function1 { return map { $_[2]->do_something($_) } @{shift->(@_)[0]} }
I'm sorry, but I can't get worked up about not being able to write code like that.

Note: the above code is a reasonable approximation of actual code I encountered by an actual person that would get visibly upset about Python's semantic white space.

P.S. The two '$_'s in the map block actually refer to two different variables, and this is one of the reasons I remember that bit of code. It makes no sense to mix usage like that because it becomes confusing.


> Getting the indentation right should be the least of your worries if you have a good editor

I never understood that. The whole problem for me is that the indentation being the only thing denoting blocks the editor can't know for sure how things should be indented, since it's not simply cosmetic.

I haven't written a whole lot of Python but how do you even refactor python code? In C I can just copy paste a block of code from anywhere to anywhere (no matter the coding style in the source and destination file and the level of indentation) and then hit C-M-\ in emacs and have it reindent everything properly. In Python you have to make sure that everything is at the level of indentation it belongs to. If you refactor huge chunks of code it's easy to miss one fubar tab and have code subtly broken and introduce weird regressions.

Also, regarding the OP and "focusing only on your code", I think we all feel that way about the language we're the most familiar with. For me that's C and I can't say I've had a "missing semicolon" compilation error in months of heavy use. Once you're used to the syntax it becomes automatic.


> If refactor huge chunks of code it's easy to miss one fubar tab and have code subtly broken and introduce weird regressions.

That is just one of the many issues that can come up when refactoring large sections of code, and is one reason that people write tests. For people to point it out as the entire reason that they can't use Python seems to be making a mountain out of a mole hill.

For example, I don't like that I can't use "if $?" in Ruby and I need to explicitly write "if $? != 0", but I don't go around bashing Ruby on that basis. For some reason people feel that need to do that with Python though. I don't really understand it.


I'm not making a mountain out of a molehill but I don't understand why the python crowd refuse to acknowledge that having significant whitespace does cause some issues and the benefits are completely subjective.

Sure unit tests will catch the error but in most other languages the error wouldn't have been introduced in the first place.

I think in the end the problem is that I've been writing in C-style languages a long enough time that I don't even "see" the brackets and semicolon anymore. As such I don't find any advantage to the python way. To me it's sacrificing convenience for aesthetics.


> I'm not making a mountain out of a molehill

I'm not saying that you are, just that these arguments/discussions generally are making a mountain out of a mole hill when people go on at length about how much they hate Python (though they've never used it) because of its semantic white space.

> I don't understand why the python crowd refuse to acknowledge that having significant whitespace does cause some issues and the benefits are completely subjective.

All language decisions are trade-offs that come with some downside. I wrote Perl for 4 years, and I would still get tripped up by its break/continue syntax (next/last) on occasion since I learned to program in C/C++.

I currently am working heavily in both JavaScript and Python, and I don't have any indentation issues swapping between the two languages (probably the issue I come across the most of switching between under_scores and camelCase for names). I could probably count on one hand the number of times I've had an indentation error in Python.

> Sure unit tests will catch the error but in most other languages the error wouldn't have been introduced in the first place.

But this is essentially the same argument for static-typing over dynamic-typing, but that doesn't get the same amount of flack as white space in Python.


I'm not making a mountain out of a molehill but I don't understand why the python crowd refuse to acknowledge that having significant whitespace does cause some issues and the benefits are completely subjective.

Here's what you wrote:

That's one of the big reason Python rubs me the wrong way: white space is semantic.

Defending python against a vague accusation like that is most certainly not "refusing to acknowledge that having significant whitespace does cause some issues"

that said, the benefits are not completely subjective. Whether you prefer the benefits or not is somewhat subjective, but the benefits can be clearly described. Specifically: you don't need braces or begin-end tags for code blocks. Correct code will always be indented based on the same concrete rules. Code can be moved from one block to another just by changing the indentation. Those are objective, not subjective traits.


Indeed that is a problem when you are copy-pasting huge blocks of code. In deeply nested code it can be difficult to determine whether the nesting should be say 28 or 32 spaces. In practice, most people shy away from writing such code because to many levels of nesting is hard to follow. People also prefer to write atomic 5-15 line functions in which keeping track of the nesting levels is trivial.

Many C# and Java-heads complain that Python lacks support for auto-completion. Which is true, the language makes it so you can't have as sophisticated auto-completion as is available for the aforementioned languages in Visual Studio and Eclipse. But it's not so bad because Python developers are trained to prefer shorter names instead of OverlyLongJavaNames such as "getattrs" instead of "GetAllAttributes".

Btw have you noticed that on this site, the only thing that indicates how the comment threads are structured is how the individual comments are indented?


Many C# and Java-heads complain that Python lacks support for auto-completion. Which is true

Isn't that an IDE issue and not a language issue? I have no problem with the auto-completion in ipython for instance, though even ipython notebook is only useful for writing simple amounts of code. PyDev though works well too for larger projects albeit a bit sluggishly.


No, Pythons dynamicness means it is in general impossible to find all available completions:

    m = type('', (), {})()
    setattr(m, 'foo', 123)
    m.f<tab>
Without actually running the code (which is unsafe), no editor could at that point figure out what the completion should be.


If you're an Emacs user, have you tried Esc-/ (or M-/) for autocompletion? Note that this works in any mode, not just Python mode.


I think all the modes for python in Emacs implement dedent and indent functions which behave nicely. I hacked one of them to leave selection active after the operation and now - it's still more than one command - I do C-y for paste, C-x C-x to select what was pasted and C-M-> or C-M-< to adjust indent.

On the other hand it's almost impossible to make a mistake with indentation with python-mode (and similar, I'm using all-in-one-plus-your-cat elpy package) when writing code - the enter key indents automatically (instead of having to press tab additionally) and it indents one level more after statements which need it. And backspace removes one level of indentation. I can't remember if I ever had a problem with indentation in Python in Emacs; although I know I had some with CoffeeScript.

So in short - it's all an editor support issue and some relatively trivial rules give you an experience as streamlined as in langs without significant whitespace.

Also, I'm a lisper so - paredit. Knowing about it and using it makes you realize how broken every other syntax is and how hard it is to edit ;)

(Replying just because of Emacs, the rest is uninteresting anyway - in my experience once you cross the border of 5-8 known langs you can easily accommodate to any syntax)


Lazy me never bothered to use proper indent/dedent function, since TAB will cycle through indentation levels.. but I'm happy I read your comment since cycling isn't efficient.

ps: although it seems, vanilla python mode binds them to 'C-c >' and 'C-c <'

Just like monads, sexps have that curse when you get how paredit or alikes work, you just can't explain how awesome it is to non lispers.


Any good editor should be able to figure out the indents when pasting. I'm not an emacs user, but I'd be surprised if there wasn't a plugin with smart python pasting.


My point is that it's not always possible for the editor to know what the indentation is supposed to be because it can't know what the code is supposed to do.

Suppose you have code like this:

    [...]
        if a:
            b
        c
    [...]
And then you paste some snippet you got from somewhere else between b and c:

    [...]
        if a:
            b
    pasted_snippet
        c
    [...]
The editor cannot know how to indent that properly. It's not a problem in most other languages.

Again, I'm not trying to say it's a deal breaker and Python is useless as a result, I just think it's a small mistake in the design of the language. It's like non-breaking switch/case in C, it doesn't make the language unusable but it is an annoyance.


In that example, a good editor should indent pasted_snippet at least to the first indent level. If you wanted it to be part of the if statement then you could just select the pasted block (both Vim and Emacs should be able to do this with a single command) and indent it by one more.

Python's use of semantic white space is more a function of it's inheritance than anything. It's based off of ABC[1].

[1] http://en.wikipedia.org/wiki/ABC_%28programming_language%29


The editor cannot know how to indent that properly. It's not a problem in most other languages.

It will have a pretty good idea. If you paste the snippet, then hit 'tab', odds are high that a good editor (I use emacs python-mode) will Do The Right Thing on the first try, although sometimes you'll have to hit tab again or backspace a couple of times to get the right indent level.

Occasionally I need to use a keyboard macro to fix the indent after a paste, but this is very easy to do and doesn't happen to often, really. I'm sure by now with python's popularity there are more advanced indentation management tools but I still just use emacs keyboard macros.

It's a very small price to pay for the huge benefits of semantic whitespace.

Generally the worst case scenario for copy/paste is that I'm using emacs in a terminal window and I forget to switch to fundamental-mode before pasting. Because the terminal is handling the paste, not emacs, python-mode treats it all as if it had been entered one line at a time and auto-indents everything after a colon, then pasting in lines that already have indentation and the result is a complete mess. (but then I just undo it all and re-paste it the right way) GUI emacs doesn't have this problem.

The worst case scenario I can think of for semantic whitespace (outside of copy/paste) is accidentally changing indent level of a piece of code without realizing it and a syntax error doesn't result, meaning there's now a logic flaw in your program you don't know about. Python is more susceptible to that than sort of regression error than most languages. That said, usually that sort of mistake WILL cause a syntax error and be easily fixed.


> The two '$_'s in the map block actually refer to two different variables

Yeah, but that's Perl 101. Grabbing an element of array @a is $a[0], which is wholly different than plain $a.

That's not really a style thing, it's a Perl thing, for better or for worse.

> I'm sorry, but I can't get worked up about not being able to write code like that.

Why? It looks more or less reasonable to me. Most of the weirdness there is a factor of Perl's unfortunate lack of named function parameters. @_ and $_[] are simply a fact of life when writing Perl.

It's even a single expression which means you could probably write a similar one liner in python (since their wimpy "lambda" only does expressions)


> Yeah, but that's Perl 101. Grabbing an element of array @a is $a[0], which is wholly different than plain $a. > > That's not really a style thing, it's a Perl thing, for better or for worse.

That code confused me after working in nothing but Perl for 4 years. It was confusing because I wasn't used to people having an array (@_ in this case) and a scalar ($_) named the same thing, and used in close approximation. The issue could have been avoided by (e.g.) setting $_[2] to a variable first, and would have made the code more readable. It's not "Perl 101" to write code that is intentionally obtuse.

> Why? It looks more or less reasonable to me. Most of the weirdness there is a factor of Perl's unfortunate lack of named function parameters. @_ and $_[] are simply a fact of life when writing Perl.

That code could be written in a way that was easier to read and maintain. For example, what is 'shift' intended to be? The only information we have is that it's supposed to be the first argument to function1.

Edit:

> Most of the weirdness there is a factor of Perl's unfortunate lack of named function parameters

This was in a code base with a source filter to provide function parameters. That could have been written as:

  sub function1($arg1, $arg2, $arg3) {
  }
in that code base, but the developer in question chose not to.

Even without said source filter, you can still name the function parameters:

  sub function1 {
    my ($arg1, $arg2, $arg3) = @_;
  }


> For example, what is 'shift' intended to be?

"shift->method()" a very standard Perl idiom for OO code. If you presume the code was called via a blessed reference, then "shift" == "this".


I don't think I've ever come across Perl code that uses "shift->method()" to access "this" but once. Maybe I just haven't look at enough code on CPAN, or maybe I just remember that instance because it was an entire file that was meant to be production code that could have been an entry into a Perl golf competition.

I understand that in Perl OO code, the first argument is 'this', but most code I've come across takes the time to actually name variables because the aim isn't write-once, read-never.


You are being kind or your coworker isn't that bad - in your example the whitespace is consistent. My experience is that the whitespace is totally arbitrary: totally inconsistently placed 0 - n spaces with random indentation levels.

Sloppily formatted code is Edward Bear code. All the bumping makes it hard to think about how it works (or, more often, why it doesn't work).

"Here is Edward Bear, coming downstairs now, bump, bump, bump, on the back of his head, behind Christopher Robin. It is, as far as he knows, the only way of coming downstairs, but sometimes he feels that there really is another way, if only he could stop bumping for a moment and think of it." - http://www.gurteen.com/gurteen/gurteen.nsf/id/L001362/


> My experience is that the whitespace is totally arbitrary: totally inconsistently placed 0 - n spaces with random indentation levels.

This is usually due to:

1) Lack of a consistent style guide.

2) Lack of style guide enforcement.

3) A language where white space doesn't matter.

If you think about this critically though, these random indentation changes would either break all of the code (e.g. it wouldn't run, or would run but not work correctly) or it would make code maintenance a nightmare. Yet there are plenty of Python shops out there, and we don't hear horror stories of Python white space maintenance nightmares. Either the Python community is doing a good job of hiding these issues, or they really aren't issues in practice.

Of the people I've talked to in-person about Python semantic white-space, the common threads are either:

1) It's different than what I'm used to.

2) It's cramping my style. My code is art, and restricting how I can structure my code is an affront to my very being.


I guess I'm in a third camp:

3) Python's semantic whitespace is so wonderful I'm baffled that most other programming languages don't have it. It's like they're coding with one eye shut: why not do this wonderful thing that makes everything easier?


I meant to say of the people that were upset by Python's semantic whitespace, those were the two general reasons why.


2) It's cramping my style. My code is art, and restricting how I can structure my code is an affront to my very being.

To be fair, there are quite a few common cases where Python's syntax is rather inelegant. The need to break out if-then statements into multiple lines, the need for explicit 'return' statements which also have to go on their own line. These things are only indirectly related to whitespace but do sometimes put a lower bound on expressiveness.


> To be fair, there are quite a few common cases where Python's syntax is rather inelegant

Now we're stepping out of the realm of "semantic white space" though. The people I've known to get (literally) red in the face over Python haven't actually used the language and can't do much more than regurgitate stuff like, "but white space!"

> The need to break out if-then statements into multiple lines, the need for explicit 'return' statements which also have to go on their own line.

Unless I'm missing something those are poor examples of the limits of semantic white space:

  % python
  >>> def function():
  ...   if True: return False
  ...
  >>> function()
  False
  >>> def function():
  ...   if False: return True
  ...   else: return False
  ...
  >>> function()
  False
Sure you can't do stuff like:

  >>> def function():
  ...   True
  ...
  >>> function()
  >>>
(That returned `None`)

But I don't see how requiring a return statement, or disallowing code like:

  if var1 = function():
    do_something()
is a crime against humanity.


Actually after a quick search I realized my problem was ignorance. I did not know about PEP 308 (conditional expressions) which is a workaround for the issue I described.

And yes technically it's a statement/expression issue not a whitespace issue, though they're indirectly related.


The problem is larger multi-people projects. You need very strict editor/whitespace discipline, and you don't want to commit some sort of re-indent which touches every line of a file. That and the refactor issue is the main issue people have with the whitespace thing.


Which is why we have things like linters, pep8, and pre-commit hooks. :P


It's easy enough if you have only one editor on one computer that you use with only one language. If you mix and match a half-dozen editors on multiple computers running different OSes coding in different languages, then it gets messier. Especially when all of the editors have different ways to set preferences for whether to use spaces or tabs, how much space per tab/indent, and whether those preferences are for this session, this language, or permanent.

What, am I the only one that does that?


One of my pet peeves with Emacs is the way that it indents things (at least by default), so you won't find me using it. :-P


> Getting the indentation right should be the least of your worries if you have a good editor (and don't do something like mix spaces and tabs, which I think everyone is in general agreement with across all languages).

Nope. Tabs are for indentation and spaces are for alignment. It's precisely because of non-good (or maybe non-smart) editors that people can't be bothered acknowledging or practicing this distinction and end up using spaces for both.


I was mainly talking about mixing tabs and white space for indentation. Many people set their tabs equivalent to different numbers of whitespace, so when the whitespace and tabs mix, it becomes an issue if the previous developer had tabs set to 2 spaces, but you have them set to 4.


Conveniently, any editor that can properly deal with tabs will have an easy time dealing with semantic leading spaces.


I used to think that way. But then I realized it forced all my co-workers to get their freakin' indenting correct.


I disliked the whitespace thing at first, but after using it for a while I got used to it. Then when I had to go back to change some Perl code I realised the real beauty of it - you never get the problem of having unmatched braces when moving blocks of code around.


Yeah, I hate when my language forces me to write pristine code...


Eh, this argument is at least 10 years old now, isn't it? I don't even remember the last time I had a problem with whitespace in Python. Just use a decent editor (vim!) and you're golden. :)


It's ironic that you say that, given that if you don't get the whitespace correct, you'll have a syntax error. That's one of the big reason Python rubs me the wrong way: white space is semantic.

Not to pile on but this is exactly backwards. The whitespace saves keystrokes and errors because it's giving a semantic meaning to something that programmers put in their code anyway.

Now that I've actually written some code in ruby, I can't comprehend how rubyists aren't driven insane by the 'end' tokens. I'm sure this is a newbie mistake but on multiple occasions I've written something like this:

    def foo(x)
      if x > 5
        puts x
      else
        puts 5
    end

    foo(7)
    foo(3)
Any experienced ruby programmers should see the error pretty quickly. But it LOOKS pretty good. Here is the error you get:

    test.rb:9: syntax error, unexpected $end, expecting kEND
What's on line 9? That's just the end of the file. Nowhere near where the syntax error actually is. In this trivial example, tab-checking the indentation using my editor will reveal the error. But this is a trivial example. In more substantial code this technique is not nearly as effective. In erb templates its harder still.

That never happened to me in python, even as a newbie. If I forget a colon I almost always know instantly because the editor will try to indent my code dramatically wrong. And if I inadvertently delete the colon at a later time without updating the indentation (this happens a lot) I get an instant syntax error that points me right at the line where the colon is missing. It's an error you can fix in your sleep. You don't forget end tokens because there are no end tokens to forget. The block ends when the indentation level decreases.


"white space is semantic"

Is this not true for webpages and journalism?


Semicolons are semantic in journalism too.


As they are in Python:

    import os; import antigravity; # etc...


seriously? you should be properly indenting your code anyway, so it's not like python's making you do more than you should already.


So you are enabled to focus wholly since you are used to its syntax?


I really do think Python's convenience is more than just familiarity. I found it very quick to learn and easy to remember compared to other languages.


I often forget ending for/while/if statements with a colon.

http://markmail.org/message/ve7mwqxhci4pm6lw

In my opinion they should not be required because they cause more problems than they solve.


Yeah, also who needs type checking when you can simply write dozens of unit tests!


without ever worrying about if I misplaced a semi-colon or left out some weird punctuation

I've seen enough code like [(foo[-1:self._bar:2]%(a,b),) for foo in quux] to not really believe that.


the parser is usually really good at spotting those errors and once they've been pointed out are trivial to correct.


Feels exactly the same about Lisp and other languages.




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

Search: