Occasionally - but recurringly - I face the following loop pattern problem:
CodeSnippet1
DO WHILE LoopCondition //LoopCondition depends on some pre-calculation from CodeSnippet1
CodeSnippet2 //CodeSnippet2 relies on LoopConditon=true
CodeSnippet1
LOOP
The problem I see here is the code duplication of CodeSnippet1.
At the first glance, it seems like I should move the condition to the end:
DO
CodeSnippet1
CodeSnippet2
LOOP WHILE LoopCondition
This won't work since CodeSnippet2 assumes LoopCondition=true. The next try would be:
DO
CodeSnippet1
IF LoopCondition THEN CodeSnippet2
LOOP WHILE LoopCondition
Again far from elegant.
In C-like programming languages, one can do the following:
while(complicated-expression-containing-CodeSnippet1-and-LoopCondition) {
CodeSnippet2
}
But
a) this can get difficult to understand and
b) not every programming language can perform arbitrary calculations, especially variable assigments, during evaluation of some loop condition.
Recently, I came up with the following way:
DO //endless loop
CodeSnippet1
IF NOT LoopCondition THEN EXIT LOOP
CodeSnippet2
LOOP
This tends to lead structured programming with loops ad absurdum / reminds me a bit of GoTo programming style.
My Question:
Are there (more or less) objective reasons to prefer one of the mentioned loop programming styles over the others?
EDIT:
I know in many occasions CodeSnippet1
together with LoopCondition
can be encapsulated in a function returning the loop condition, and we're done. I agree with that. But this does not hold in general. Above in b) I tried to hint at "variable assignments". Here in detail:
My favourite minimal but real-world example: Using a BufferedReader
in Java:
line = bufferedReader.readLine();
while(line != null) {
//CodeSnippet2
line = bufferedReader.readLine();
}
vs.
while((line = bufferedReader.readLine()) != null) {
//CodeSnippet2
}
Both variants are not satisfying. Factoring out (line = bufferedReader.readLine()) != null
into a function that returns a boolean has one new problem: How to retrieve line
? Using a global variable / class member just for this purpose?
CodeSnippet1
is hardly a problem if you shove it into a function.CodeSnippet1
and the loop condition. But I also don't see why the duplication of a single line is unsatisfying to you.