[comp.lang.modula2] "for" loops

abcscagz@csuna.UUCP (stepanek/cs assoc) (01/26/89)

In article <739@jupiter.iis.UUCP> heiser@iis.ethz.ch (Gernot Heiser) writes:
>
>worst features. C's 'for' is really a 'while' with an initialization clause and
>a designated spot that may contain an incrementation clause. What I consider a
>"real" 'for' (as opposed to the while/repeat/loop family) is a construct that
>executes a specific number ot times, the iteration count being determined
>BEFORE the processing of the body starts. This is what is really needed most of
>the time in numerical programs. The other cases are exactly what while/repeat/
>loop constructs are for.


Actually, C's "for" can be duplicated EXACTLY by C's "do ... while" loops.
Consider:

    for (i = 0; i <= 17; ++i)
    {
        stuff();
        more_stuff();
    }

versus:

    i = 0;
    do {
        stuff();
        more_stuff();
    } while (++i <= 17);


These two iterations are indistinguishable from one another.  The "for" term
in C is totally superfluous and is only included because it makes it look like
languages that have a more "for"-ish "for" statement, like Pascal or Modula.
(I won't even get into Algol's "for" here....)

-- 
Jeff Boeing:  ...!csun.edu!csuna!abcscagz    (formerly tracer@stb.UUCP)
--------------------------------------------------------------------------
"When Polly's in trouble I am not slow  /  It's hip, hip, hip and away I go!"
                            -- Underdog

hascall@atanasoff.cs.iastate.edu (John Hascall) (01/27/89)

In article <739@jupiter.iis.UUCP> heiser@iis.ethz.ch (Gernot Heiser) writes:

>worst features. C's 'for' is really a 'while' with an initialization clause and
>a designated spot that may contain an incrementation clause. What I consider a
>"real" 'for' (as opposed to the while/repeat/loop family) is a construct that
>executes a specific number ot times, the iteration count being determined
>BEFORE the processing of the body starts. This is what is really needed most of
 ^^^^^^

  I can't count the number of times this has nailed C novices who have had
  experience with other languages (i.e., FORTRAN).
  For example:

      for ( i=0; i < fn_with_side_effects(x); i++ ) {
	  blue_dog_moon_up();
      }

>the time in numerical programs. The other cases are exactly what while/repeat/
>loop constructs are for.

    As far as I can see, the main purpose of C's "for" is to save space,
    which is one of C's strengths (to some, probably not to MIS/COBOL
    types [oh! sorry, this isn't the misc.jobs.misc C/COBOL-CS/MIS
    flamewar?])

    John Hascall
    ISU Comp Center

bowles@eris.berkeley.edu (Jeff A. Bowles) (01/28/89)

In article <738@atanasoff.cs.iastate.edu> hascall@atanasoff.cs.iastate.edu (John Hascall) writes:
>In article <739@jupiter.iis.UUCP> heiser@iis.ethz.ch (Gernot Heiser) writes:
>
>>worst features. C's 'for' is really a 'while' with an initialization clause and
>>a designated spot that may contain an incrementation clause. What I consider a
>>"real" 'for' (as opposed to the while/repeat/loop family) is a construct that
>>executes a specific number ot times, the iteration count being determined
>>BEFORE the processing of the body starts....

I hate to fan flames like this, but I can't resist. I have strong reservations
about certain things in C, but the "for" loop is something that's really
kinda nice:

1. It's not restrictive on the types of the indices, because it defines a
   more general construct. If I had a nickel for every time, in Fortran,
   that I needed a loop that ran from 0.0 to 1.0 by 0.1 (or the like) and
   had to use INTEGER to do it. Or Pascal, which lacked the "step" clause
   so that you couldn't increment by more than what the language-designer
   wanted.
2. Yes, you're right, it's redundant - the "while (expr) statement;" and
   the "do statement; while (expr)" and the "for (expr;expr;expr) statement;"
   have a lot of redundancy, probably for brevity. So?
