Right; but the problem is that you usually don’t really understand what you’re building until you’re halfway through building it. Specs inform code, and code also needs to inform the spec. Both because we learn more about how it will be used, and because there’s usually a clean, simple, straightforward way you can build something that won’t exactly match up to feature list in front of you.
Worse, I never seem to get those abstractions quite right until I’ve gotten them wrong a few times. If you don’t take the time to iterate and build some knowledge of the solution space, anything you make will be a bit of a buggy, fragile mess.
And I think it’s much easier (and more efficient) to do that iteration during development than spend years building something messy and then try and remake it from scratch, cleaner, later. But that means it takes more time to get to market, and that’s a really hard pill to swallow (for good reason).