[comp.lang.c] do...while vs. repeat...until

karl@haddock.ima.isc.com (Karl Heuer) (03/16/90)

In article <5819.25f7a840@vax1.tcd.ie> cbuckley@vax1.tcd.ie writes:
>In article <Mar.7.10.43.42.1990.17402@paul.rutgers.edu>, emuleomo@paul.rutgers.edu (Emuleomo) writes:
>> The other less serious flaw in C is the do...while contruct.
>> I kind of prefer PASCAL's repeat....until construct myself.
>
>How can this be a flaw? The two constructs are identical except for the fact
>that the condition is reversed...

That's enough to make it a (minor) flaw.  Judging from my own personal
experience, it is more natural for a test-at-top loop to specify the condition
for continuing (while), but for a test-at-bottom loop to specify the condition
for terminating (until).  I don't know if there's been a study on this; in
fact, I'm not entirely sure how to formalize the concept.

And no, I did *not* learn Pascal before C.  At worst, my opinion may be
slightly polluted from Ratfor; but I believe there's a sense in which
repeat...until is really better.

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint
Followups to comp.lang.misc.

gary@hpavla.AVO.HP.COM (Gary Jackoway) (03/17/90)

Karl Heuer writes:

> Judging from my own personal
> experience, it is more natural for a test-at-top loop to specify the condition
> for continuing (while), but for a test-at-bottom loop to specify the condition
> for terminating (until).  I don't know if there's been a study on this; in
> fact, I'm not entirely sure how to formalize the concept.

----------

Bah, humbug.
It is clearly more consistent to have while..do and do..while where the
sense of the test works the same, than while..do and repeat..until
where the sense of the test changes.  If nothing else, when someone converts
one form into the other, the likelihood of error is significantly reduced.
And it seems to come up frequently that one has to change the test from
the beginning to the end of the loop. (And vice-versa.)

Gary "and I learned Pascal before C" Jackoway

peter@ficc.uu.net (Peter da Silva) (03/19/90)

The only sense in which repeat...until is more natural than do...while is
if you're an assembly programmer or compiler writer. In that case they
both use tests that code to:

	expr	ession,that
	eval	uates,to
	a	true
	or	false,value

	bzero	label

which means you can save a single argument to your "generate-conditional-
branch" subroutine. Wow.
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

ejp@bohra.cpg.oz (Esmond Pitt) (03/19/90)

In article <OVB2S3Bxds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>The only sense in which repeat...until is more natural than do...while is

etc etc.

There is a further significant difference between the Pascal
repeat..until and the 'C' do..while. In Pascal, 'repeat..until'
delimits a statement-list, not a single statement as in 'C'.

Otherwise you would have to begin a multi-statement 'repeat..until'
with 'repeat begin', and end it with 'end until'. There is no formal
need for such redundancy.


-- 
Esmond Pitt, Computer Power Group
ejp@bohra.cpg.oz

peter@ficc.uu.net (Peter da Silva) (03/20/90)

In article <383@bohra.cpg.oz>, ejp@bohra.cpg.oz (Esmond Pitt) writes:
> In article <OVB2S3Bxds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
> >The only sense in which repeat...until is more natural than do...while is

> There is a further significant difference between the Pascal
> repeat..until and the 'C' do..while. In Pascal, 'repeat..until'
> delimits a statement-list, not a single statement as in 'C'.

Oh, granted. But that's not the issue at hand, is it? Pascal could have
had a do-while with the same gross semantics as repeat-until, and C
could have had a repeat-until with the same gross semantics as do-while.
That's a side effect of C's strict insistence on statement blocks being
explicit, where Pascal allows begin, or both, to be implicit.

In Pascal++ (a language I made up at this very moment) you have a new
control structure, do-while. It has the same semantics as repeat-until
except that the sense of the test is reversed. The main difference between
repeat-until and do-while is that it's marginally harder to generate
code for the do-while...

In C^.D (a language I made up at this very moment) you have a new control
structure, repeat-until. It has the same semantics as do-while expect that
the sense of the comparison is reversed. The main difference between repeat-
until and do-while is, um... I don't think there is one. We already have
the code to generate two sorts of branches for the do-while.

#define repeat do
#define until(x) while(!(x))
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

karl@haddock.ima.isc.com (Karl Heuer) (03/22/90)

(Followups to comp.lang.misc.  I'm not talking about C; I'm talking about loop
constructs in general.)

