This really stood out for me. I'm always tempted, while writing something specific, to generalize it. I try to resist that, when I recognize it. Writing a ThingThatImWritingFramework risks ThingThatImWriting never seeing the light of day, or never being used.
People often think that projects get slower as code is added. However, the systems we work with are dramatically more complex and based on more pre-existing code than ever before. Because that pre-existing code has been generalised out, we can write new code easily and quickly.
There are two situations that you need to think about wrt to this issue (IMHO). If someone needs to do something that you have already done in your project, it should be simple and obvious how to do it. The more often something needs to be done, the more simple and obvious it needs to be. However, if someone needs to do something that hasn't been done before (even if it is is very much related to what already exists), then all doors should be open. The code should not imply how new work should be done. It definitely shouldn't try to guess what you want to do and do it before you get there.
<sarcasm> This could be written on the tombstone of JS. </sarcasm>
The article kind of already says this:
> Keep your code absolutely simple.
> Keep looking at your functions and figure out
> how you simplify further.Then maybe that programmer should go into teaching instead?
Too many projects suffer immensely because of people who don't give a shit about delivering. In that mode, anything is an excuse: we need to reactor, we need to build a better framework, we need to revisit the requirements, etc.
Then real progress gets slowed down because of some ill fitting development philosophy that some of those folks pulled out of their asses.
What you need are wise programmers that care about delivering product, wise enough to balance long term maintenability and code health with actual delivery schedule.
The keyword is "wise".
You once wrote something specific, and it was great. Then you had to write a second thing, and you remember things from the first, so why not make it more general for the inevitable 3rd, 4th, 5th to come? And, then, you fail to deliver the 2nd.
It's easy to confuse abstraction (choosing to deal with one, possibly newly contrived, concept over another) and generalization (reducing the number of concepts required to explain something to a minimum). The former is like building a Haswell CPU from a description of 70s microcontroller architecture, whereas the latter is like trying to figure out what CPUs were like in the 70s by looking at a Haswell core under a microscope.
The quote refers to a future product, one that is very likely unspecified at best, and more likely just something that an individual contributor dreamed up. Unless we have some sort of multi-phase contract, how do we know we'll ever build another thing like this again?
Markets change, hardware changes, experience changes. Hell, building this thing may show you that you should never build another one like it.
Generalize where sensible inside the project, sure. But as the quote says, build what you're building, not what you're not.
All abstractions have a cost and no abstraction is better than the wrong abstraction.
I found this talk on the topic very interesting https://youtu.be/4anAwXYqLG8
prefer duplication over the wrong abstraction ( https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstracti... )
Increasingly I try to find a strategy that transitions towards the generalization over time by following a path of "lower friction instead of greater friction." It's easy to increase friction by adding a new configuration step, new concepts and idioms that are discordant with the rest of the environment, and then the point of doing it gets lost - you don't want to pay for that overhead most of the time, you can't ship code that way.
Didn't someone say premature generalization is the root of all evil?
Sometimes the static array of factories contains a single factory. Creating a single item. No variation, no types, just one kind of one item.
The item is needed once. In one place.
A bit like the Wright brothers building a wind tunnel, so they could experiment quickly with control systems.
But Id wrote some great games, so maybe I'm missing how they handled this aspect...
It is easy to slide into an OCD mindset when programming, to make things tidy and proper. It feels dirty to make stuff just work, to make stuff disposable, but evolution operates a lot like this - many little, reversible mistakes that add up to big improvements quicker than any other method.
This one is also nice, especially for mid to large software houses. As long as a common denominator is respected, I guess.
These are achievements beyond belief.
I think, I heard him state in an interview that he also did a lot of development on Quake in addition to the levels. Obviously the graphics engine was Abrash and Carmack's
They just got on with it because they were talented experienced and motivated. For that reason, the rest of the talk is very inspiring - so listen to the hour-long video (half talk, half questions), and not the article which only has the post-hoc bits. https://youtu.be/E2MIpi8pIvY
Agreed and that's the whole secret sauce right there, combined with: no distractions (social media or indeed even "coding forums" with constant flame-wars on this and that language/stack/paradigm) and crucially also no distracting "stack" or APIs to speak of (bare metal coding literally "on top of the BIOS" in these days, no OS/GUI/multithread/GPU APIs).
The initial core team spent their entire youths 24/7 getting insanely good at ASM and C and numerous gfx tricks and then "they just played the piano" to the best of their accumulated abilities. Observe how much longer the Dooms took compared to Wolfenstein and priors, and how much longer the Quakes took them compared to the Dooms.. as they were slowly entering the age of Windows native & Internet multiplayer even they too got slowed down a bit (were shocked how for Quake "just waiting for 'ze engine' took a year"!) compared to the earlier works --- of course still managed to ship high-quality products, but still
I disagree with this so much, prototypes and proof of concepts teach you so much but usually they are crap you will always write it better a second time. Throw away the prototype and re-write it as a much better implementation.
No. You won't:
I remember Carmack building a prototype of the texturing system for Rage to see if it would all work, so maybe the prototyping was always just an implicit part of JC's programming.
You can build things to try out and experiment different modes of play or modes of rendering but the code you write should always be production ready. No taking shortcuts because "it's just a prototype".