Whenever I work on some fairly significant piece of code, often I find that the I go through a phase of high level designing (aside: I like to use pencil and paper for this), followed by mental walkthroughs to highlight flaws and make refinements.
I see coding as another level (and finest grained) of mental walkthrough - you have to consider and cover every eventuality and this often results in further refinement of the design. Usually I find at the end of the process that enough has been learned that if I were designing and writing the code again there are things I could do better. And some of those things are perhaps too 'baked in' to the structure of the code to warrant spending the time to make the changes.
It often seems to me that in an ideal world I would always plan to go through the above process with the intention of using it as a learning process, and to plan to rewrite. Noting that much of the nuts and bolts of the code (e.g. low level subroutines) will be re-usable, so it's not a full bottom up re-write.