Live data from Hacker News

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

kotaku.com

91–100 of 210 posts

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

#91

A lot of the practices here are enshrined in the Google C++ styleguide: http://google-styleguide.googlecode.com/svn/trunk/cppguide.x... The author's first point about establishing conventions so that you can re-use the code that works with those conventions is very important. At Google, nobody writes code to serialize/deserialize bytes, because the default answer is just "use protobufs". Nobody writes low-level commu…

It's funny you mention that, as I'm using the companion program (http://google-styleguide.googlecode.com/svn/trunk/cpplint/cp...) on the code for my current project right now. My only complaints is that much of the cpplint program checks for arbitrary style choice versus possible issues. Sure, most of the style I agree with, but I've actually hacked on that program a bit because the style guidelines are hardcoded in it. I'm halfway tempted to make it more flexible in terms of style, or at least separate the style components from the linting parts.

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

#92

My heart grew a little warm with the last paragraph of John Carmack's comment: "The major evolution that is still going on for me is towards a more functional programming style, which involves unlearning a lot of old habits, and backing away from some OOP directions."

Tim Sweeney of Epic also praised functional programming few years ago http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-... I don't know what's his stance on the subject since though.

He uses C# to provide examples of dynamic failure in compiler checked code. Since then, some of his 'what we want to write' pseudo-code examples are now reality in C#.

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

#93
post #82

Earlier quoted context omitted.

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.

It depends.

But in this particular case, some trivial extra code inserted inside that if statement may break things. Like breaking vectorization of that 'for' (note, that we are going over vertices).

When you are writing the code, some times you may want to put additional constraints on the allowed operations, modifications, etc. A trivial example in C++ would be using 'const &' instead of '&'.

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

#94
post #82

Earlier quoted context omitted.

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.

Then why are you using a statically-typed language?

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

#95
post #80

Earlier quoted context omitted.

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…

Not to mention that it's essential for initializing some constant variables; I have yet to find a better way to do:

  const int count = argc > 1 ? atoi(argv[1]) : 1000000;
For quick test programs where I might want to change some number of iterations without having to recompile, but I also don't want to have to provide an argument every time I run it.

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

#96
post #80

Earlier quoted context omitted.

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…

No, you clearly didn't understand my point. I am talking about maximizing the rate of successful features implemented. Programming things in assembly language is obviously not going to do that.

I don't know, man. I have 31 years of programming experience. I am not detecting from your argument that you have anywhere near this level of experience, so I am inclined not to get into this discussion. But I will say that your code example at the end of your comment is exactly what I am talking about. It happens all the time that I want to put something in front of 'return b' (or, in fact, I just want to put a breakpoint on that line in the debugger! Not going to happen in your second example...)

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

#97

A lot of the practices here are enshrined in the Google C++ styleguide: http://google-styleguide.googlecode.com/svn/trunk/cppguide.x... The author's first point about establishing conventions so that you can re-use the code that works with those conventions is very important. At Google, nobody writes code to serialize/deserialize bytes, because the default answer is just "use protobufs". Nobody writes low-level commu…

It's funny you mention that, as I'm using the companion program ( http://google-styleguide.googlecode.com/svn/trunk/cpplint/cp... ) on the code for my current project right now. My only complaints is that much of the cpplint program checks for arbitrary style choice versus possible issues. Sure, most of the style I agree with, but I've actually hacked on that program a bit because the style guidelines are hardcoded i…

That's my pet peeve about many linters as well - I don't use jslint because it has many of Crockford's personal style tastes embedded in it, several of which I disagree with. In cpplint's (and perhaps jslint's) defense, it was written for one specific organization with broadly-accepted style guidelines, and open-sourced "in the hopes that it'll be useful, but without any warranty of any kind".

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

#98
post #75

So he discourages Getters/Setters and instead says that declaring the variable as Public is better? I mean, isn't that like not giving a sh-- about encapsulation principles ?

I'm kind of the same opinion as Carmack re: getters/setters. My feeling is, if all you're going to do is allow clients to read and write the variable, why not just expose it? Sure, you can argue encapsulation and even justify it by saying that later down the road you may want to change the implementation, but far too often I've seen C++ classes with a setter and getter for every variable, for no good reason (eg, they're never called, or shouldn't be). I think it behooves programmers to really think about the interfaces their code offers; don't just expose something through setters and getters because it's there, ask yourself, what is this class really offering that you couldn't get with a struct? Pass through setters and getters aren't an abstraction.

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

#99
post #80

Earlier quoted context omitted.

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…

Well, I might be unusual, but I don't object to goto, I don't uses classes and inheritance much - and I like code that's all in one file, too. (Means I can keep an eye on it.) So it might not surprise you to hear that I'd vote for the code that uses the if statement :) - in fact, I don't really understand why the second would ever be preferable, outside some unlikely case specially engineered to prove me wrong.

I can pretty much promise you that at some point, you will find yourself wanting to debug one case, but not the other. If not this specific code, then some other code very much like it. If not you, then somebody else! But if the code is all on one line, how will you stop on one case and not the other? In every native debugger I've ever used, you can't. You need to split it into separate statements, so you can breakpoint each case separately. So in the long run, the code is very likely to be changed, so it'll probably end up the first way eventually. So why not just write it that way to start with?

("Ah, ah, but but, but have you heard of this thing called a conditional breakpoint?" - yes, I have, thank you.)

It's just not even funny to think about how much of my time this specific issue has wasted over the years :(

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

#100
post #42

> 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…

Considering how many languages these days completely eschew the header/body paradigm, I'm not sure that "head-only" programming is such an obvious mistake.

Such languages tend to be reasonably smart about what changes trigger large recompiles, and about not re-parsing the same lines of header-only code over for every compilation unit. In C++ the best you can hope is to set up precompiled headers and live with the artificial dependencies.
Post reply on HN