In fact, I would go so far as to say that, if in the design phase the precise structure of every single piece of what you are implementing, and the scope and feasibility of all alternatives, is known and crystal clear, then the project is trivial and probably does not need a design phase - you might as well just write the code.
The article makes this point as well: "a complete, abstract specification is, in general, at least as much work as creating the software itself"
Building software is usually more of a process than a plan. This is in contrast of traditional engineering where you absolutely need a rigid plan to build something like a bridge or a building. Of course reality is messy and no plan will be perfect
And often not, particularly when you are building a new system. And if you are replacing an existing system, the requirements that you discover are usually, "it must work exactly the same way as the old system."
"Part of", because there's the other part, which wasn't specified, and they just assumed there was only one possible answer, and so they didn't even realize that there was a gap in the spec there. But there is, and if someone, somewhere, makes the opposite assumption, the gap matters.
In reality, a loose spec is better than no spec. For example:
1. The loader should be able to parse an input file of up to 100MB in under 1 second.
2. The loader should support XYZ files version 3, 3.2, 3.3, and 4.0.
3. The loader should validate and reject erroneously formatted files.
4. The application should store internal state in robust storage that is independently inspectable.
5. The UI should be able to function if the backend database is down for less than 3 hours.
If you can't write ~1 page of such high-level requirements, why would you expect that you could start writing code? But we do. I mean, even I do!
But I think where the disagreement comes is in the difference between requirements and specification. The example you gave is, in my view, not a spec at all, just requirements.
Take item 4: That could mean anything. It could mean a SQL database with a published schema, or it could mean a 1 GB file on disk that I can view in a hex editor. (The file probably can't be in /tmp though, because you said "robust".)
So people try to make the requirements more specific, so that they "specify" exactly what the software does. And that's where my previous comment comes in - you can't make it specific enough to answer all the questions. Which was one of the points of the article.
> The only way to know exactly what software we want to build is to fully specify it: without doing so, there will be gaps between our vague ideas and harsh reality. However, a complete, abstract specification is, in general, at least as much work as creating the software itself — in many cases, it is substantially more work.
Well, there is a way to do this: it's called requirements. There's a whole subfield of Software Engineering called Requirements Engineering that deals with exactly this. The fact that we don't stop to write down even a one page description with bullet points of what software should do is damning as a field.
We'd instead rather just jump right in and then later spend hours, days, weeks, months, even years later refactoring the wrong thing we started with, or banging on it with a hammer every time a new (often anticipatable) requirement seems to appear.
Sure, software development is a young field, but it will never mature if we constantly ignore and even forget the basics.