3. Because it's not restrictive on the types, and because I don't have to
   know EXACTLY how many times it will run through the body, I can do things
   like:
	for (p = headoflist; p != NULL; p = p->l_next)
		process(p);
   The article said that you could code loops that run a arbitrary
   number of times, using something like:
	for (i = 0; i < thingwithsideeffects(i); i++)
		munge();
   And while the author of the article is correct, you can code garbage
   like this in most languages. Fault the coder, in this case.

The only thing I really miss is something you Unix-types will recognize
from awk (and perhaps from Algol 68?) -
	for (t in table)
		process(table[t]);
But that's another story....

	Jeff Bowles

ags@s.cc.purdue.edu (Dave Seaman) (01/28/89)

In article <19579@agate.BERKELEY.EDU> bowles@eris.berkeley.edu (Jeff A. Bowles) writes:
>   If I had a nickel for every time, in Fortran,
>   that I needed a loop that ran from 0.0 to 1.0 by 0.1 (or the like) and
>   had to use INTEGER to do it. 

Fortran does not require an integer.  The control variable of a DO loop may
be integer, real, or double precision.  It is perfectly legal to write:

	REAL X
	. . .
	DO 10 X=0.0, 1.0, 0.1
	. . .

according to the current standard, but this has been recognized as a
mistake which will probably be rectified in the next standard.  You can't
even tell how many iterations you will get from the DO statement above
(10? 11? how do you know?).  Why anyone would want to add this deficiency
to a language that doesn't currently have broken FOR statements is beyond
me.

-- 
Dave Seaman	  					
ags@j.cc.purdue.edu

arrom@aplcen.apl.jhu.edu (Ken Arromdee) (01/28/89)

>Actually, C's "for" can be duplicated EXACTLY by C's "do ... while" loops.

I suspect you're going to get an awful lot of flames for saying this.  What
about
	for(i=0; i<=j; i++)
		printf("%d\n",i);
Since a do-while loop has the test condition at the termination of the loop,
it is not possible to produce an equivalent do-while version, for the
behavior will differ if j is less than 0.
--
               EARTH                  --Kenneth Arromdee
           smog  |   bricks          UUCP: ....!jhunix!ins_akaa
        AIR     mud       FIRE   INTERNET: arromdee@crabcake.cs.jhu.edu
      soda water |   tequila       BITNET: g49i0188@jhuvm
               WATER           (please, no mail to arrom@aplcen)

jlg@lanl.gov (Jim Giles) (01/28/89)

From article <19579@agate.BERKELEY.EDU>, by bowles@eris.berkeley.edu (Jeff A. Bowles):
> [...] 
> 1. It's not restrictive on the types of the indices, because it defines a
>    more general construct. If I had a nickel for every time, in Fortran,
>    that I needed a loop that ran from 0.0 to 1.0 by 0.1 (or the like) and
>    had to use INTEGER to do it. Or Pascal, which lacked the "step" clause
>    so that you couldn't increment by more than what the language-designer
>    wanted.
> [...] 
> 	Jeff Bowles

ALL standard conforming Fortran processors allow the following:

      DO 10 i=0.0,1.0,0.1

The standard committee now considers this to be a mistake and is likely
to remove it in 8x, but for the moment this is a standard feature.

It is considered a mistake because the standard doesn't make any
constraints on the accuracy of floating-point arithmetic.  So the
trip count on a loop with floating-point limits is not well-defined.
The C for-loop is even worse in this regard - the trip count is not
precomputed.  Consider the following:

      for (x=0.0; x<=1.0, x+=0.1) {...}

The value of x for each trip through the loop is a sum of 0.1+ ... +0.1,
a value which suffers round-off or truncation on each successive add.  
If the four operations in the computation of the Fortran trip count
lead to ambiguous results, the 11 adds in the above are even worse.
For a loop from 0.0 to 1000.0 by 0.01 on a 32-bit floating-point machine,
the round-off of the last 100 adds is comparable to the increment itself!
This may be another reason for the undesireable feature in C of assuming
double precision as the default floating-point.

J. Giles

crew@Polya.Stanford.EDU (Roger Crew) (01/28/89)

