> Better to prototype and iterate.
Agreed. Version 1.0 is a glorified prototype anyway. Nothing about writing a spec prevents you from prototyping and iterating, though. These are not competing ideas.
Of course you won't get everything right in the first draft of the spec. You won't get everything right in the first release of your software either. That's not an excuse to stop trying.
Let's suppose you write a spec, then go on to write some code. For each design problem that makes you break from your original plans, one of two things is true:
(1) Someone noticed a problem while writing or reviewing the spec, and changed the design. You've saved a ton of time over implementing the wrong thing and then changing it later.
(2) You didn't notice the problem until implementation. It still takes just as long to fix as it would have if you hadn't bothered writing a spec first.
If #1 is common enough, writing the spec saves you time. At worst, #1 never happens and you're out the time it took to write the spec. But how long does that take? In my experience, it takes a lot less time to write a spec than to actually implement it.
There's a lot of potential upside and little potential downside.
I don't advocate Epic Design Up Front—at some point, it's time to stop planning and start doing. But I do advocate Some Design Up Front, as opposed to Let's Wing It And Hope For The Best.
> Software should be the spec.
Software is not a spec. It's written in computerspeak so only the programmers can read it, and sometimes they're not even completely sure what's going on. Without a spec, QA has nothing to test against, so you get into arguments about how things should work because there's no record of any decision on the matter. There's nothing to write documentation against, so the documentation ends up worthless. Sales and marketing make up all sorts of neat features you get to implement whether they make sense or not because they've already been sold, and you can't really say they should've known better because you never bothered to write down what they should know in the first place.
If all you have is code, you don't have a spec. Code is not a spec.