I would like to submit a humble plea in defence of the Spec, a sadly endangered creature whose passing would make us all poorer.
In the bad old days, you had an Analyst who talked to the User and wrote the Spec, and a Programmer who read the Spec and wrote the program. Nowadays the Programmer is allowed to talk to the User and write the program, and you cut out the wasteful back of a fag packet. I suspect that this change was really brought about by the demise of the cigarette as an essential aid to programming. The Programmer is now called an Analyst-Programmer, and the Analyst is now called a Manager and spends all his or her time writing reports for the people who justify their existence by reading reports.
In my early days as a Programmer, the Analyst told me exactly what to write. I was told to write loops that never ended, code that was never executed, and to 'goto the processing described in paragraph 126.96.36.199.' Of course, I never did anything so silly. Most of the time I worked out instead what the User wanted, and did that.
The basic problem with the Specs I was given to work with is that they were not, as I understand it, Specs at all. They were pseudo-code, written by somebody who had never been trained to write code and who had never sat up at night debugging programs that had been poorly designed. They never had to suffer the mistakes in their work, so of course they never learned. Enter the Analyst-Programmer, exit the Analyst, and good riddance.
But hold on. In two years' time, when someone wants the program changed, what happens? You go back to the code to try to find out what the program does. And in the code you find, because the Standards say the code must be 'documented', and the programmer did a good job, lots of lines like this:
fred=fred+1 ** Add one to fred
Great! You really know that fred wants to be incremented at this point. But you haven't the faintest idea why. Possibly the programmer didn't know why. 'The Spec said increment it, so I incremented it.' One of the best specs I ever had (and there were many) initialised something like 'pgno' to one in three places (one of which could never be reached), and incremented it in about a dozen other places. It was printed at random on various lines of the report. Eventually I worked out the User wanted each page numbered.
If I had done what the Spec said, who would have been at fault? I was only carrying out orders (heard that one before, somewhere...) The Analyst might have been mistaken, but they did check it out with the User, and the User had signed in blood. So of course it is the User's fault for not saying what they wanted. Rubbish! The system was at fault for asking the impossible of the people involved. The User can't be expected to wade through dozens (if not hundreds) of pages of technical gobbledegook, let alone understand it. The Analyst can't be expected to write pseudo-code the User will understand, and the Programmer can't be expected to correct errors when they don't have any idea what the system is supposed to achieve.
What is a Spec? It is a specification - or statement - or the User's requirements. It should state clearly an unambiguously WHAT the program is to achieve. The criteria for success, if you like. The User will be happy if the system does this, and takes this long to do it. It should contain no technical details because the User is simply not interested in them.
The job of the Analyst is simply to understand and document the User's needs - or the part of them being addressed - and describe clearly not what they ask for, but what will make their life better for a reasonable cost.
Once the Programmer knows what the User wants, there is usually not much problem in working out the best way of achieving it. Only the Programmer has the specific knowledge of the hardware, the operating system and the language to design for robustness and efficiency. Only the Analyst has sufficient knowledge of the business to ensure that the system makes sense in the real world. The two roles are quite distinct, even when they are carried out by the same person. And when they are carried out by the same person, it is even more important that between them comes the Spec for the User to understand and the Programmer to satisfy.
There is one more role for the humble Spec. As well as saying WHAT the system is to achieve, it should go some way to saying WHY it is to be achieved in this way. Not in terms of the program's innards - neither the Analyst nor the User is interested in those - but in terms of the business decisions made while producing the Spec.
The Spec should document some of the rationale behind the decisions. Yes, the system could do that as well, but it would be very expensive and only of potential benefit in about 5% of cases. This functionality was left out due to lack of time or money, but could be added later. That functionality was left out because it doesn't belong in this area and would seriously compromise the reliability and maintainability of the entire system if it was added.
There is an element of CYA about this, of course. But how many times does a Programmer look at someone else's work and think 'What beautiful code!'? How many times does an Analyst look at a system and think, 'I haven't spent as long as the original Analyst did on this project, I'm sure there is a good reason for it all.' No - they think 'What a dreadful mess! I'm glad I'm not responsible, and I wish I didn't have to clear it up.'
To put it another way, you look at a system and fail to understand why it was built like this. Do you blame your lack of comprehension (a) on a poor grasp of the business issues involved, or (b) on the incompetence of the Analyst who has now left?
The only way anyone can be expected to maintain your system is if they understand the reasoning behind your design decisions. Circumstances change, and perhaps the original justification no longer holds water. You cannot tell if the reason is left undocumented. And, far more frequently, the factors which influenced the original design continue to be important as the system is enhanced and modified, and changes which ignore those factors will introduce problems to plague successive generations of Programmers who are always told to do a quick fix.
Of course systems grow old, but they can, with care, grow old gracefully. Document your systems: produce a Spec which says WHAT is to be achieved and WHY. You owe it to posterity, even if you don't care about your reputation after you have gone.