Hacker News new | comments | show | ask | jobs | submit login
Tabs slower than spaces in Firefox (bugzilla.mozilla.org)
179 points by emilong on July 19, 2016 | hide | past | web | favorite | 123 comments



I'm going to use this as fodder next time I get into an argument with someone about why spaces are better than tabs when writing code.

Or maybe I've just been watching too much silicon valley...


I thought that was the most unrealistic thing this season: a supposedly genius programmer who loves tabs and hates spaces.


Poe's law and all, I hope your comment isn't serious. The whole point was to highlight Richard's "neurotic" side. (It failed to convey it for me when his girlfriend started audibly indenting by hitting the spacebar 8 times... I'd go nuts, who wouldn't?)

Also, plenty of geniuses use tabs :) the Linux kernel included. It obviously has no relation.

(Seriously though, tabs are a matter of accessibility. https://leclan.ch/tabs)


If the tab people would reliably use tab for leading indent and space for further alignment, I'd be 100% on board.

But what happens in practice is that the file ends up with a mish-mash of tabs and spaces throughout and the file is only legible if you set your tab stop to a specific setting, and sometimes not even then because different authors have used different tab stops for both indentation and alignment. At which point the tabs buy you nothing.

So just use spaces and be done with it. Or go fmt. :-)


As a tab person, I don't line up code. Each line may decide to unindent, indent, or maintain indentation

Here's some Befunge interpreters in a few different languages: https://github.com/serprex/Befunge


>If the tab people would reliably use tab for leading indent and space for further alignment, I'd be 100% on board.

There is no other way to do tabs. Anything else is simply wrong and grounds for execu... a stern talking-to.


There is another alternative. At the risk of repeating what I've mentioned elsewhere in the thread, this is to not use column alignment at all.

Simply use indentation in the places where you might be tempted to start lining up columns.

It's really easy to use an alignment-free style. A good way to get in the habit is to code in a proportional font instead of monospaced. By doing that, you won't be able to use column alignment, and you'll naturally gravitate toward using indentation to represent the block structure of your code.


I use tabs for indentation. I don't desire or care about column alignment. Code that has carefully-laid-out column alignment feels bizarrely fiddly to me - it's like the fad for absurd giant ASCII boxology comment headers back in the late '80s. Why bother? What's it adding?


I think it would not be hard to create a git hook that checked and fixed inconsistent tabbing.

As someone who tabs, 4 is a very common standard, and consistency has never been a problem.


In our project, we use ESlint to check for this kind of stuff. For a while we had it forcibly fix indentation and minor bugs but some devs didn't like it so now it just warns you. I thought it was amazing.


In an argument of tabs vs spaces. Someone always says both. You are that person.


But the argument really is both vs. spaces. Anyone using tabs for alignment is doing it wrong.


I wonder what's wrong with people today. Just use spaces, any descent text editor inserts 4 or 2 spaces on pressing tab, and nobody has any problem.


This is interesting. Why do we use spaces anyway? I mean, really - what are the advantages spaces have over tabs?

(I use spaces only because I try to follow common coding styles, like PEP 8, but I never gave it enough thought)


One of the main drivers for spaces is alignment, which you should never attempt to do with tabs (except in contexts which normalize tabstops, which generally excludes programming).

Aligning within a line can and should be done with spaces. There's good reasons against alignment in such cases -- for example, it creates git blame/git diff noise when reformatting due to having to update alignment on a bunch of other lines just because you introduced a variable one character longer than the others. Irrelevant, though; such alignment is perfectly fine to do with spaces in a context where you indent with tabs.

The other type of alignment is beginning-of-line alignment, which is indeed not doable with spaces. Some people recommend doing such alignment with spaces despite the tab indent (cf. http://dmitryfrank.com/articles/indent_with_tabs_align_with_...). It's a valid argument but I feel it's too much of an aberration to be taken seriously.

I personally find such alignment generally repulsive anyway. Take a look at the following code and tell me which method looks better:

http://sprunge.us/ZFHJ

Too many times have I seen such function calls where the space between the parenthese and the soft wrap leaves <10 characters to work with. And here we go with one small argument per line, every argument preceded by 70+ spaces. I know programmers who could fit video games in the bytes used for just a single function call like that.


Indeed, column alignment is just about the only reason to prefer spaces for indentation. If you use column alignment, then indenting with spaces avoids the question of "tabs for indentation, spaces for alignment."

But I'm with you: that kind of column alignment is harmful to maintainability, and I find it much less readable too.

Some time ago I posted a few examples of column alignment gone bad, from the Servo source code:

https://news.ycombinator.com/item?id=9469713

and also discussed alignment here:

https://news.ycombinator.com/item?id=9469713

Once you give up column alignment, there's no longer any real reason to prefer spaces, and you can gain the benefits of using tabs. As a side benefit, when you give up alignment, your code becomes just as readable in a proportional font as a monospaced font.

More details in my previous comments linked above, so I won't rehash them here. :-)


Hah, those are beautiful examples, thank you! :) The latest I encountered was a few days ago in the allauth codebase, where I found several instances of things like these: https://github.com/pennersr/django-allauth/blob/07d70fd68c4c...

