In this example, we write a short program to copy a file while prepending two characters
"| "to every line. Here, is pseudocode for one possible approach:
read Ch
WHILE Ch != END_OF_FILE DO
IF Ch = END_OF_LINE THEN
write Ch
read Ch
IF Ch != END_OF_FILE THEN
write "| "
FI
ELSE
write Ch
read Ch
FI
END
This code is fallacious. How easily can you see why?
Once you have seen why, you might be tempted to solve the problem by adding
write "| "
to the beginning of the pseudocode. This isn't a good idea for two reasons. First, it won't properly handle the case in which the input file is empty. Second, it perpetuates the real problem which is that the single loop structure does not match what the program is supposed to do.
Since the program copies lines and takes an action for each line copied, it is quite clear that line-by-line processing is natural. Pseudocode that uses line-by-line processing is:
read Line
WHILE Line was input DO
process and write Line
read Line
END
or -- depending on your language's i/o paradigm -- like this:
WHILE there is more input DO
read Line
process and write Line
END
From this pseudocode you might well choose to use library functions for reading and writing lines. Here is the solution using the second i/o paradigm:
WHILE there is more input DO
read_line LINE
write "| "
write_line LINE
END
Isn't the correctness of this code easy to see at a glance?
Because read_line and write_line are easy to use and because they are readily available, they would make it easier for you if you need to switch from one of these two i/o paradigms to the other at some future date. However, in an object-oriented world you can easily fake one paradigm with the other so the possibility of having to make the switch at some future date need not carry much weight.
If tight code is important, you will not want to use these subprograms. That, however, is no excuse for not using loops in a natural way. Here is an example using the first i/o paradigm.
read Ch
WHILE Ch != END_OF_FILE DO
write "| "
REPEAT
write Ch
read Ch
UNTIL Ch = END_OF_FILE OR Ch = END_OF_LINE
END
Here, the inside loop can be said to "copy the line" and the correctness of the program is easier to see than the incorrectness of the first version -- even though this version uses nested loops while that version does not.
It requires some thought to create inner loops that match the natural logic of what you are doing. Your solution will depend somewhat on your other goals. The payoff, however, comes when you have to check whether you have written a correct program. This payoff may seem small with a small example. Taking the same kind of care with a large program, however, pays a large dividend. Copyright and Permissions
This tip is distributed to individuals free of charge from the Internet Themes web site. All other distribution (including but not limited to internal distribution within an organization and mirroring of any kind) is forbidden without written consent of the copyright holder.
Return top of this document.