[net.lang.c] "Break" and other ways out of loops and switches

cscussel@ihuxq.UUCP (08/23/83)

The recent article asking why "break" replaced "endcase" reminded me of the
following. A high school student (!) that I help with his compiler over
occassional lunch hours came up with what I think is a super way out of
the multiple-level or multiple-construct break problem (i.e., breaking
out to the "right" level (the one you want)). He suggested labelling the
initial statement of the construct to be "broken" (e.g., the "for" statement)
and then giving the label as an "argument" to break. This binds the break
to the construct that it's suppossed to break, even if intervening code
is deleted or added. It's reminiscent of the way some people comment
their code (e.g., break; /* end scan */ becomes  break scan ; ). 
This idea was original with this student, although I've since found out
that other languages (such as BLISS) have this feature. I think that
it's great, would be relatively easy to add to compiler (I think),
and is even compatible with the current C. Multiple-level breaks are
a common reason for seeing one of those rare goto's in modern code.
This feature would eliminate the need those occurrances. Well,
what do do you think, yea or nay?

				Chris Scussel
				Bell Labs
				Naperville, Illinois
				ihuxq!cscussel

dce@tekecs.UUCP (David Elliott) (08/24/83)

I believe that PL/I has the LEAVE statement which takes an optional
label. This would be equivalent to the 'break scan' type of
construct. This can be very useful when you are not allowed to
use GOTOs without writing a five-page paper explaining why you
needed to use a GOTO.

			David

chongo@nsc.uucp (Curt Noll) (08/24/83)

>	...  A high school student (!) that I help with his compiler over
>	occassional lunch hours came up with what I think is a super way out of
>	the multiple-level or multiple-construct break problem (i.e., breaking
>	out to the "right" level (the one you want)). He suggested labelling the
>	initial statement of the construct to be "broken" ... and then giving
>	the label as an "argument" to break.
>	... other languages (such as BLISS) have this feature. I think that
>	it's great, would be relatively easy to add to compiler (I think),
>	and is even compatible with the current C. Multiple-level breaks are
>	a common reason for seeing one of those rare goto's in modern code.
>	This feature would eliminate the need those occurrances. Well,
>	what do do you think, yea or nay?
>	
>					Chris Scussel Bell Labs

i say NAY to the high school suggestion regarding labeled multi-break.
what that would do is to create another quasi-goto, and another
way for obscene code to be created.

try:
/* more or less minus possible typos */
#define TRUE 1
#define FALSE 0
#define breakout( breakflag ) if ( breakflag ) { break; }
#define multibreak( breakflag ) breakflag = TRUE; break
#define setbreak( breakflag ) breakflag = FALSE
#define testbreak( breakflag ) ! breakflag
#typedef unsigned char BREAKFLAG
...
	BREAKFLAG stopreading;	/* read process termination */
	...

	/* read lines of text ... */
	for ( setbreak( stopreading );  some-code;
	    some-code && testbreak( stopreading ) ) {
		...

		/* character in line processing */
		while ( some-code && testbreak( stopreading ) ) {
			...

			/* case in char in a line */
			switch ( some-code ) {
			...
			case SOMETHING:
				...

				multibreak( stopreading ); /* stop reading */
				break;			/* for readability */
			...
			}
			breakout( stopreading );	/* termiate loop */
		}
		breakout( stopreading );	/* terminate loop */
	}

any number of ways can be constructed in C to do similar things.

chongo /\../\

crandell@ut-sally.UUCP (08/25/83)

     I cast a strong vote in favor of that proposition.  Incidentally, if
you're interested in discovering another language (a small and very
orderly one) that incorporates that feature, look at REPORT ON THE
PROGRAMMING LANGUAGE PLZ/SYS by Snook, Bass, Roberts, Nahapetian and Fay
(Springer-Verlag, 1978).  You'll probably notice that PLZ/SYS doesn't
have a GOTO, and the loop-break statement EXIT (probably from DEC Pascal)
plus the RETURN statement (from FORTRAN -- no, it's not the same as the
C version) have substantially obviated it.
     It seems reasonable that loop labels are somewhat "safer" than
statement labels, since they are more difficult to dislocate.  I haven't
heard any Certified Programming Moralists rule on it, however.

