That reminds me of an old adage from a former colleague back at H.P. He said start with the null program, and debug it until it does what you want. :)
I do concur with the author's point (3), where he recommends starting with the high-level syntactic forms and fill them out from the top down.
That has more uses than merely preventing syntax errors. I also use it for case-driven development. Often I'll write a routine with this sort of inner dialogue: OK, there are only two cases here. Let me write an "if" for that. Now I'm not quite sure what to do in case 2, so let me focus on the easier case 1. Now here I need to do a three-way comparison of these two strings. OK, the less-than and greater-than cases are easy -- I'll go ahead and do those. The equals case is a little harder. Tell ya what, I'll get to that one later. Meantime, let me go back and address the top-level case 2, because I think I have a bead on that one now.
That sort of thing. And of course, as I go, I develop a test input for each case I've developed.
Also, in those postponed cases, I like to insert a "die" or "abort". That way when I develop a new test input for it, I'll know I'm hitting it because the program will die. Then I can punch into that case and make it handle my new test scenario. I know when I'm done because the code doesn't say "die" anymore -- except when I really do want to assert the impossibility of a certain condition.
I do concur with the author's point (3), where he recommends starting with the high-level syntactic forms and fill them out from the top down.
That has more uses than merely preventing syntax errors. I also use it for case-driven development. Often I'll write a routine with this sort of inner dialogue: OK, there are only two cases here. Let me write an "if" for that. Now I'm not quite sure what to do in case 2, so let me focus on the easier case 1. Now here I need to do a three-way comparison of these two strings. OK, the less-than and greater-than cases are easy -- I'll go ahead and do those. The equals case is a little harder. Tell ya what, I'll get to that one later. Meantime, let me go back and address the top-level case 2, because I think I have a bead on that one now.
That sort of thing. And of course, as I go, I develop a test input for each case I've developed.
Also, in those postponed cases, I like to insert a "die" or "abort". That way when I develop a new test input for it, I'll know I'm hitting it because the program will die. Then I can punch into that case and make it handle my new test scenario. I know when I'm done because the code doesn't say "die" anymore -- except when I really do want to assert the impossibility of a certain condition.