Live data from Hacker News

John Carmack's comment on Doom 3's code style

kotaku.com

81–90 of 210 posts

Re: John Carmack's comment on Doom 3's code style

#82
post #63

Earlier quoted context omitted.

I like the last one better. I think it reads more like "assign one of these values to sides[i]" and less like "do one of these three things". "By this latter I mean, if you change the code a little bit, you don't have to rewrite it; it looks basically the same." I'd say that's kind of the point though. The first one would look "basically the same" if in the last else it assigned to sides[j] instead of sides[i]. In th…

Precisely. And there is even a little bit more to it. 1. it reads "assign one of these values to sides[i]". 2. it would not allow some other peoples spurious code into the assignment. which is a good thing. 3. space is used to convey meaning; note how sides[i] stands next to dists[i]; ternary operation is formatted as a table, etc.

Not allowing other code in is a bad thing. See my putty reply above.

Re: John Carmack's comment on Doom 3's code style

#83

I've loved John's code since I saw it first time when the original Quake was leaked from their FTP site through IP spoofing. I was just a kid at that time, and it was an amazing experience to hack it. Yet now, the first example that I saw in this article hurts my eyes. Compare: for ( i = 0; i numVerts ; i++ ) { dot = plane.Distance( in->verts[i] ); dists[i] = dot; if ( dot LIGHT_CLIP_EPSILON ) { sides[i] = SIDE_FRONT…

Since we're playing Space Nazi, I like this better:

  for (int i = 0; i numVerts; i++)
    {
      dot = plane.Distance (in->verts[i]);
      dists[i] = dot;

      sides[i] =
        dot  LIGHT_CLIP_EPSILON  ? SIDE_FRONT : SIDE_ON;

      counts[sides[i]]++;
    }
Note that emacs will tab-align the table rows properly if you break the sides[i] = line after the = which is why I did it; not sure about vim.

Re: John Carmack's comment on Doom 3's code style

#84
post #79

Earlier quoted context omitted.

If trivial whitespace difference causes wrath fill conflicts then I think you have a deeper issue. I can't think of a situation where this would be even a minor issue.

Not a huge deal, but it hides the actual author of that line when you're doing a blame. I try to only change the precise lines I need to in a commit, and all of them are relevant to the commit message. That way it's usually a very quick check to see what commit added a certain line. If I absolutely need to do some tidying in a file, I do it in a fully separate commit so that the change can not be construed to be rela…

Sounds like someone should implement a blame option for "ignore whitespace - show latest author with non-whitespace changes"!

Re: John Carmack's comment on Doom 3's code style

#85
post #69

Earlier quoted context omitted.

I really do not understand why they chose to do so. In my opinion, it does not improve readability at all, even worse, when the spacing between type and name gets big , your eyes need more work to figure out the correct line relations. Furthermore, this can generate horrible commits, for example: int x; int y; becomes: int x; int y; float z; after adding ONE single variable. But your commit will contain changes for t…

If trivial whitespace difference causes wrath fill conflicts then I think you have a deeper issue. I can't think of a situation where this would be even a minor issue.

If multiple people rearrange the white space at the same time as adding variables (e.g., because the new variables are of types whose names are different widths, both wider than the old gap), you are more likely to get a conflict than if they just leave the spacing alone. Many version control systems seem to tend to do their automated merges line by line, and this sort of edit seems to give them less to work with. [8c99a51796e06219f472f78a5c081dd664da83dc]

Then the wrath comes when you get latest (pull, update, fetch, rebase, call it what you will) and have an inconvenient merge forced on you! I've always personally found the fact that it's just adding or removing white space especially galling :) - but tastes may differ.

Re: John Carmack's comment on Doom 3's code style

#86
post #11

As someone who has worked with the Doom 3 source code for a mod, I have the opposite opinion. The code very clearly shows a programming team (or programmer) in the process of transitioning from old-school C to C++. Most functions have a huge blob of variable declarations right at the top, as was once necessary in C, even though these variables aren't used until later, or possibly even at all. Usage of const is minima…

What do you find so disagreeable about collecting variables at the top of a function? For the most part, I like having all the variable declarations at the top, so it's easy to see what names are in what scope.

It makes it difficult to have const locals if you get some sort of dependency chain based on other locals interspersed with other computation. For example, if you're a const nazi you can't have code like this:

    const int x = foo();
    // ...
    const int y = bar(x);
and also have your variables all declared at the top.

In C++ I'm a const nazi and declare where used to facilitate it, but if I'm writing C that targets the MSVC compiler (C89) where all variables have to be collected at the top of the inner scope I'll relax this as much as I have to.

Re: John Carmack's comment on Doom 3's code style

#87
post #80
post #63

Earlier quoted context omitted.

I like the last one better. I think it reads more like "assign one of these values to sides[i]" and less like "do one of these three things". "By this latter I mean, if you change the code a little bit, you don't have to rewrite it; it looks basically the same." I'd say that's kind of the point though. The first one would look "basically the same" if in the last else it assigned to sides[j] instead of sides[i]. In th…

My point is that when you are writing complicated production code, and you are a good programmer such that your rate of features successfully implemented is high, then you will often be going to old code and changing that code to behave somewhat differently than it was before. When you do this, you want that old code to be like putty. You want to bend it into a new shape without having to break it and start over. Som…

It strikes me that your argument taken to the extreme is that everybody should program in assembly language because you can do anything, anytime, anywhere. Well, at least as far as control flow structures are concerned. Certainly C is preferable to C++ if you want simple and malleable code.

Do you also prefer if-else to switch statements? (I'm not sure.)

Do you like to use goto? (I doubt it.)

Do you eschew the use of classes and inheritance? (I doubt it.)

Do you keep all your code in one file? (I'd be very surprised.)

My point with these semi-facetious questions is that structure is important and regularity in a codebase does wonders for comprehensibility and maintainability. I agree with you for the case in which you do actually have something where the underlying structure is likely to change, in that then it does make sense to write it with malleability in mind.

Consider something like command line options processing. You have 50 options. You might want a 51st option. It makes sense to use the most regular structures you can so that people don't start special-casing stuff in the middle of it all. That, or to use an options library that defines the allowable formats for you.

Part of me thinks you're just having an allergic reaction to ?: simply because it is pretty unusual the first time you see it used seriously. But it can simplify so much:

Compare:

  if (a)
    {
      return b;
    }
  return c;
to:

  return a ? b : c;

Re: John Carmack's comment on Doom 3's code style

#88

> C++ code can quickly get unruly and ugly without diligence on the part of the programmers. To see how bad things can get, check out the STL source code. Microsoft's and GCC's[5] STL implementations are probably the ugliest source code I've ever seen. Even when programmers take extreme care to make their template code as readable as possible it's still a complete mess. Take a look at Andrei Alexandrescu's Loki libra…

Any style of programming can look like a mistake if you take it to crazy extremes. I find header/template C++ programming works very well provided you do it in moderation and keep things simple.

Remember the STL is complicated because it tries to be super generic, and it tries to be super generic because it's a library so it tries to cater for all possible uses. If you're writing a program instead of a library, you can make things orders of magnitude simpler because you only have to provide what you need, not everything any programmer on Earth might need.

Re: John Carmack's comment on Doom 3's code style

#89
post #57
post #25

Earlier quoted context omitted.

void up_front_decls() { float some_var; int another_var; some_var = get_some_var(); do_some_calculations(some_var); maybe_something_else(&some_var); some_var = get_another_var(); do_some_other_calculations(another_var); blah_blah_already_broken(); } void as_needed_decls() { float some_var = get_some_var(); do_some_calculations(some_var); maybe_something_else(&some_var); int some_var = get_another_var(); // compile-ti…

Regarding poor_style(), I've never understood this objection (and indeed I prefer the block style you complain about there). Can't your editor fix this up for you in a few keystrokes? This is the sort of thing that an editor should make easy.

I have a few objections:

1. It wastes my time. Sure, I could probably set up my editor to fix this, but I shouldn't have to do so to satisfy someone else's pointless indentation fetish. I've personally never worked on a team where this was an accepted, general guideline. It was always just one guy who wanted this, and did it to every function he touched, adding maintenance headaches for everyone else (until/unless other people finally told him to stop).

2. It messes up diffs. Now instead of one line showing up in the diff, the entire block is often different. And yes, most diff tools have options to hide whitespace differences. Again, though, this adds overhead to everyone who doesn't want this block style. I'd rather not hide whitespace differences, because if someone has added a bunch of inappropriate whitespace (or mangled the block while trying to reformat it to include their new variable), I want to know about it during the code review so I can tell them to fix it then rather than finding it later when I'm editing the file.

3. It doesn't actually help anything. Yes, you get a nice column that shows you all the variable names. What good is that, though? Unless you're putting everything at the top of the function (which has its own set of problems), you're not really getting anything useful from this except maybe prettier code (arguable), because at a glance you still don't really get know all the in-scope variables (not to mention file-scope variables). Moreover, you actually lose something valuable with this style, because now it's harder to determine a variable's type. You're trying to scan left from the name across some indeterminate amount of whitespace to match with the type. This is not typically easy to do, which is why column-oriented data is typically displayed with alternating background colors on each row.

Re: John Carmack's comment on Doom 3's code style

#90

I've loved John's code since I saw it first time when the original Quake was leaked from their FTP site through IP spoofing. I was just a kid at that time, and it was an amazing experience to hack it. Yet now, the first example that I saw in this article hurts my eyes. Compare: for ( i = 0; i numVerts ; i++ ) { dot = plane.Distance( in->verts[i] ); dists[i] = dot; if ( dot LIGHT_CLIP_EPSILON ) { sides[i] = SIDE_FRONT…

Well, let me state this: John's version is not to my preference 'cause it has { in the same line as if, but I can live with that. But YOUR version uses not only the ? operator, which should be burned with fire but it NESTS two of them together. Please, I want to die now. :(

Conclusion: We have different preferences.

Post reply on HN