John Carmack's comment on Doom 3's code style
21–30 of 210 posts
Re: John Carmack's comment on Doom 3's code style
#22Re: John Carmack's comment on Doom 3's code style
#23My 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."
John Carmack wrote a nice article about experiences writing functional code in C++ here: http://www.altdevblogaday.com/2012/04/26/functional-programm...
Re: John Carmack's comment on Doom 3's code style
#24As 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.
If instead, a variable is assigned to only when it is defined, you're moving (in a small way) towards functional programming.
Also, I often use scope just control the lifetime of a resource. These look like meaningless braces in the middle of a function to the uninitiated. It's RAII.
Re: John Carmack's comment on Doom 3's code style
#25As 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.
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-time error
// ...
}
Also: void poor_style()
{
up_front declarations;
also encourage;
this_ridiculous *block_style;
that_is a_royal_pain;
to maintain;
because_some_long_type inevitably;
screws_it up;
}Re: John Carmack's comment on Doom 3's code style
#26Earlier quoted context omitted.
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.
I was reading '21st Century C' (I strongly recommend it for anyone writing C on a regular basis), and the author also argued against declaring all the variables up front. I don't quite know why, but I had a very strong reaction against it. As far as best practices go, I would try to keep every function small enough that you can find all the stack variables easily. If the function gets too hairy, refactor it so you ca…
Re: John Carmack's comment on Doom 3's code style
#27I always resent doing it but I can see how if the body of the function is not declared in the header file, but instead the associated .cpp file, that an author can change it, without introducing a whole recompile overhead.
Writing code that may not be needed is bad, but it's a trade off vs. preventing other users writing code that depends on it when their code should not.
Re: John Carmack's comment on Doom 3's code style
#28http://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 communication protocols (well, outside of some very-specialized infrastructure teams), because there's one RPC system. There's one standardized naming system, and a mostly-standard logs format and method for analyzing logs. If you do batch computation, there're two solutions, and there're only a handful of different file formats and storage engines, certainly less than in the open-source world.
I think Rails and Django (and Lisp) discovered the same principle: if you get everybody writing their code & data files the same way, you can write tools to manipulate those files, and that saves you way more in productivity than trying to get the perfect file format.
Re: John Carmack's comment on Doom 3's code style
#29"I am a full const nazi nowadays, and I chide any programmer that doesn’t const every variable and parameter that can be." Immutability...one less thing to worry about.
Broadly, my feeling is that getting your own APIs (internal and external) to be const correct is important and worth the trouble. But don't jump through hoops to shoehorn the strategy into someone else's code where it isn't honored.
Re: John Carmack's comment on Doom 3's code style
#30What I find much harder is to write "beautiful" code at a higher level. The examples shown are mostly algorithms working with fundamental language features. My code tends to get ugly when integrating APIs from different sources with different conventions. I spend a lot of time checking return codes, mapping from one set of error codes to another. Sometimes it's hard to decide whether a return code has to be checked or whether I should assume, for efficiency, that all parameters I'm sending in or getting out are ok.
Other things that uglify my code: exception handling, locks or other concurrency artifacts, retry loops.