It doesn't have necessarily to be poorly written code though - you can start with lots of constant functions and later replace with actual logic, and still, at each iteration you'll have a complete testable flow.
Some test frameworks like Clojure's midje [1] and Python's mock [2] help a lot with this by making mocking functions inside the test painless, so you can start with what you wish you had and then fill the blanks.
I believe someone on the internet named this "Wishful Thinking Driven Development", quite ingenious.
[1] https://github.com/marick/Midje
[2] https://docs.python.org/dev/library/unittest.mock.html#the-p...
> Think of changing a tire: you screw in the lug nuts loosely first, in a star pattern. Once you have all the lug nuts in loosely, you tighten them a little bit at a time, going around in that star pattern, until they’re all tight.
It just doesn't work this way, the bad code stays there. I'd be a little concerned to take over software you wrote, because that tightening plan lives in your head and the issues are global, not local to some module.
You (author) are on the right track though, it's a good idea to have a reflex against perfectionism.
I read this differently. I didn't feel the author is saying the code is bad or "fast and dirty" to be cleaned up later so much as limited in features. Do limited features along the stack to get the whole toolchain in place before adding more features.
There's recent image with respect to UX which I think is relevant here https://twitter.com/jopas/status/515301088660959233
This is the kind of codebase I like to take on. Limited features = less code = less to refactor, and what is there is probably better tested and has fewer bugs. I get to writing new features myself instead of just fixing someone else's work.