My first experiences with programming were laboriously copying reams of mysterious incantations, codes, and passphrases from multivarious magazines and books, then running the results and hoping against hope that I hadn't made any mistakes. When something didn't work I knew I was in for an even more laborious session of poring through all that source code looking for typos. (I never thought about it then, but now I wonder who tested those apps. All of us readers, mayhap. <g/>) No debugger for Basic on my Apple //e -- at least, none I knew about. Not that it would have made much difference; I understood Basic well enough to write my own simple programs that converted temperatures and the like, but the peeks and pokes and other fancy things in which the programs I copied in reveled were far beyond my ken. (Although, who knows -- a debugger might have helped quite a bit in that arena. Years later I discovered a poster that explained what data all those memory locations that were being peeked and poked stored. Going through a program I had saved, I found the gibberish magically transformed into sensical commands. Of course I had a bit more experience by then too. <g/>)
Fast forward to college. I had still managed to miss out on any formal CS training (why do architects need to program anyway), and I still had that Apple //e (albeit now with a dot matrix printer rather than a daisy wheel). Nevertheless I turned a summer internship at a Chicago bank entering as-built drawings into their CAD system (which task is exactly what it sounds like: survey a floor and record what furniture is where, then go back to the CAD room and update the appropriate floorplan so that it reflects the as-built condition) into an as-much-time-as-I-can-squeeze-into-my-schedule job administering and customizing said CAD system -- i.e. a little bit of running tape backups and a lot of programming.
Program I did, fast and furious and non-stop. My manager was amazed at how much code flowed out of my fingers in how little time. Just give me a problem to solve and BAM! five minutes later I had an app or script or macro for you. If it wasn't quite what you wanted, or was a bit buggy, well, no big deal; a couple more minutes and I'd have a new version for you.
It takes me a lot longer these days to get from problem description to the point where I'm ready to start coding. The total time from spec to finished product is probably less, though. It took longer than my boss probably would have liked, but I did eventually come to understand the value gained from thinking about the problem a bit, sketching out some architecture and program flow, and letting that subconscious mull things over awhile before strapping on my coding leathers and entering code land.
Fast forward another decade-plus-change. Now I'm the one trying to convince the younger coders on my team that spending time at the start thinking and designing will save time (not to mention produce a much better app) over launching straightaway into coding. Yes, it's great that you built the whole app last night. But do you know whether the problem you solved is the problem we really have? Did you think about this and this and this? No? Oh look, that invalidates half of your solution.
The problem with pondering time -- from management's point of view, anyway -- is that it's incredibly hard to manage that time. There's no telling how long it will take, oftentimes. Not to mention that your boss can't tell the difference between you going over a design in your head and you debating which movie to see tomorrow night! <g/> And of course calculating its ROI is nearly impossible -- can you tell how much longer your project would have gone if you hadn't taken that thought time first? "Way longer" isn't the precise time span management is usually looking for.
Another problem is that coding is just plain fun, and when you're in the flow alongside your code it can be bloody hard to pull yourself out and up onto the bank for some thinking and design. Test First Design really helps here by setting clear bounds on the amount of code you can write -- when you can only code until your tests pass you have built in "stop coding now and think a bit" breakpoints -- but all it really takes is a little discipline (OK, a lot of discipline <g/>).
How to beat this speed trap? Build up history proving it really is a trap. Every time I take an iterative approach cycling between little bits of pondering, little bits of design, little bits of coding, and little bits of testing (not necessarily in that order) I always end up (so far, anyway) with a robust design that solves the problem in a simple and elegant fashion. When I don't, it doesn't. So I'm building up that history for myself. The more times I'm able to convince management that slow and steady wins the race (to counterfeit a phrase) -- and then follow through on my claims [he says sardonically] -- the more they will come to believe and the less I will need to convince. A while of that and...Ho! Utopia comes! <g/>
*** Comments, questions, feedback? Want a fun job on a great team? Send two coding samples and an explanation of why you chose them, and of course your resume, to me at michhu at microsoft dot com. I need testers, and my team needs a data binding developer, program managers, and a product manager. Great coding skills required for all positions.