In <OVB2S3Bxds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>The only sense in which repeat...until is more natural than do...while is
>if you're an assembly programmer or compiler writer [because at a low level,
>both are branch-if-false].

That's one possible justification, but it certainly isn't "the only sense" in
which it's more natural.

To take a concrete example, let's ignore the existence of <ctype.h> and
suppose that we want to test whether or not a given character is a lowercase
letter.  I claim that, to me, the condition "(c >= 'a' && c <= 'z')" is a
simpler expression than "(c < 'a' || c > 'z')".  I immediately recognize the
idiom in the former, but the latter causes a perceptible delay as I mentally
translate the condition.  (If you disagree with this example, invent another
one--unless you want to claim that there is *no* condition that is simpler
than its inverse.)

Now, my observation is that, given a condition COND which is simpler than
!COND, I am more likely to encounter the condition "do...while (!COND)" than
"do...while (COND)".  In this sense, repeat...until is the more natural
construct.

This is not a proof.  It's an observation, possibly biased (though I don't
think so) and subject to being contradicted by a more extensive study.

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint
________
(Note to those who keep on beating this red herring: the difference is *not*
so significant that I'm willing to use it as an excuse to switch from C to
another language; not even to that dialect of C that uses an "until" macro.
So don't bother to point out that "the preprocessor can fix it".  Do you think
you're telling me something I don't know?)

emuleomo@paul.rutgers.edu (Emuleomo) (03/23/90)

In article <IEC2SG5xds13@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes:
> In article <383@bohra.cpg.oz>, ejp@bohra.cpg.oz (Esmond Pitt) writes:
> > In article <OVB2S3Bxds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
> > >The only sense in which repeat...until is more natural than do...while is
> 
> > There is a further significant difference between the Pascal
> > repeat..until and the 'C' do..while. In Pascal, 'repeat..until'
> > delimits a statement-list, not a single statement as in 'C'.
> 
> Oh, granted. But that's not the issue at hand, is it? Pascal could have
> had a do-while with the same gross semantics as repeat-until, and C
> could have had a repeat-until with the same gross semantics as do-while.
> That's a side effect of C's strict insistence on statement blocks being
> explicit, where Pascal allows begin, or both, to be implicit.
> 
> the code to generate two sorts of branches for the do-while.
> 
> #define repeat do
> #define until(x) while(!(x))
> -- 
>  _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
> /      \  'U`
> \_.--._/
>       v

What wrong with C having 

repeat  <stmt> until <condition>
 I think this is preferable  to 
 do  <stmt> while <condition> 

 Why?  Because  using the keyword  while  for two different loop structures
 in a program tends to introduce subtle error that will be hard to find
 into the program.  Whereas, if the keyword   until  was used, there will
 be no room for such errors.
 Consider the following program fragment

etc....
lots of code
etc..
do
	etc....
	while (some_func(j++)) ;  /* This stmt was introduced by a maintenance */
							  /* programmer */
	a += b;

while (not_end_of_loop) ;
etc....


Guess what happens to the above code inadvertently??

--Emuleomo O.O. (emuleomo@yes.rutgers.edu)
-- 
** The ONLY thing we learn from history is that we don't learn from history!

night@pawl.rpi.edu (Trip Martin) (03/23/90)

emuleomo@paul.rutgers.edu (Emuleomo) writes:

>In article <IEC2SG5xds13@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes:

>What wrong with C having 

>repeat  <stmt> until <condition>
> I think this is preferable  to 
> do  <stmt> while <condition> 

> Why?  Because  using the keyword  while  for two different loop structures
> in a program tends to introduce subtle error that will be hard to find
> into the program.  Whereas, if the keyword   until  was used, there will
> be no room for such errors.
> Consider the following program fragment

>etc....
>lots of code
>etc..
>do
>	etc....
>	while (some_func(j++)) ;  /* This stmt was introduced by a maintenance */
>							  /* programmer */
>	a += b;

>while (not_end_of_loop) ;
>etc....


>Guess what happens to the above code inadvertently??

That's why I always do the follow, even though it's not necessary:

do {
   ...
} while (some condition);

Again, good coding style can avoid many potential trouble spots.

As for whether do..while is better then repeat..until, I think it's purely
a religious issue.  I personally don't care, as long as I can have my loops
test either at the beginning or at the end. 

An interesting note that might give some perspective to this issue is how
Plus, a little-known language that I'm somewhat familiar with, handles loops.
Instead of having both while and do..while forms of loops, it uses one form
called cycle.  Cycle is an infinite loop.  You can then stick exit statements
anywhere in the loop (and then can be conditional, with both flavors of tests
supported).  Conceptually, it's a more general way of handling loops.