I remember that page, actually. It's a really good point that code alignment breaks proportional fonts, I never considered it. More points for accessibility I suppose!


for example, it creates git blame/git diff noise when reformatting due to having to update alignment on a bunch of other lines just because you introduced a variable one character longer than the others.

If you're working with git on a non-whitespace-sensitive language, and this annoys you, you can use the --ignore-space-change option to avoid this.


That is certainly true! But the problem is I don't want to ignore whitespace changes when I review my diffs. If I do that, I'm very likely to introduce inadvertent whitespace changes that will annoy everyone I work with. :-)


> Take a look at the following code and tell me which method looks better:

That seems like a strawman to me. I would go with something like:

    function() {
        nested_code() {
            some_very_long_function_call(
                long_argument_one,   long_argument_two,
                long_argument_three, long_argument_four,
            );
        }
    }


That is no semantically no different to #2 so I'm not sure why you think it's a strawman seeing as you just agreed with me. While, like I said, there's reasons against alignment within lines, using tabs doesn't prevent you from doing it.


I meant that aligning columns is orthogonal to breaking up long lines; you can do either, both, or neither, so your example comes across as a strawman.


By definition, scrollaway's example is not a strawman, because the first version matches the way I've seen code formatted very many times.

(I wonder if this why your comment got downvoted? FWIW, I upvoted you for engaging in the discussion.)

Personally, I would do his second example like this:

  function() {
      nested_code() {
          some_very_long_function_call(
              long_argument_one,
              long_argument_two,
              long_argument_three,
              long_argument_four,
          );
      }
  }
In other words, once I get to the point of splitting up the call into multiple lines, I generally split all the arguments onto their own lines.

Now all the arguments are lined up with each other, as they are in your example. This matches how I format multiline statement blocks: if I'm splitting the code to multiple lines, then I split it consistently on each argument. This way I don't have to worry about how many arguments fit on a single line.

Of course I'm not entirely consistent about this. :-) Take a function like CreateFile() in the Windows API. It has so many parameters, and you're likely to pass in NULL or 0 for so many of them, that it makes sense to bunch them up a bit to not use so many lines.

But even then I wouldn't start adding extra spaces within a line to make vertical columns out of it.


This isn't about breaking up long lines. The second indent style results in shorter lines, that is one of the various side effects which makes it superior. My example was meant to display that start-of-line alignment is generally a poor idea and there are better alternatives... which you seem to understand just fine.


my opinion:

The second is better looking. I'd rather maintain the second.

But...

The first is easier to read. The shape of the code is enough for me to parse without effort. In the second, I have to "walk myself" through the code, even for this little example. I feel the effort required as soon as I have to start looking for the embedded commas.

So I usually choose something like the first, since time spent typing matters less than time spent thinking.


How I wish for a universal standard of two tabs producing automatic alignment with whatever also follows a corresponding two tabs on adjacent lines.


Tabs make no sense to me as they're clearly control codes.

I maintain that if tabs are permitted, so are other ASCII control codes, like vertical tab, form feed (which is actually used in GNU code), and bell.

    int foo(void)
    {
    <TAB>/* <BEL><BEL><BEL> This bit is really important. */
    <TAB>...
    }
    <VT>
    int blah(void)
    {
    <TAB>...
    }
    <EOT>
    <EM>
:-)


I like the idea :-)

The GNU coding standards request form-feed (\f or ^L) to separate code into logical pages.

https://www.gnu.org/prep/standards/standards.html#index-cont...


Careful, my friend. Strawmen are highly flammable. ;-)

But I like your sense of humor, so you definitely earned an upvote from me - a flaming tab advocate!

(And I learned to program on a ASR33 Teletype - so I do miss those old control codes...)


Why not go all the way? Use Start of Header before your require/#include/import/etc. then Start of Text when your code proper starts. Replace ifs with ENQ, thens with ACK and elses with NAK. You can build an entire language where all the keywords are just ASCII control codes. That will free up all the punctuation for other purposes, and you could name your variables if, for, while, etc.


The reason is probably similar to why there's now top posting in emails.