asente@decwrl.UUCP (Paul Asente) (08/25/83)

The solution with breakflags & setbreaks & testbreaks is
cleaner than one with labelled breaks and continues?  Give
me a break! (Ug)  Labelled breaks and continues are infinitely
cleaner than that tangled mess of flags.  The advantage of
structured over unstructured programming is that structured
programming is easier to understand and follow, not that it
has no gotos.  The effect of a goto is not necessarily bad if
it is to the end of a loop or the end of a procedure.  (Do you
object to multiple "return"s in a procedure?  It's really the
same thing.)

	-paul asente

jsq@ut-sally.UUCP (08/26/83)

If you only permit the labels for multi-level breaks to label blocks,
you have a mechanism that does away with the last excuse for using
gotos, and is much cleaner than the preprocessor kludge you advocate.
-- 
John Quarterman
{ihnp4,ut-ngp}!ut-sally!jsq, jsq@utexas-780.ARPA (soon to be jsq@ut-sally.ARPA)

wilner@pegasus.UUCP (08/26/83)

The Burroughs systems implementation language SDL done in 1970
had a parameter on its "break" (nee "undo") statement that specified
how many levels up to break.  It was used rarely, mostly for error
recovery, and was very welcome.  I regret C does not use the elegant 
"loop { ... break ... }" for control constructs.

mat@hou5e.UUCP (08/27/83)

	If you only permit the labels for multi-level breaks to label blocks,
	you have a mechanism that does away with the last excuse for using
	gotos, and is much cleaner than the preprocessor kludge you advocate.

FLAME ON!

	Goto's are not INHERENTLY evil (I hope MR. Djikstra is reading this!).
Goto's are bad because they require discipline in use and because more
disciplined constructs reflect well the structure of MOST problems and,
therefor, are appropriate for MOST programming.  There are some problems
that are not clearly written this way.  A few problems look like finite
state automata.  They CAN be written as loops containing switches and
diddling with state variables.  This is an unnatural solution, however,
and usually error-prone.  It is usually better to write the program
like the problem.

	A word on program state variables:  FORTRAN provides the ASSIGN
statement, which is almost tailor-made to the uses of state variables.  Yet
we seem to have little good use made of the ASSIGN.  Why?  Could it be
because state variables are a bad thing?

					Mark Terribile
					Duke of deNet

henry@utzoo.UUCP (Henry Spencer) (08/28/83)

I take a somewhat different approach to the argument about whether
it's better to use flags or "break n" to get out of multiple control
structures.  It does happen sometimes that I am in the middle of
multiple nested control structures and I want to get out several levels.
When this happens to me, I have learned to think:  "Stop!  This nesting
is too complex!  Break some of it out into subsidiary functions!".  The
result invariably seems to be cleaner, simpler code.  This has all the
obvious useful side effects, like less debugging and easier changes
later on.

In short, it doesn't matter what the answer is if you're asking
the wrong question.  Procedures are the most important control structure
in almost any programming language, and the most under-rated.  How many
times have you heard people complain about the logic of a procedure
being too complex?  Have you *ever* heard people complain about a
procedure being too simple?

I don't say that better decomposition into procedures ("functions"
in C) will solve all control-structure problems.  But my own experience
suggests that it will solve a lot of them, to the point where I am
continually unhappy that our beloved schools don't do a better job
of teaching it.  (My opinion is that procedures should be taught before
loops and before ifs and even before assignment statements -- they are
that important and that fundamental.)

If you object that it's inefficient to do this because of C's call
overhead, I suggest you listen more carefully to what you are saying.
Personally, I find it much easier to make a working program more
efficient than to try to debug an "efficient" ball of hair.  Plus
I don't have to do it as often, since the "inefficient" approach
often turns out to be good enough anyway.

More generally, I find it useful to listen very carefully for that
little voice that says "Stop!  It's too complex!  You're starting
to have trouble keeping track of it all!  Rethink it, now, before
you type another line!"  The more listening I do, the more I break
things down into the simplest functions I can think of.  My code is
better for it, and it's been years since I had any interest in using
a goto.  (Note, not "years since I used a goto", but "years since I
wanted to use one".  The difference is important.)
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry