This question was inspired by How to transform a flow chart into an implementation? which asks about ways of algorithmically eliminating the goto
statement from code. The answer to the general problem is described in this scientific paper.
I have implemented some code following the high-level sketch of Algorithm X from Knuth's The art of computer programming describing the generation of Lexicographic permutations with restricted prefixes (see p. 16 of this draft).
This is the corresponding flow chart of the above algorithm.
This might be a very clever and very efficient algorithm, but the structure of the code seems to be challenging to follow. I ended up using the good old goto
-style implementation:
//Algorithm X;
1:
initialize();
2:
enter_level(k);
3:
set(a[k],q);
if(test() == ok) {
if (k == n) {
visit();
goto 6;
}
goto 4;
}
goto 5;
4:
increase(k);
goto 2;
5:
increasev2(a[k]);
if (q != 0) {
goto 3;
}
6:
decrease(k);
if (k==0) {
goto 7;
}
set(p,u_k);
goto 5;
7:
return;
The question is: how can this code be refactored to eliminate all the goto
calls?
One (bogus) answer is a suggestion to "look up the cited scientific paper, and follow it line by line" - indeed, that is certainly a possibility. But this question is about what experienced programmers see instantly once they give a glance at this spaghetti code.
I am interested in the how of refactoring, step by step, more than just the code.
Note:
- It is straightforward to actually implement Algorithm X based on its high-level specification and
goto
jumps. Implementing the black-box functionsinitialize()
etc. would take only a few extra instructions, but those are irrelevant regarding the structure of the code. It is not important what is happening during the function calls, as the focus is now on the flow of the program. - The usual debate of "is GOTO still considered harmful?" is absolutely irrelevant regarding this question, and should not be addressed at all in the answers and in the comments.
goto
s... right? Or just how to do the first algorithm withoutgoto
s? – Chondruleif (k==n)
byif (an alien race attacks Earth)
or with whatever else you want. Such a statement will then be transformed in the refactored code to awhile(!an alien race attacks Earth)
. This goes to all other variables. – Hagiographagoto
s, right? – Chondrule