The support in editors is abysmal and doesn't work out of the box correctly for tabs (e.g. invisible whitespace).

I've never seen an argument for spaces that would hold iff all editors would have sane defaults for programmers. Of course, it's also bad that some programmers can't configure their tools correctly, but that is a complete different issue.

The best of both worlds would be "tabs for indentation, spaces for alignment" but as it is now, you only need one programmer with wrong settings to screw that up, so that's why most projects have settled on the most conservative setting.


There's an even more conservative setting, which is "don't use alignment at all, use indentation only."

If you do that, all of these issues go away. You can use tabs or spaces for indentation, and it won't affect your formatting. You can reformat the code to a different number of spaces, or switch from spaces to tabs or vice versa, and your code will still be perfectly formatted.

A good way to learn and practice this style is to switch your editor to a proportional font. Now you won't be able to use column alignment, and without even working at it you'll naturally start to explore an alignment-free style.

I've had many programmers react in shock when they see I write code in a proportional font, but when you don't use alignment it stops mattering what font you use.


The common argument is that with spaces the indent is the same in not only every editor, but also every tool used, such as cvs, diff, patch, build tools, web viewers (e.g., for your cvs tool, issue tracker, and/or code review), shell tools (e.g., less and cat), et etcetera.

With tabs you need to configure each and every tool you use to use the right indent (2? 4? 8?), with spaces, every tool just works, and copy/pasting a section of code to or from an issue or an e-mail or a chat tool just works.

It is a matter of code typography. When more than one developer is working on a code base, it helps if every one sees the same outline, because with varying amounts of indenting one persons preference aligns all parameters in a long important method call, whilst any other indenting breaks (part of) that format — code may look fine for one person, but jumbled for another with a different indent preference.

With editor support better than ever, using spaces isn't something you think about when coding; you just hit tab to indent and it inserts the number of spaces configured.

I like Python's PEP 8 in that respect. The language itself (and the syntax checking tools such as pyflakes) simply states the sensible default you aught to be using.


> With editor support better than ever, using spaces isn't something you think about when coding; you just hit tab to indent and it inserts the number of spaces configured

You mean like those times I would have to configure my editor so it inserts the exact amount of spaces required by the project I'm working on, for the project maintainers prefer 4-width to 2-width or 8-width? :)

You talk about typography but this is exactly what I underline in my article: Your preference is not everybody else's and I personally find 2-space code absolutely unreadable... while some companies adopt it as their internal codestyle.

My eyesight has been deteriorating for the past 10 years and I've had to increase my font and zoom sizes as well as line spacing every now and then. Compact 2-space code truly is a strain on the eye for me. If you're using tabs, you don't have to care about my eyesight, just like you don't care about my font size.


If you're interested in another view, see scrollaway's code example linked above, along with my other comment in this thread that links to a couple of my previous discussions of the topic.

In short, the real issue with tabs is that you can't reliably use them for column alignment. But many of us have concluded that column alignment is a harmful practice, preferring indentation instead to show the structure of our code.

And once you give up column alignment, you can use tabs for indentation, and it just doesn't matter what tab size the person reading your code prefers. It will read just the same in any tab size and any font, even proportional fonts.

It's really quite liberating to stop using column alignment. :-)


It's been mentioned elsewhere, but I figured I'd emphasize it here, given

> And once you give up column alignment, you can use tabs for indentation

You don't have to give up alignment for tabs if you like it occasionally; just indent with tabs and align with spaces. (I highlight leading spaces in a slightly different shade from the background to allow for this.)


With tabs, everyone gets to use their own indent. It is a lot more portable from programmer to programmer.


AFAIR It is because a 30 years old rant in Usenet that defended spaces over tabs, but all their arguments were biased by the fact it was about LISP.

It's impossible to use anything but spaces in LISP without going mad, and the editors like emacs do a fantastic job formatting the s-expressions. So spaces are very superior to tabs for some languages.

For languages with a syntax similar to C, it doesn't matter, the rant was taken out of context, and the rest is history.

Whatever you use, make tabs and spaces visibles in your editor and never, ever, mix them up for indentation.


How do tab advocates deal with max column widths? Many projects require that lines not exceed 80 chars, but I'm not sure how'd you establish that kind of limit with variable length tabs.


That's a very reasonable question to ask.

I suspect that it isn't much of an issue in practice for a few reasons:

1) I'd wager that most projects that have a hard 80-column limit also forbid tabs.

2) If a project does use tabs and has a hard line length limit, it can simply say that that limit is interpreted using a certain tab size (e.g. the most common tab size is probably 4 spaces).