-- 

Trip Martin
night@pawl.rpi.edu

jamiller@hpcupt1.HP.COM (Jim Miller) (03/23/90)

>
>> I'm sorry. I have to ask...
>> Since Each of these above as occupied a station in my past, for whom,
>> pray tell, are Fortran and Cobol for?
>
>Fortran--for those who like to do things fast
>Cobol--for those who like to make money
>
>-john-


Cobol--for those who work for those who like to make money

 -jim-

gary@hpavla.AVO.HP.COM (Gary Jackoway) (03/23/90)

Emuleomo O.O. writes:

> I think this [repeat..until] is preferable  to do  <stmt> while <condition> 

> Why?  Because  using the keyword  while  for two different loop structures
> in a program tends to introduce subtle error that will be hard to find
> into the program.  Whereas, if the keyword   until  was used, there will
> be no room for such errors.
> Consider the following program fragment

I agree with your point, that using the keyword for two purposes can
lead to problems, but your example...

> lots of code
> etc..
> do
> 	etc....
> 	while (some_func(j++)) ; /* This stmt was introduced by a maintenance */
> 							  /* programmer */
> 	a += b;
> 
> while (not_end_of_loop) ;

> Guess what happens to the above code inadvertently??
You can't make this mistake, because a do statement only captures a
single line: do <statement> while (condition).
The way I differentiate "while (condition) do" from  "do <statement> while"
is by ALWAYS putting {} around the do statement(s).  Thus my structure is
do {
statements
} while (condition);
By putting the while on the same line as the curly I also improve readability.
You never stop to wonder whether this is the start of a "while..do".

Gary Jackoway

cbuckley@vax1.tcd.ie (03/24/90)

In article <KZB#G{_@rpi.edu>, night@pawl.rpi.edu (Trip Martin) writes:

> An interesting note that might give some perspective to this issue is how
> Plus, a little-known language that I'm somewhat familiar with, handles loops.
> Instead of having both while and do..while forms of loops, it uses one form
> called cycle.  Cycle is an infinite loop.  You can then stick exit statements
> anywhere in the loop (and then can be conditional, with both flavors of tests
> supported).  Conceptually, it's a more general way of handling loops.
> 
> Trip Martin

...... in other words .......

 GOTO !

.............................

+-----------------------------------------------------------------+
| Colm Buckley. (Computer Science, Trinity College, Dublin)       |
|                                                                 |
| EMAIL      : cbuckley@vax1.tcd.ie                               |
| Phone      : Dublin 770101                                      |
+---+---------------------------------------------------------+---+
    |       Beware of a programmer with a screwdriver...      |
    +---------------------------------------------------------+

raw@math.arizona.edu (Rich Walters) (03/26/90)

I think that _BOTH_ while and do ... while loops suck.

I worked for the Arizona State Musuem here on campus.  They have a Prime and
use INFORMATION, a big league data base system.  It includes a dialect of
BASIC called INFO-BASIC.  The syntax of the loop structure there is:


		loop
			{ statement }
		{while (expr) | until (expr)}
			{ statement }
		repeat		

This allows _complete_ freedom in where you check for loop termination.  You
can check at the beginnig the end or _anywhere_ in between!!!

I think this is the bestest ever!!!!!!



				Richard Walter

-------------------------------------------------------------------------------

			Keep on crunching those numbers

-------------------------------------------------------------------------------

wittig@gmdzi.UUCP (Georg Wittig) (03/28/90)

raw@math.arizona.edu (Rich Walters) writes:

>		loop
>			{ statement }
>		{while (expr) | until (expr)}
>			{ statement }
>		repeat		

>This allows _complete_ freedom in where you check for loop termination.  You
>can check at the beginnig the end or _anywhere_ in between!!!

>I think this is the bestest ever!!!!!!

Personally, I prefer that style, too. But alas, there are situations where it
is far from optimal. Example

	for (i=0;   i<2700;   ++i,++j,--k,m=f(x)) {
		...
		if (condition1) continue;
		...
		if (condition2) continue;
		...
		if (condition14) continue;
		...
	}

Try to convert that into the general form. It won't look good and clearly
arranged.