Here's a quiz:
How would you write the following in C?

	VAR a, b, c : Char;
	...
	FOR c = a TO b DO ... END;

You can even assume that the body of the loop affects neither a nor b.
Hint:  the answer is *not*

	char a, b, c;
	...
	for (c = a; c <= b; ++c) { ... }

(just try a = 0 and b = 255 in the case of 8 bit chars).
--
Roger Crew		Copyright 1989 -- All Rights Reserved.   (so there!)
Usenet:    {arpa gateways, decwrl, uunet, rutgers}!polya.stanford.edu!crew
Internet:  crew@polya.Stanford.EDU	

guy@auspex.UUCP (Guy Harris) (01/28/89)

>Actually, C's "for" can be duplicated EXACTLY by C's "do ... while"
>loops.

No, they can't.

	for (i = 0; i < N; i++)	/* N is a *variable* here */
		stuff;

isn't duplicated by

	i = 0;
	do
		stuff;
	while (++i < N);

because, if N is 0, the first loop will be executed 0 times and the
second loop will be executed 1 time.  It *is* duplicated by

	i = 0;
	while (i < N) {
		stuff;
		i++;
	}

as long as "stuff" doesn't include a "continue" (see p. 60 of K&R
Second Edition; there's probably similar stuff somewhere in the First
Edition).

>These two iterations are indistinguishable from one another.  The "for" term
>in C is totally superfluous and is only included because it makes it look like
>languages that have a more "for"-ish "for" statement, like Pascal or Modula.

Well, to quote something else from p. 60:

	   The "for" is preferable when there is a simple initialization
	since it keeps the loop control statements close together and
	visible at the top of the loop.

Whether you agree with that opinion or not is your business; however, it
seems the reason "for" was included wasn't solely to "make it look like
languages that have a more 'for'-ish 'for' statement", but because DMR
felt the "for" statement had merits of its own.

Devin_E_Ben-Hur@cup.portal.com (01/29/89)

Jeff Boeing writes:
> Actually, C's "for" can be duplicated EXACTLY by C's "do ... while" loops.
> Consider:
> 
>     for (i = 0; i <= 17; ++i)
>     {
>         stuff();
>         more_stuff();
>     }
> 
> versus:
> 
>     i = 0;
>     do {
>         stuff();
>         more_stuff();
>     } while (++i <= 17);
> 
> 
> These two iterations are indistinguishable from one another.  The "for" term
> in C is totally superfluous and is only included because it makes it look
> languages that have a more "for"-ish "for" statement, like Pascal or Modula.

Nope.  This is the actual equivalent code:

	i = 0;
	while (i <= 17) {
		stuff();
		more_stuff();
continue_here:
		++i;
	}

The for loop tests at the first iteration, and a continue statement will
branch to the increment not to the test.

The C for statement is a convenience allowing the programmer to place
all loop control statements in one place instead of spreading them all
over the loop.  I've always thought the limits placed on Pascal & Modula's
for statements were silly, but that's just MHO.

Devin_Ben-Hur@cup.portal.com
...!ucbvax!sun!cup.portal.com!devin_e_ben-hur

abcscagz@csuna.UUCP (stepanek/cs assoc) (01/29/89)

Hoo boy, did I ever mess up in my last posting.
I forgot that a C "for" loop may be executed zero times.
So, let me rephrase my conviction that a C "for" loop is superfluous
because it can be replaced by an equivalent "while" loop, NOT an
equivalent "do ... while" loop:

    for (i = 0; i <= 17; i = sqr(i) + 2)
       <stuff>;

versus:

    i = 0;
    while (i <= 17)
    {
        <stuff>;
        i = sqr(i) + 2;
    }

There.  I hope I have redeemed myself in the face of my previous blasphemy.

And now that I think about it, it IS nice to have final incrementational
conditions in the loop declaration rather than at the end of the loop-body,
as the "while" case forces you to do.
   (Although I do still believe that the initial "statement" field of a
"for" loop is superfluous.)

-- 
Jeff Boeing:  ...!csun.edu!csuna!abcscagz    (formerly tracer@stb.UUCP)
--------------------------------------------------------------------------
"When Polly's in trouble I am not slow  /  It's hup, hup, hup and awaay I go!"
                            -- Underdog

chris@mimsy.UUCP (Chris Torek) (01/30/89)

[followups redirected to comp.lang.misc]
In article <8515@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>[the floating point DO-loop construct] is considered a mistake because
>the standard doesn't make any constraints on the accuracy of floating-
>point arithmetic.  So the trip count on a loop with floating-point
>limits is not well-defined.

(True in both C and FORTRAN.)

>The C for-loop is even worse in this regard - the trip count is not
>precomputed.

That this is worse is mere opinion (or perhaps contentiousness).

>Consider the following:
>
>      for (x=0.0; x<=1.0, x+=0.1) {...}

Or consider:

	tripcount = (int)((1.0-0.0)/0.1) + 1;
		/* or should this be rounded rather than truncated? */
		/* (I have no F77 reference handy, sorry) */
	for (x = 0.0; --tripcount >= 0; x += 0.1) ...

which (in theory) does what the F77 construct

	DO label X = 0.0, 1.0, 0.1

does.  But suppose the task is to find the accumulated error?

	for (i = 0, x = 0.0; x <= 1.0; i++, x += 0.1)
		/* void */;
	printf("[0.0,1.0] count took %d steps; x-1.0=%g\n", i, x - 1.0);