3) In my own code, as I've mentioned probably too many times in this thread :-) I don't use column alignment, which is one of the main causes of excessive line length. Because I use indentation for multiline expressions, my lines of code tend to be a lot shorter than they would be with column-aligned expressions.


Personally: by not enforcing maximum widths. Having a fixed limit makes for ugly workarounds and looks horrid if you happen to be viewing at a narrower width. Just wrap code where it makes sense to do so.


I think that depends partially on the verbosity of the programming language (e.g. type declarations, casting, templating) which eat up a lot of columns, and verbosity of coding style. In the latter case, if your variable names are `name_of_person' rather than simply `name' (which should be obvious by context), you're also going to have problems.

The first one might be a legitimate issue. The second issue, I've noticed, I've never had a problem with, even in heavily indented lisp:

- If your variable names are too long, they must not be obvious from context, and your function/method/block is doing too much. Refactor.

- Consequently, if the line is too long, perhaps it's doing a little too much; short lines with limited logic help with code comprehension the same way short methods do. Splitting code into multiple lines generously allows you to clearly indicate how parts relate to one-another.

My line width is 76 characters max to allow for 3 columns for line numbering + one space after it---if line numbering requires more columns that that, maybe your file's too big as well. Some will disagree on that last point, but I consider that in the same light as I do line length and function size. For OOP especially where there's one class per file, it's certainly a code smell if you have a long file.


EditorConfig or various other configuration setups allow your editor/git/whatever to read a tab as if it is "n" spaces, where that is somewhat configurable. Using EditorConfig, this allows consistency across tooling, and solves this problem neatly (at least in this particular use-case, YMMV in other places where this isn't possible or desirable).


Suppose I have a configured tab width of 2 and I write a line with three tabs that's 78 characters wide. When my friend with tab-width 8 views it, he'll see a line that's 90 characters wide. What do projects with 80 character limits do in situations like that?

In either case the line contains only 75 characters, of course, but that's a pretty pedantic non-answer: we care about horizontal screen space, not the number of bytes of storage you'd need.


EditorConfig tells you the canonical tab size for the project, in other words "a tab counts as 4 characters to the soft wrap". If you choose to increase the tab size beyond 4 characters, you have to accept you'll get longer lines.

(It's also high time we stop pretending wrap limits matter to the exact character. In most cases, they are and should be guidelines - we have evolved beyond 640x480 CRTs and 80 character terminals)


This is interesting. Why do we use spaces anyway? I mean, really - what are the advantages spaces have over tabs?

Apparently nested JS runs faster with spaces.


Tab width can vary between editors, i.e. do a "set shiftwidth=8" in vim, and it'll be 8 spaces. Spaces are more constant.r


I have to admit I always thought of that as an advantage of tabs, since they allow the viewer to set how much to indent the code, and doesn't force anyone to adapt to someone else's preferred style. I like it when a tab = 4 spaces, but you like it when a tab = 2 spaces. Cool, just set your editor accordingly.


Unfortunately, it also means that if the viewer hasn't or can't set the tab width, it may look awful. GitHub was using 8 spaces per tab by default, and my code looked ridiculous. Now GitHub checks .editorconfig for a default tab width, but it didn't used to.


It's certainly some progress that GitHub now follows .editorconfig! But now that they have the ability to render tabs with different numbers of spaces, I wish they could have changed the default to four spaces while they were at it. Aside from the Linux kernel, not too many people really like eight-column tabs.

I've always omitted the indent_size and tab_width settings from my .editorconfig files that specified tabs, because I wanted to let people view the code in their preferred default indentation size instead of one I specified.

(As I've mentioned too many times in this thread, I follow an indentation-only style with no column alignment, so you can view the code at any tab width without breaking the formatting.)

Now, just to make GitHub give a reasonable code listing, I'm having to add indent_size=4 to all my .editorconfig files. That's not a terrible thing, but I really would prefer to leave the choice up to the viewer instead of forcing 4-character tabs.


Isn't that the whole point of tabs? So everyone can have their own width preference without going mad with git merges.


I thought that was a reason _for_ tabs, so everybody can have their own indent size.


Tabs don't work very well when you use whitespace for alignment, for example in multi-line statements. Change the tab size and it's all off...

And seeing as 80 characters is still the normal line limit, because of window splitting, it does happen quite often.


The problem there isn't tabs, it's column alignment.

If you stop using alignment and use only indentation for your multiline statements, these issues go away. Your code will be just as readable with any tab size, and even in a proportional font. And your line lengths get much shorter in the process.

For specific examples, see the other comments in this thread from scrollaway and myself, in particular the Servo source code I linked to.


So you're trying to dictate a coding style to make up for tabs' weaknesses? That's like Apple's reaction to bad reception on phones: "You're holding it wrong".

No, thanks, I'd rather use spaces that don't require any workarounds.


> So you're trying to dictate a coding style to make up for tabs' weaknesses?

Not in the slightest. The disadvantages of column alignment have nothing to do with whether you use tabs or spaces.

I don't recall for sure, but I think I was using spaces for indentation at the time that I stopped using column alignment.

Column alignment has the same problems if you indent with spaces: it leads to excessive line length, it's unfriendly toward source control diffs, it's fiddly to maintain, it mandates the use of a monospaced font, and I find that it harms readability compared to the alternative of using indentation.

Take a look at the Servo code examples I linked to in another comment. Are the column-aligned versions a better way to format code than the indented versions?

Here's another way to look at it. If the column-aligned way of writing a multiline function call or expression is such a good thing, why don't we also format blocks of statements this way:

  if( foo == bar ) { if( baz == moo ) { console.log( "yes" );
                                        this.that = true; }
                     else { console.log( "no" );
                            this.that = false; } }
instead of:

  if( foo == bar ) {
      if( baz == moo ) {
          console.log( "yes" );
          this.that = true;
      } else {
          console.log( "no" );
          this.that = false;
      }
  }
It is probably obvious that I prefer the latter, as would most developers. So why not apply the same formatting principle to expressions that we apply to statements?


That's a good question. Lisp programmers such as myself do indeed format code like your first example all the time.

In fact, having done a lot of Lisp programming recently, I wanted to format some Java code using that style too, but IDEA's code formatter is too limited to allow me to do that.


> If the column-aligned way of writing a multiline function call or expression is such a good thing, why don't we also format blocks of statements this way:

I don't see any reason not to. Your example is pretty ugly though, as it's not particularly aligned. What about:

    if( foo == bar ) { if( baz == moo ) { console.log( "yes" );
                                             this.that = true ; }
                                   else { console.log( "no"  );
                                             this.that = false; } }


Now that is an interesting approach! So you're lining up the dots? I like the creative thinking, even if I don't like the end result.

A couple of problems I see here:

What happens if you have more than one dot, like foo.bar.method()? Which dots do you line up?

And note that the else isn't aligned with its matching if.

I suppose another alternative would be to line things up like this:

  if( foo == bar ) { if( baz == moo ) { console.log( "yes" );
                                        this.that = true; }
                     else             { console.log( "no" );
                                        this.that = false; } }
Now the if and else line up, and so do the statements in the dependent blocks.

But with either of these aligned formats, I'm finding it pretty hard to visualize which if statement goes with which block of statements.

To me, this is one of the fundamental problems with column alignment: once you start doing it, it's too easy to start fiddling with all of the possible things you might align. And it really doesn't help the reader visualize the code structure except in the simplest cases.

Also, you're in for a maintenance headache when someone changes foo to moreMeaningfulName. Now what? Move everything farther to the right?

With an indentation-only format, you can change any of the variable/function names without breaking the formatting at all.


> To me, this is one of the fundamental problems with column alignment: once you start doing it, it's too easy to start fiddling with all of the possible things you might align. And it really doesn't help the reader visualize the code structure except in the simplest cases.

I certainly agree that it can cause problems, e.g. with diffs, extraneous decisions, etc.

I only tend to do it when there's commonality between the lines (more than trivial ones, like "there's a dot"); e.g. aligning the "=" in a bunch of assignments, aligning the arguments in calls to the same function, etc.

> Also, you're in for a maintenance headache when someone changes foo to moreMeaningfulName. Now what? Move everything farther to the right?

I tend to follow the following process:

- Preserve the existing alignment (e.g. "move everything over")

- If any lines grow longer than 80 characters, split them

- If any already-split lines shrink to less than 80 characters, remove the split

- If you spot a nicer pattern, try it

- If there's no pattern anymore, "fall back" to not doing any alignment; consider inserting blank lines if the statements are very different or the lines are very dense

I've thought a few times about making an auto-layout script, which would run files through a language-agnostic "nicely aligned" fitness function, and make a bunch of language-specific semantics-preserving edits to try and maximise this score. It's quite low on my TODO list though ;)


Why are you doing character-based right-alignment in a LTR script?

It breaks with proportional fonts, and... well, if we wanted to right-align things in code, our non-document editor would probably support it by now, don't you think?


> Why are you doing character-based right-alignment in a LTR script?

It's not right-aligned, I've aligned the "." method accessors, ";" statement delimeters, etc. into the same column, and treated "else {" as a single token.

It would be even nicer to align the two pairs of statements more directly, but that ends up overflowing 80 characters, e.g.

    if( foo == bar ) { if( baz == moo ) { console.log( "yes" ); this.that = true ; }
                                   else { console.log( "no"  ); this.that = false; } }
> It breaks with proportional fonts

Proportional fonts break many "in-band" layout schemes; e.g. ASCII-art layout used in plaintext email. I think "out of band" layout schemes, like CSS, would be overkill for code layout; and certainly more effort to implement than making the editor manipulate ASTs instead of character streams.


"Many of us" - you are using that way too often in your posts and it's a pseudo argument. Fact is, you're giving up the choice of different coding styles to make something broken work.

"Many of us" prefer spaces for that reason and that's why it has become the de facto standard.


> "Many of us" prefer spaces for that reason and that's why it has become the de facto standard

Has it? I wasn't informed. I know it has in the Python community, because of pep8 mainly, but a lot of communities have settled on tabs (Lua for example, and for a long time PHP until recently).

I'll paste here what I replied to someone off-thread, regarding "why" anything ever becomes a de facto standard.

> I would bet quite a bit that personal indent preferences are driven by whatever the default is on the editor of choice of the person in question. I would equally bet that you can correlate the tab defaults on editors/IDEs widely used in specific communities (Visual Studio for Windows C-family stacks, PyCharm for python, Eclipse and its little family for java, etc) and the general preference of that community.

Chicken and egg problem. Spaces aren't standard because they're preferred; they're preferred because they're standardized by editor defaults. Developers that don't have a particular preference grow into those defaults.


It's more like new editors ship with spaces as default, because most style guides recommend it.

Google, Microsoft, Apache and NASA for C-family languages, Crockford and almost every other web-related style guide I've ever seen recommend the use of spaces. Apple is a notable exception.

It seems you're the vocal minority: https://ukupat.github.io/tabs-or-spaces/


Your point about my overuse of "many of us" is a good one, so I changed it to "I" in the comment you just replied to. Fair enough?

But look, my real point here is that column alignment is detrimental in several ways, and indentation is a better way to illustrate your code structure - both for statements and expressions.

Using indentation instead of column alignment isn't a workaround for anything - it's just a more practical, readable, maintainable way to format your code. This question really has nothing to do with tabs or spaces.


I see the points for VCS and non-monospace fonts, minor as they may be, but readability is absolutely a matter of choice.

While we're on the matter of user prefereces and numbers: Most style guides recommend spaces as lined out in my other post.

>Google, Microsoft, Apache and NASA for C-family languages, Crockford and almost every other web-related style guide I've ever seen recommend the use of spaces. Apple is a notable exception.

That doesn't make them right, but I'd like to know how you came up with the "many of us" in the first place, because there are far more developers who use spaces (https://ukupat.github.io/tabs-or-spaces/), and it's not even close.


"Many of us" doesn't imply "a majority of us". This statement isn't contradictory and is backed up by the data you linked: "Many of us use tabs. Many of us use spaces. Some of us use form-feed.. bloody nutters!"


> It failed to convey it for me when his girlfriend started audibly indenting by hitting the spacebar 8 times... I'd go nuts, who wouldn't?

I remember when I got into coding Runescape autoclick bots when I was 14, in an arcane Delphi editor / standard library called SCAR, it was the insane convention to not use any indenting at all. Indeed you had to manually hit the spacebar again and again to get some proper indenting.

Also, the spacebar key on my keyboard was noisy.


If you're interested, that community is still alive and pretty active as SIMBA [1].

Not hard to find very smart people with very poor coding standards.

[1] https://villavu.com/forum/


Autorune was better though :)

Attack(0) would attack yourself in wilderness, leaving bystanders confused.


I've never quite understood why lots of IDEs don't convert a file to your preferred variation of tabs or spaces when you open a file, and then convert it back again when you save it. On disk the indentation could be one thing while in the editor it's something else. That way everyone's happy.


Probably because it's not easy. Spaces as indent are lossy - converting spaces to tabs can lose contextual information (eg. when they are used for alignment).

You can easily and losslessly do it the other way around, though, which leads me to do exactly what you say when working on a space-indented project: I code with tabs, I convert before committing. It's usually easier than dealing with spaces.


I think the whole notion of programming language as pure text and even using "files" as a unit is veering towards obsoletion. We do it that way because that's the way it's always been done, but I can see plenty of cases where an IDE that uses a more hybrid graphical approach would be beneficial, and we wouldn't have arguments like this :)


While I agree in some senses, i'm terrified of this idea in others.

A business-basic style language i work with (second time i've talked about it in a few days... it's weird) saves it's files in a strange not-compiled-but-not-plaintext format that only it can read. That means you can't use your VCS of choice, you can't use your favorite editor, you can't even grep through the codebase to find where a variable name is used.

Technically you could write something to get it working in a more "normal" editor, but that is a path I don't want to run down.

Ignoring encoding, text is about as accessible as it gets. You can always layer more tooling on top of it, but you can't take it away from a non-text representation easily.

Personally I like the way that the go team handles it. Source files are "plaintext" (again, ignoring encodings for the sake of discussion), but there is one (and only one) canonical format for the layout of the code, and a tool which will apply it.

Then like you said, you can have IDEs which can layer more visual representations on top of that if needed, and there is a chance that some people could program without actually seeing the "plaintext" source code.


I feel like WASM could be a first step in that, a binary AST/graph-like format with a preferred textual representation. It even has a bidirectional codec.


The "tabify" and "untabify" commands do this in Emacs, and many languages have linters which can flag either (which you can then run, e.g. as a git pre-commit hook).

If spaces/tabs were just about nesting code blocks then this would all be a no-brainer, but vertical alignment can convey much more information than that (for example, splitting statements into semantically equivalent columns).


> hitting the spacebar 8 times

I used to do this before I switched from vi to vim. I used 2-space indents to save wear and tear on my thumb.


> I thought that was the most unrealistic thing this season: a supposedly genius programmer who loves tabs and hates spaces.

I've never met a programmer that didn't have some view of code style. Even the really clever ones consider their code to be a form of art, so what you use to write it does matter. It's all pretentious, but I actually thought it was a very accurate portrayal of the trivial things that programmers make a big deal out of.


A supposed genius programmer who can have an argument for such a silly question.

Besides, why people don't use linters?


Shots fired!


Just because of this I knew the whole show was BS.


You just don't get it, it's not supposed to depict programmers in the Silicon Valley.

It's a comedy, that makes fun of the stuff happening in the Silicon Valley by strongly exaggerating it.

On a side note, geniuses are know to have unusual quirks.


Doesn't everyone have their IDE turn tab characters into some number of spaces by default? Easiest way to deal with this.


the only reason to use spaces over tabs is if your tab key broke and you can't map it to a double-tap space (yeah, I did that once). /thread


> map it to a double-tap space

How do you do that?


In vim, adding the following to your .vimrc should do it:

    inoremap <Space><Space> <Tab>


Or just `set expandtab`...


That would be more like

  inoremap <Tab> <Space><Space>
The request was: when I press two spaces, I want a tab character to be inputted. I agree that if you want `n` spaces when the tab key is pressed, you should use `expandtab` and `shiftwidth`.


Ah, quick/lazy reading. Sorry.

Of course now my question is why in the seven hells would you want that mapping??


The premise was that the tab key was broken.


Tabs are the devils puss is a more convincing argument for the religiously motivated Tabs user.

They don't respond to reason. Obviously. /s


From the comments, it looks like there's an "optimization" that kicks in when a function is under 100 characters long. It seems that optimization is backfiring and actually making a tabbed function slower.


Interesting to note that character-based optimizations in JS engines are somewhat common (though this article is a few years old): http://jayconrod.com/posts/54/a-tour-of-v8-crankshaft-the-op...


Obvious fix: Count the length of the function without whitespace characters, so that both versions are equally slowed down by the optimization.

Unfortunately, this sounds like one of those problems where a non-fix like that is still the best you can really do. If nothing else, this should still be at least a more accurate representation of the complexity of the function.


Then the next guy comes and complains why `var a = 42` is slower than `var abc = 42`. And so on. I wonder if it also counts comments. It soon becomes quite complicated. Maybe you can count the number of dots in non-comments and non-strings and will get a better heuristic.


> I wonder if it also counts comments.

It does! If I remember correctly, there's a great gist floating around that shows this off, where the comment itself is what caused two functions to be different in performance, despite being identical ;)


I think you're thinking about "Optimization killers" (https://news.ycombinator.com/item?id=7943303 [which funnily, I submitted 754 days ago!]), but it just touches V8.

Haven't seen one around for SpiderMonkey, would be interested in seeing one though.


(Note: I worked on SpiderMonkey's JIT and various optimization-related things)

In general the accepted "best practice" approach is always to use the length of the compiled bytecode as a heuristic. This is what we use basically everywhere in the JIT for "function size" heuristics - inlining logic being the biggest user.

V8 doesn't have a bytecode (although I've heard they're adding a bytecode interpreter now), but even there, they can use AST-weight (i.e. the count of all vertices in the AST for a function) as a measure of the function size.

Counting bytes, characters, or any sort of raw source-related metric is a bad idea.

These things happen because it's easy to use an easy heuristic that'll work most of the time. The size of a function in source-code bytes is easy to get, and always available. You may not be able to guarantee that bytecode or AST info is available when you want to use it (e.g. if the function has been lazified due to lack-of-use and all the compiled bits thrown away).


Yes. If the optimization actually worked then tabs would be better than spaces in some cases and spaces would never out-perform tabs.


Read the title and thought it had to do with tabbed browsing versus using different Spaces in OS X.


This is great bug, right up there with the Dwarf Fortress bug that involved a dwarf planting a bed in a farm plot.


Would you be able to link this? I'm interested in reading about it. A quick google for 'dwarf planting a bed in a farm plot bug fortress' turns up nothing relevant at a glance.


It's mentioned in the wikipedia page under "further updates"

https://en.wikipedia.org/wiki/Dwarf_Fortress#Further_updates

Which refers to a brief mention here:

http://www.pcgamer.com/community-heroes-tarn-adams-for-dwarf...

but there are no details.


Tested in ff 47 on linux, same result in both cases (0). Am I missing here something?


Same on Firefox 47.0.1, OS X -- maybe it's only on Windows?

BTW I get ~15ms on Safari, ~60ms on Chrome and ~47ms on Firefox.


Now, can we please have a bug that punishes the use of semicolons?


I vote for a bug that punishes the opposite.


Hear, hear.


Man, you are about to start WWIII :)

https://news.ycombinator.com/item?id=3842713


That would be terrible for minified code, though


well a newline is the same amount of bytes!


Newlines and semicolons aren't always interchangeable in Javascript.


the only situation they aren't is when a line starts with a [ or a (

In every other scenario, a newline and a semicolon are interchangeable.


This reminds me of "Silicon Valley" episode whent there was TABS vs. SPACES fight :)


Anyone who makes a language in which the performance of a call to previously processed code depends on its original whitespace should immediately be stripped of their CS degree, if they even have one.

If some decision depends on the size of a function, that size should be measured over the parsed code: number of nodes in the abstract syntax tree or whatever. This should be obvious to everyone by around the end of their second year of school. A function isn't larger if we give it wider indentation with more spaces, or replace its local variables with ones having longer names.


Now it's been a bit since I last read about this a bit so forgive me if i'm off by a lot, but i'm pretty sure most javascript engines do this.

The reasoning is that they will parse the text slightly differently depending on if it is being inlined or not (potentially skipping steps if possible to speed the process up), so the heuristic needs to happen before the parsing step.

Yeah, you could add in some checking to do things like strip comments, whitespace, and other "simple" things, but is it really worth the extra cycles?

With minifiers and compilers in such large usage, a check like that would most likely just waste CPU time in the vast majority of cases, not to mention the extra developer time spent in the engine.

That being said, i'm pretty sure this exact instance is a bug.


> parse the text slightly differently depending on if it is being inlined or not

Any frosh should recognize that as a language design/implementation smell by their third year.

> most javascript engines do this

That somehow falls short of being convincing that it's right.


You can say how it's design smell all you want, but do you have any reasons why?

This is a JIT, optimizations like this can (and do) have some pretty big impacts on the speed of the execution without needing a long warmup which is extremely important for a language like javsacript. And in doing so it needs to balance battery usage, startup performance, "hot" performance, and a ton of other things. Its easy for you to stand back and say "that's dumb", but optimizations are often messy, and without them the language would run much slower.

> That somehow falls short of being convincing that it's right.

That's why I tried to provide other reasons why I think it's right...


The reason most JavaScript engines do it is because they have three or four ways of executing code that are all intended to offer maximal performance under different circumstances. If it takes longer to compile a function than to simply interpret it, don't bother compiling. If it's called frequently, compile it.

Your academic view of compilers work has no bearing on how ugly and complicated reality is.


> Your academic view of compilers work ...

I didn't write anything about compilers. Scanning tokens isn't compiling. Even old line number BASIC in 1981 running on 1Mhz computers with 32Kb RAM at tokenized code as it was entered into memory.


The JavaScript VM is a lot more complicated than a compiler, it's a compiler, an interpreter, and a whole heap of hacks to squeeze maximal performance out of it.

That there's a problem processing whitespace isn't a reflection on the team not knowing their stuff, it's a problem that will be corrected. It's likely something that was never benchmarked and proven to be an issue before, or if it was an issue it was a low-priority one.


Lets say you've thrown away the ast, don't have a token stream, etc, but do still have access to the source of the function. Getting the function length is O(1). At worst, its a subtraction. Lexing it is considerably more expensive, and doing so just to improve the heuristic may not be worth the time.




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

Search: