The Cunningham & Cunningham Wiki is a wonderful place to get lost in, and it is so (chaotically) packed with useful programming lore that you are bound to come out of a dive a bit more enlightened about what it is programmers actually do.
One of my favorite pages is You Aren’t Gonna Need It from which I pull the following quotation:
Always implement things when you actually need them, never when you just foresee that you need them.
The justification for this is pretty straightforward: adding things you don’t need takes time and energy, plus generates more code, which means more potential bugs and cognitive load for future development. Since your job is to deliver software that actually does something which you presumably have at least a provisional understanding of, speculative development is an obvious waste of time.
To this basic justification I add only the following small elaboration: If you don’t need it now, you probably don’t understand it anyway. Anything you implement speculatively is very likely to be wrong as well as useless.
Why Software Is Hard
There are a lot of reasons software engineering is hard. Probably the primary reason it is hard is that we do not yet have a complete understanding of why it is so hard in the first place. Richard P Gabriel, a software philosopher and progenitor of the Worse is Better meme observes, probably correctly, that one reason for this fundamental ignorance is that software engineering is a comparative tyro among engineering disciplines: it is both extremely young (beginning only in 1945, approximately) and subject to radical change. A developer in 1945 would find the contemporary development environment utterly alien and vice versa, a state of affairs not afflicting, for instance, stone masons, who have, arguably, thousands of years of more or less dependable tradition to inform their work.
With characteristic insight, Dr Gabriel also observes that software engineering is also difficult because it isn’t physically constrained1, which means that humans, the product of 3.5 billion years of evolution in a physical environment, but not a computational one, have very little experience upon which to rely as they build objects in the space of computable functions.
Suffer me a brief, digressive analogy: Hyper Rogue III is a game which takes place in a two-dimensional hyperbolic plane. One implication of such a space is that it is very unlikely that a wanderer will ever return to a particular position unless she almost exactly follows her own trail of bread crumbs. Exploring the space of computable functions is similarly dangerous to wanderers, except more so: we are not well equipped to even identify the hills, valleys, walls and contours of this space.
Hence my elaboration: the wanderer in the landscape of programming is very likely to lose his way. He has neither physical constraints nor well developed intuition to guide him. And despite the existence of tools like git, which promise us the ability to backtrack and refactor with some confidence, software inevitably ossifies as it grows.
Hence my elaboration: you don’t build things you don’t need because, if you don’t need them, you probably don’t really understand what they should be. If you don’t understand what they should be, you’ll probably wander off base as you build them, and you probably won’t even notice that you have wandered off until something concrete impinges upon that code. When that happens, you might find that refactoring to solve the problem you have now is prohibitively difficult, because that feature you thought you would need has subtly impinged on other parts of your code.
Explicit, concrete requirements are the closest thing you have to the physical constraints which make stone masonry a more reliable discipline than software engineering, and nothing but rote experience will ever give you the physical intuition that stone masons can rely on.
So don’t wander off: You Aren’t Gonna Need It anyway. At least until you do.
1: Well, the relationship between the physical constraints on software and the software is, at any rate, not entirely trivial or transparent.