Live data from Hacker News

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

kotaku.com

31–40 of 210 posts

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

#31
I am also a const nazi, and occasionally find myself trying to imitate some of its uses elegantly through run time errors or strict naming conventions in other languages. I do understand why many other languages decided not to support it though. There's definitely a few times I've coded myself into a corner and ended up with "const spaghetti", having to do a const_cast or two to free myself and make a deadline.

The article makes it sound a little like you can just slap const everywhere and your code will be better. It does take more time and effort to be const correct, although it's usually worth it.

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

#32

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

you can find all the stack variables easily

You can't do that unless you look at the assembly output. While there may have once been a time in history where "locally-scoped variable == entry on stack", those days are long gone. Any decently smart compiler (i.e. GCC and LLVM) will use registers in preference to the stack, and will collapse local variables whose lifetimes do not overlap into a single storage location.

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

#33

Earlier quoted context omitted.

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…

you can find all the stack variables easily You can't do that unless you look at the assembly output. While there may have once been a time in history where "locally-scoped variable == entry on stack", those days are long gone. Any decently smart compiler (i.e. GCC and LLVM) will use registers in preference to the stack, and will collapse local variables whose lifetimes do not overlap into a single storage location.

My bad, I meant locally scoped, I tend to think in terms of "it's on the stack (or a register), or it's on the heap (because it's been malloc'd and needs to be freed)". I do need to review my terminology...

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

#34

Earlier quoted context omitted.

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…

I don't see any advantages of declaring variables up front. Not all variables should be at the function scope. Often I have a local variable that is only used inside one branch of a conditional, why should I declare that at the top? Declaring things up front also separates the type from the usage, which makes things harder to read and takes up twice as many lines in some cases.

Maybe I miscommunicated; I'm not against declaring variables at scopes smaller than the function - I declare variables at the top of conditional branches as well. I still don't buy the 'twice as many lines' reason for mixing assignment and declaration.

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

#35
post #10

Earlier quoted context omitted.

The key is to have self documenting code, not undocumented code. If you create functions that do only a single thing, with their purpose fully described by their method signature then you don't need comments - the method itself explains exactly what it does. The author makes a good point that comments are just more text that you need to maintain, and whenever you make changes you now have to make changes in two place…

Oh, I get the concept. I've just been doing this for a while and see it fall part constantly. The problem is always that what is clear to you isn't clear to everyone else, including yourself somewhere down the road. And decomposing everything to atoms tends to lead to a mess of indirection. Clarity can usually be addressed with longer variable or method names, but there's a strong culture against that in nearly ever…

> Clarity can usually be addressed with longer variable or method names, but there's a strong culture against that in nearly ever programming community.

It would be interesting to see a list of those that discourage long method and variable names. I haven't seen anything that suggests that Java, Ruby, Python, Haskell, Kotlin, Scala, PHP, Groovy etc. discourage long variable and method names.

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

#36
post #21

I guess Carmack would be a big fan of Rust which essentially borrows lots from Haskell, OCaml, C++ and Erlang while being native, safe and on-par in terms of speed with idiomatic C++.

On the Quakecon where he talks about static code analysis, he mentions that ML languages are too much for games developers, given the usual skill set.

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

#37
"I mistrusted templates for many years, and still use them with restraint, but I eventually decided I liked strong typing more than I disliked weird code in headers."

I never liked templates myself, and still avoid them almost completely. Even if my reasons are ridiculous, here they are:

1) I typically don't use anything where I don't understand its inner workings (i.e. how it manages memory, how the compiler is likely to optimize it). This does not mean the entity in question is bad, it just means I'm too lazy to learn about it on a deeper level.

2) In most cases where I need to handle a diverse amount of operations and a diverse amount of data types, it is not CPU-critical and I can resort to a higher level scripting language that is much better suited for the purpose.

3) Template syntax does not sit well with me. This is really just an OCD on my end.

4) I often prefer using uber-types (all-encompassing) to many different types -- within reason. I don't like to extend classes for this reason (particularly when you get into extension-hell with 5 different sub types).

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

#38

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

Bear in mind that the person making the comments you quoted is not actually John Carmack, who I will agree is a "guru". Carmack's own comments later indicate that the style represented in Doom 3 is an intermediate point in his personal evolution. Indeed, this style was a common one 10+ years ago and may have been appropriate for the less reliable compilers and buggier STL implementations of the day. It's certainly still popular with many programmers, though, as you imply in your last sentence...

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

#39

"I mistrusted templates for many years, and still use them with restraint, but I eventually decided I liked strong typing more than I disliked weird code in headers." I never liked templates myself, and still avoid them almost completely. Even if my reasons are ridiculous, here they are: 1) I typically don't use anything where I don't understand its inner workings (i.e. how it manages memory, how the compiler is like…

I'd say 1-3 are perfectly reasonable. If you want to get good, put in the time and you will be rewarded, but that's really a choice.

#4... I think that might make a lot of sense with a weak or dynamic type system, but with a static type system there is a lot of benefit to having a different type anytime the behaviour is different. Of course, that can be tedious unless you have templates or at least generics...

Post reply on HN