Apart from that, I must admit that a for statement makes the control of the
loop much more clear and compact.
-- 
Georg Wittig   GMD-Z1.BI   P.O. Box 1240   D-5205 St. Augustin 1 (West Germany)
email: wittig@gmdzi.uucp   phone: (+49 2241) 14-2294
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Freedom's just another word for nothing left to lose" (Kris Kristofferson)

schaut@cat9.cs.wisc.edu (Rick Schaut) (03/28/90)

In article <KZB#G{_@rpi.edu> night@pawl.rpi.edu (Trip Martin) writes:
| An interesting note that might give some perspective to this issue is how
| Plus, a little-known language that I'm somewhat familiar with, handles loops.
| Instead of having both while and do..while forms of loops, it uses one form
| called cycle.  Cycle is an infinite loop.  You can then stick exit statements
| anywhere in the loop (and then can be conditional, with both flavors of tests
| supported).  Conceptually, it's a more general way of handling loops.

This is the second request I've seen for a loop construct that allows an
exit from anywhere in the loop.  Is there something drastically wrong with:

for(;;) {
   <statements>
   if (expr)
      break;
   <statements>
}

or have I missed something here?

--
Rick (schaut@garfield.cs.wisc.edu)

"I'm a theory geek; we use Turing machines!"--Gary Lewandowski

bader+@andrew.cmu.edu (Miles Bader) (03/29/90)

schaut@cat9.cs.wisc.edu (Rick Schaut) writes:
> This is the second request I've seen for a loop construct that allows an
> exit from anywhere in the loop.  Is there something drastically wrong with:
> 
> for(;;) {
>    <statements>
>    if (expr)
>       break;
>    <statements>
> }

You could always extend the syntax of the do-while statement:

    do
	<stmnt>
    while ( <condition> )
	<stmnt>

of which the existing do-while is a special case.  And just THINK of all the
new uncaught errors when someone forgets a semi-colon after a normal
do-while!

-Miles

curtj@microsoft.UUCP (Curt JOHNSON) (03/29/90)

In article <KZB#G{_@rpi.edu> night@pawl.rpi.edu (Trip Martin) writes:
| An interesting note that might give some perspective to this issue is how
| Plus, a little-known language that I'm somewhat familiar with, handles loops.
| Instead of having both while and do..while forms of loops, it uses one form
| called cycle.  Cycle is an infinite loop.  You can then stick exit statements
| anywhere in the loop (and then can be conditional, with both flavors of tests
| supported).  Conceptually, it's a more general way of handling loops.

How 'bout:

    #define Cycle for(;;)

'tho I prefer

    #define forever for(;;)

or

    #define ever (;;)
    // for ever { stuff... }

[] -- Curt Johnson -- ...!uuent!microsoft!curtj

#include <standard\disclaimer.h>

night@pawl.rpi.edu (Trip Martin) (03/30/90)

schaut@cat9.cs.wisc.edu (Rick Schaut) writes:

>In article <KZB#G{_@rpi.edu> night@pawl.rpi.edu (Trip Martin) writes:
>| An interesting note that might give some perspective to this issue is how
>| Plus, a little-known language that I'm somewhat familiar with, handles loops.
>| Instead of having both while and do..while forms of loops, it uses one form
>| called cycle.  Cycle is an infinite loop.  You can then stick exit statements
>| anywhere in the loop (and then can be conditional, with both flavors of tests
>| supported).  Conceptually, it's a more general way of handling loops.

>This is the second request I've seen for a loop construct that allows an
>exit from anywhere in the loop.  Is there something drastically wrong with:

It wasn't a request for that kind of loop construct.  I was just trying
to give a different perspective on the loop discussion.  I'm perfectly 
happy with the C looping constructs.  

>for(;;) {
>   <statements>
>   if (expr)
>      break;
>   <statements>
>}

>or have I missed something here?

I never said you couldn't do the exact same thing in C.  I was talking
about how the constructs are viewed by programmers.  

With both a do..while and a while loop, the assumption is that most code
will only want to jump out of the loop at the beginning or the end of
a loop.  Admittedly, this is a good assumption, but there are times when
it might blind programmers to where the test should really be done.  One
example which comes to mind is reading in and processing data.  The test
for end-of-file should really occur in the middle of the loop, after data
has been read in but before it's been processed.  There's a temptation to
kludge the loop so that the test does occur at the beginning or the end.  

With the cycle statement from Plus, that mistake won't be made since no
assumption is made about where the test should be.  


Trip Martin
night@pawl.rpi.edu
-- 

Trip Martin
night@pawl.rpi.edu