From: rgp@mpd.tandem.com (Ramon Pantin)
Newsgroups: comp.lang.c++
Subject: Re: Tiny proposal for named loops.
Date: 22 Aug 92 07:17:56 GMT
Organization: Tandem Computers, Micro-Products Division

In article <rmartin.714435942@dirac> rmartin@dirac.Rational.COM (Bob Martin) writes:
>
>IMHO breaks and continues should be avoided, not improved.  As you
>say, they are a form of goto.  Don't use them, except in case
>statements where you must :-( use break.

Pretty dogmatic huh?
I imagine that you only have one return statement at the end of
your functions (I'm not going to even ask you about gotos).

>State variables are preferable to breaks and continues.  Judicious use
>of them allows all loops and blocks to be exited at the same place.

So what?

>This benefit outweighs the disadvantage of using a flag.

You call that a benefit?

IMNSHO, each "state variable" that you invent to avoid using a
break, continue or return, when it is natural to do so, is just a
replacement for immediately expressing your intentions:

	- Break, I'm done with this loop, lets get out of it.
	- Continue, I'm done with this case, the code that follows
	  doesn't apply to this case, lets go to the next iteration.
	- Return, I'm done, lets get out of this function.

Instead your code saves in a state variable what your intentions are
Then your code "judiciously" proceeds to test these state variables in
the right places to avoid executing the code that should be skipped
because you are not really supposed to be there anyway.

A very SIMPLE example:
	a, b, c and d are arbitrary expressions (maybe with side effects),
	*_statements are arbitrary sequences of statements.

	/* C code, _just_ 1 break, 1 continue, 16 lines */
	while (a) {
		if (b) {
			b_true_statements;
			if (c) {
				c_true_statements;
				break;
			}
			c_false_statements;
			if (d) {
				d_true_statements;
				continue;
			}
			d_false_statements;
		}
		post_b_statements;
	}

	/*
	 * Pascaloid code, 2 state variables, 3 tests, 2 sets, 22 lines.
	 * Certainly the complexity (by any count!) "outweighs" that of
	 * the previous code.
	 */

	/*
	 * MAINTAINER NOTES:
	 * Loop exited in only one place. (So what?)
	 * Where the heck is this "done" set that causes this loop
	 * to be exited here?  As far as I'm concerned the loop is
	 * exited also where "done" is set (humm, that might not be
	 * true, some more code might execute after that assignemnt
	 * so I better watch for that also).  Rewrite this in C.
	 * Who was the Pascal programmer who wrote this messy code anyway?
	 * Lets send him for instruction to some C programming courses.
	 */
	done = 0;		/* judiciously introduce state variable */
	while (!done && a) {	/* j. test s. v. */
		skip = 0;	/* j. i. s. v. */
		if (b) {
			b_true_statements;
			if (c) {
				c_true_statements;
				done = 1;	/* j. set. s. v. */
			} else {
				c_false_statements;
				if (d) {
					d_true_statements;
					skip = 1;/* j. set. s. v. */
				} else {
					d_false_statements;
				}
			}
		}
		/*
		 * CAVEAT MAINTAINER: don't just simply add code here,
		 * read next caveat.
		 */
		if (!done || skip) {	/* j. test. s. v. */
			post_b_statements;
		}
		/*
		 * CAVEAT MAINTAINER: review the whole function before
		 * adding code here, code to be added to the end of the
		 * loop goes in the "if" above, otherwise the cases:
		 *	b && c
		 *	b && !c && d
		 * would be broken.
		 */
	}

Why do you think that most modern languages have things similar
to continue, break and multiple returns?  N. Wirth omited them
from Pascal to avoid programming students from going crazy
with the gotos before they learnt how to program (which explains
why some programmers that had early and continuous exposure to
BASIC seem to have had so many side effects from it :-).

I suggest that you try rewriting some of your code using breaks,
continues, and multiple returns, you might really like it!  :-)
You might also want to try some of those forbiden gotos.  As you
already know, there is a place for everything, and excess can hurt
you, so be carefull (specially with those handy gotos)!

>Robert Martin

Nothing personal Robert, I just couldn't resist!  :-)

Ramon Pantin