which in F77 can be written (I will use `WHILE' here for conciseness
and to avoid those blasted statement numbers)

	X = 0.0
	I = 0
	WHILE (X .LE. 1.0) DO
	    X = X + 0.1
	    I = I + 1
	ENDWHILE
		! (I forget whether PRINT * puts spaces around numbers)
	PRINT *, '[0.0,1.0] count took', I, 'steps; x-1.0=', X-1.0

Not really that different after all (although the FORTRAN version is
in ugly uppercase :-) ).

>The value of x for each trip through the loop is a sum of 0.1+ ... +0.1,
>a value which suffers round-off or truncation on each successive add.  
>If the four operations in the computation of the Fortran trip count
>lead to ambiguous results, the 11 adds in the above are even worse.

Any programmer worth his pay is aware of the method by which the trip
count is determined, and will write the appropriate code in the appropriate
situation.  It is true that situations demanding floating point loop
counters are rare.

In any case, the generalised `for' loop construct in C is very
worthwhile, although a specialised precomputed-count loop construct (a
la most other Algol/FORTRANnish languages) might be nice.  C's `for'
fits a number of situations well, such as

	for (p = head; p != NULL; p = p->next)

for simple list traversal, or

	for (p = head.next; p != &head; p = p->next)

for circular queues, or

	for (x = init; fn1(x) < fn2(x); x = fn3(x))

for essentially arbitrary stepping around a graph of two functions
looking for a crossover.  For loops with a fixed iteration limit,
a construct like

	for i in [1..N) do

is often better, since it is clearer and allows the compiler to use
shadowing or downcounts or whatnot without requiring it to determine
that the limit is in fact fixed.  It is sometimes worthwhile in C to
recode something like

	for (i = 1; i < f(); i++)	/* where f() is a pure function */

as

	for (j = f(), i = 1; --j > 0; i++)

or (clearer but sometimes slower)

	for (i = 1, j = f(); i < j; i++)

and this sort of nonsense is really best left to the compiler.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

chris@mimsy.UUCP (Chris Torek) (01/30/89)

In article <6419@polya.Stanford.EDU> crew@Polya.Stanford.EDU (Roger Crew)
writes:
>Here's a quiz:
>How would you write the following in C?
>
>	VAR a, b, c : Char;
>	...
>	FOR c = a TO b DO ... END;
>
>You can even assume that the body of the loop affects neither a nor b.

(I do not know what this does if the range of c does not include a and
b---e.g., FOR c = 9999 to 10001 DO ... END;---so I am sort of ignoring
that case.  Probably it is a compile-time error, but what about a, b
integer, c character?)

Typically `a' and `b' are not arbitrary, and it is possible to
determine beforehand that they do not cover the entire range of `c'.
The worst-case expansion is

	if (a <= b) for (c = a;; c++) {
		...
		if (c == b) break;
	}

(This is what a compiler typically generates for a Modula loop with
indeterminate bounds---actually, it is more like

	if (a > b) goto out;
	c = a;
   top: ...;
	if (c==b) goto out;
	c++;
	goto top;
   out: ;

but only code generators and FORTRAN programmers *like* all those jumps.
Incidentally, note that c itself is never assigned if a>b.  This is the
real reason that the value of a loop iteration counter is undefined in
Pascal and Modula II after the loop, despite rationalisations.  Go ahead,
ask Wirth.  Betcha betcha :-) )

If the range of c is an improper superset of a, this can be written

	if ((c = a) <= b) for (;; c++) {
		...
		if (c == b) break;
	}

and if overflow can be ignored it can be shortened to

	if ((c = a) <= b) do {
		...
	} while (c++ != b);

Finally (or more properly firstly), if b can be determined to be
less than the maximum value of c, the whole thing can be written

	for (c = a; c <= b; c++) {
		...
	}

Incidentally, the `char' type in C is often signed:

>Hint:  the answer is *not*
>
>	char a, b, c;
>	...
>	for (c = a; c <= b; ++c) { ... }
>
>(just try a = 0 and b = 255 in the case of 8 bit chars).

If `char' is signed, and a=0, b=255, the loop runs not at all,
since b is actually -1.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

schmidt@blanche.ics.uci.edu (Doug Schmidt) (01/30/89)

In article <1626@csuna.UUCP> abcscagz@csuna.csun.edu (Jeff Boeing) writes:
++Hoo boy, did I ever mess up in my last posting.
++I forgot that a C "for" loop may be executed zero times.
++So, let me rephrase my conviction that a C "for" loop is superfluous
++because it can be replaced by an equivalent "while" loop, NOT an
++equivalent "do ... while" loop:

I don't think you've gone far enough.  After all, can't both a while
loop and a for loop be replaced by an if statement and a goto?

++
++    for (i = 0; i <= 17; i = sqr(i) + 2)
++       <stuff>;
++

versus

   i = 0;        
LOOP_HEAD:
   if (i <= 17) {
      <stuff>
      i = sqr(i) + 2;
      goto LOOP_HEAD;
   }
   
In fact, aren't all high-level control constructs superfluous?

Doug

p.s.  ;-) ......
--
schmidt@ics.uci.edu (ARPA) |   Per me si va nella citta' dolente.
office: (714) 856-4043     |   Per me si va nell'eterno dolore.
                           |   Per me si va tra la perduta gente.
                           |   Lasciate ogni speranza o voi ch'entrate.

bill@twwells.uucp (T. William Wells) (01/30/89)

In article <1626@csuna.UUCP> abcscagz@csuna.csun.edu (Jeff Boeing) writes:
: Hoo boy, did I ever mess up in my last posting.
: I forgot that a C "for" loop may be executed zero times.
: So, let me rephrase my conviction that a C "for" loop is superfluous
: because it can be replaced by an equivalent "while" loop, NOT an
: equivalent "do ... while" loop:

C is superfluous because it can be replaced by an equivalent assembly
program.

---

The C for loop exists because it encapsulates the common initialize,
test, and update control structure; it does not exist because such
encapsulation can't be written any other way, or to save keystrokes,
or any other such irrelevant reason.

---
Bill
{ uunet!proxftl | novavax } !twwells!bill

jeenglis@nunki.usc.edu (Joe English) (01/30/89)

crew@Polya.Stanford.EDU (Roger Crew) writes:
>How would you write the following in C?
>
>	VAR a, b, c : Char;
>	...
>	FOR c = a TO b DO ... END;
>
>You can even assume that the body of the loop affects neither a nor b.
>Hint:  the answer is *not*
>
>	char a, b, c;
>	...
>	for (c = a; c <= b; ++c) { ... }
>
>(just try a = 0 and b = 255 in the case of 8 bit chars).


Howzabout

         int a, b, c;
         ...
         for (c = a; c <= b; ++c) { ..., but use "(char)c" instead of "c" }

?

Or
         char a,b,c;
         ...
         for (c = a; ; ++c) { ... if (c == b) break; }


--Joe English

  jeenglis@nunki.usc.edu

diamond@csl.sony.JUNET (Norman Diamond) (01/30/89)

In article <19579@agate.BERKELEY.EDU>, bowles@eris.berkeley.edu (Jeff A. Bowles) writes:

[Praising C's for-loop over other languages' iterators]

>    If I had a nickel for every time, in Fortran,
>    that I needed a loop that ran from 0.0 to 1.0 by 0.1 (or the like) and
>    had to use INTEGER to do it.

If you do such iterations in floating-point, adding 0.1 each time
instead of multiplying an integer by 0.1, you will lose a lot of
nickels.  I wouldn't mind receiving them.  (The Vancouver Stock
Exchange did that kind of thing.  Eventually their computed index
of stock prices became about half of the correct value, and they
finally noticed they had a bug.)

>    Or Pascal, which lacked the "step" clause
>    so that you couldn't increment by more than what the language-designer
>    wanted.

This was not due to what the language designer wanted.  Remember that
he only had resources available for a small compiler and had to provide
maximal assistance to novice students in error checking.  Testing "for"
statements for overflow when the stepsize is not 1 is more difficult.
Now if you had complained that the modern version, i.e. the draft ISO
Extended Pascal standard, still doesn't allow it, then I would agree
with your complaint.

> The only thing I really miss is something you Unix-types will recognize
> from awk (and perhaps from Algol 68?) -
> 	for (t in table)
> 		process(table[t]);
> But that's another story....

Do you mean:  for (t in some_set) process (table[t]) ?
At least the draft Extended Pascal standard has this one.
-- 
Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net)
  The above opinions are my own.   |  Why are programmers criticized for
  If they're also your opinions,   |  re-inventing the wheel, when car
  you're infringing my copyright.  |  manufacturers are praised for it?

john@frog.UUCP (John Woods) (01/30/89)

In article <19579@agate.BERKELEY.EDU>, bowles@eris.berkeley.edu (Jeff A. Bowles) writes:
>    If I had a nickel for every time, in Fortran,
>    that I needed a loop that ran from 0.0 to 1.0 by 0.1 (or the like)
...you'd be broke.  You NEVER need a loop that runs from 0.0 to 1.0 by 0.1.
1/10 is a repeating fraction in binary, and thus .1+.1+.1+.1+.1+.1+.1+.1+.1+.1
does NOT equal 1.0.  Read "The Elements of Programming Style" for more tidbits
on this and other programming topics.
-- 
John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101
...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu

Presumably this means that it is vital to get the wrong answers quickly.
		Kernighan and Plauger, The Elements of Programming Style

fransvo@htsa.uucp (Frans van Otten) (01/30/89)

In article <6224@paris.ics.uci.edu> Doug Schmidt <schmidt@blanche.ics.uci.edu> writes:
>I don't think you've gone far enough.  After all, can't both a while
>loop and a for loop be replaced by an if statement and a goto?
>[..]
>In fact, aren't all high-level control constructs superfluous?
>
>Doug

And I propose to change the name of this newsgroup. It should
be comp.lang.not_modula2_but_c !

-- 
                         Frans van Otten
                         Algemene Hogeschool Amsterdam
			 Technische en Maritieme Faculteit
                         fransvo@htsa.uucp

firth@sei.cmu.edu (Robert Firth) (01/30/89)

In article <15694@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:

>(This is what a compiler typically generates for a Modula loop with
>indeterminate bounds---actually, it is more like
>
>	if (a > b) goto out;
>	c = a;
>   top: ...;
>	if (c==b) goto out;
>	c++;
>	goto top;
>   out: ;

There is a trick that works on most machines; it gives a rather tighter
loop than the above:

	IF a>b THEN GOTO done END;
	c := a-1;
    loop:
	c := c+1;
	<body>
	IF c#b THEN GOTO loop END;
    done:

This even works when 'a' is the minimum of the range; the value wraps around
on the decrement but immediately wraps back again on the first increment.
For a zero-times loop this is one conditional branch taken; for an N-times
loop it is one conditional branch not taken and (N-1) taken, plus the
possible overhead of the extra "-1" in the control initialisation.

dg@lakart.UUCP (David Goodenough) (01/31/89)

From article <1611@csuna.UUCP>, by abcscagz@csuna.UUCP (stepanek/cs assoc):
> Actually, C's "for" can be duplicated EXACTLY by C's "do ... while" loops.
> Consider:
> 
>     for (i = 0; i <= 17; ++i)
>     {
>         stuff();
>         more_stuff();
>     }
> 
> versus:
> 
>     i = 0;
>     do {
>         stuff();
>         more_stuff();
>     } while (++i <= 17);

Yes, but how about:

	for (i = 0; i <= a; i++)
	 {
	    lots_of_stuff();
	 }

against:

	i = 0;
	do
	 {
	    lots_of_stuff();
	 } while (++i <= a);

when the value of a is (say) -5. Are you _SURE_ these two are the same?

Better would be to say a for loop can be replaced by a while loop:

	i = 0;
	while (i <= a /* or 17 */)
	 {
	    lots_of_stuff();
	    i++;
	 }
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

dg@lakart.UUCP (David Goodenough) (01/31/89)

From article <6419@polya.Stanford.EDU>, by crew@Polya.Stanford.EDU (Roger Crew):
> Here's a quiz:
> How would you write the following in C?
> 
> 	VAR a, b, c : Char;
> 	...
> 	FOR c = a TO b DO ... END;
> 
> You can even assume that the body of the loop affects neither a nor b.

Probably like this:

	char a, b, c;

	c = a;
	do
	 {
	    grunt();
	 } while (c++ != b);

or like

	for (c = a; c != b; c++)
	 {
	    grunt();
	 }

depending on whether the FOR DO END loop iterates once or never when b == a.
The basic idea is to test for equality rather than relation.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

barmar@think.COM (Barry Margolin) (01/31/89)

In article <1381@X.UUCP> john@frog.UUCP (John Woods) writes:
]In article <19579@agate.BERKELEY.EDU>, bowles@eris.berkeley.edu (Jeff A. Bowles) writes:
]>    If I had a nickel for every time, in Fortran,
]>    that I needed a loop that ran from 0.0 to 1.0 by 0.1 (or the like)
]...you'd be broke.  You NEVER need a loop that runs from 0.0 to 1.0 by 0.1.
]1/10 is a repeating fraction in binary

Just because Fortran can't do it doesn't mean that he doesn't NEED it;
it just means he can't GET it.  Since the real world mostly works in
decimal, I imagine that the need is frequent.  Luckily, there are
well-known and easy ways around this problem.


Barry Margolin
Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

marti@ethz.UUCP (Robert Marti) (01/31/89)

Please stop cross-posting this drivel about for-loops in C to
comp.lang.modula2!  (Gernot, are you listening, too?)  Those
Modula-2 hackers who don't know that a for-loop in C can be
expressed as a while-loop but not as a do-loop probably couldn't
care less ...

-- 
Robert Marti                    Phone:       +41 1 256 52 36
Institut fur Informatik
ETH Zentrum                     CSNET/ARPA:  marti%ifi.ethz.ch@relay.cs.net
CH-8092 Zurich, Switzerland     UUCP:        ...uunet!mcvax!ethz!marti

tcm@srhqla.UUCP (Tim Meighan) (02/01/89)

In article <6419@polya.Stanford.EDU> crew@Polya.Stanford.
EDU (Roger Crew) writes:
>Hint:  the answer is *not*
>	char a, b, c;
>	for (c = a; c <= b; ++c) { ... }
>(just try a = 0 and b = 255 in the case of 8 bit chars).

Sure it is.  You need to declare  a, b, and c as:

 unsigned char a, b, c;

Otherwise, setting b = 255 is actually doing this:  b = -128.

Tim Meighan
Network Operations
Silent Radio

geoff@warwick.UUCP (Geoff Rimmer) (02/03/89)

In article <6419@polya.Stanford.EDU> crew@Polya.Stanford.EDU (Roger Crew) writes:
>Here's a quiz:
>How would you write the following in C?
>
>	VAR a, b, c : Char;
>	...
>	FOR c = a TO b DO ... END;
>
>You can even assume that the body of the loop affects neither a nor b.
>Hint:  the answer is *not*
>
>	char a, b, c;
>	...
>	for (c = a; c <= b; ++c) { ... }
>
>(just try a = 0 and b = 255 in the case of 8 bit chars).
>--

What a stupid question.  If you are going to count from 0 to 255, you
wouldn't use char in the first place - you'd use unsigned char, or
int.  I can't see what you're getting at, at all.

Go back to writing Fortran.  Let the *real* programmers use C. :-)

>Roger Crew		Copyright 1989 -- All Rights Reserved.   (so there!)
>Usenet:    {arpa gateways, decwrl, uunet, rutgers}!polya.stanford.edu!crew
>Internet:  crew@polya.Stanford.EDU	

	------------------------------------------------------------
	Geoff Rimmer, Computer Science, Warwick University, England.
			geoff@uk.ac.warwick.emerald

	"I didn't ask to be made.  No consulted me or considered my
	 feelings in the matter, not that anyone considered that I
	 might *have* feelings.  After I was made, I was left in a
	 dark room for six months, and me with this terrible pain in
	 all the diodes down my left side.  My one and only true
	 friend was a small rat.  One day it climbed into a cavity of
	 my inner leg and died.  I've a horrible feeling it's still
	 there." - Marvin, The Hitch Hiker's Guide to the Galaxy.

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

crew@Polya.Stanford.EDU (Roger Crew) (02/07/89)

In article <1004@ubu.warwick.UUCP>, geoff@warwick (Geoff Rimmer) writes:
> In article <6419@polya.Stanford.EDU> crew@Polya.Stanford.EDU (Roger Crew) writes:
> >Here's a quiz:
> >How would you write the following in C?
> >
> >	VAR a, b, c : Char;
> >	...
> >	FOR c = a TO b DO ... END;
> >
     [ ... yup, this discussion ...]
>
> What a stupid question.  If you are going to count from 0 to 255, you
> wouldn't use char in the first place - you'd use unsigned char, or
> int.  I can't see what you're getting at, at all.

I'll grant that, for the benefit of compilers that *have* signed
chars, I actually did intend to say ``unsigned char'' rather than
``char''.  The fact of the matter is, however, that

        unsigned char a;
	for( c=0; c<=255; ++c) {...}

still doesn't work.  You can try it if you like, or you can read the
submissions from the other 10 posters who understand what's going on...  

The fact that I was using chars signed or unsigned is irrelevant to
the point I was trying to make, namely that the semantics of C
for-loops and Modula/Pascal for-loops are entirely different -- it is
not simply a case of one being more general than the other.  While
it's fairly obvious that a general C for-loop often can't be written
as a Modula for-loop, it's not so obvious (or at least, *I* didn't think
it was completely obvious...) that to do a general Modula for-loop
in C *also* requires strange contortions.

As for *why* I'd want to be counting with chars, just consider any
application requiring some kind of array indexed by chars, e.g.,

	VAR font : ARRAY Char OF Bitmap;

It's an obvious thing to do in Modula.  I suppose this also
illustrates the danger of carrying over one languages way of thinking
into another, a problem that does not confine itself to for-loops.

> Go back to writing Fortran.  Let the *real* programmers use C. :-)

I'll let this statement speak for itself.  :=)

--
Roger Crew					``Beam Wesley into the sun!''
Usenet:    {arpa gateways, decwrl, uunet, rutgers}!polya.stanford.edu!crew
Internet:  crew@polya.Stanford.EDU