markh@csd4.milw.wisc.edu (Mark William Hopkins) (04/17/88)
The best way out of the difficulties associated with the for-loop is to define it. I would suggest the following definition: FOR I := A TO B DO == I := A; <Statement Sequence> WHILE I < B DO END <Statement Sequence>; I := I + 1 END; IF I = B THEN <Statment Sequence> ENDIF This set-up makes I come out of the loop with the value B. An alternative, which is closer to the original intent of making the "control variable" a LOCAL VARIABLE of the FOR-LOOP, is the following: FOR I := A TO B DO = PFOR(A, B) where PFOR is declared as the procedure <Statement Sequence> PROCEDURE PFOR( A, B : TypeName); VAR I : TypeName; END BEGIN Enclose the statements above END This does not make the troubles associated with I disappear, but it does make the restrictions on I less ad-hoc.
seitz@cory.Berkeley.EDU (Matthew Eric Seitz) (04/17/88)
In article <5571@uwmcsd1.UUCP> markh@csd4.milw.wisc.edu (Mark William Hopkins) writes: > > The best way out of the difficulties associated with the for-loop is >to define it. I would suggest the following definition: > >FOR I := A TO B DO == I := A; > <Statement Sequence> WHILE I < B DO >END <Statement Sequence>; > I := I + 1 > END; > IF I = B THEN > <Statment Sequence> > ENDIF > >This set-up makes I come out of the loop with the value B. _Programming_In_Modula-2_ essentially defines the for statement as the following equivalency "FOR" ident ":=" expression1 "TO" expression2 [ "BY" ConstExpression ] "DO" StatementSequence "END" is equivalent to ident ":=" expression1; "WHILE" ident "<=" expression2 "DO" StatementSequence [ident ":=" ident "+" ConstExpression (* if "BY" clause used *) | ident ":=" ident "+ 1" (* if "BY" clause not used *) ]";" "END" (* ident := undefined *) This means that you can replicate any FOR statement by a WHILE statement with only two additional lines. Since this is also more explicit and flexible than a FOR loop, I've started using the WHILE loop exclusively. I imagine Wirth had similar reasons for dropping the FOR loop from Oberon. Matthew Seitz seitz@cory.berkeley.edu
crew@polya.STANFORD.EDU (Roger Crew) (04/18/88)
In article <2455@pasteur.Berkeley.Edu> seitz@cory.Berkeley.EDU.UUCP (Matthew Eric Seitz) writes: > > _Programming_In_Modula-2_ essentially defines the for statement as > the following equivalency > > "FOR" ident ":=" expression1 "TO" expression2 [ "BY" ConstExpression ] "DO" > StatementSequence > "END" > is equivalent to > > ident ":=" expression1; > "WHILE" ident "<=" expression2 "DO" > StatementSequence > [ident ":=" ident "+" ConstExpression (* if "BY" clause used *) | > ident ":=" ident "+ 1" (* if "BY" clause not used *) ]";" > "END" > (* ident := undefined *) > Ouch. If _Programming_in_Modula-2_ says this,... well, it's a mistake, plain and simple. Consider: FOR ch := 0C TO 255C DO whatever END; which supposedly is equivalent to ch := 0C; WHILE ch <= 255C DO whatever INC(ch); END; If you don't like playing with characters, try FOR i := -2^31 TO 2^31-1 (for 32 bit integers... i.e., MININT and MAXINT, or whatever they happen to be called these days...). The WHILE loop will bomb at runtime when it tries to increment 255C. If you were doing this with integers, you won't be this lucky. (hint: in C, for(ch=0;ch<=255;ch++) is an infinite loop when ch is an 8-bit char). You really do need that second IF statement (or something similar; if you don't like writing the statement body twice, then you have to go through contortions like ident := expression1; IF ident <= expression2 THEN LOOP whatever; IF ident = expression2 THEN EXIT END; INC(ident); END; END; And even this general form fails miserably for FOR ch := 0C TO 255C BY 2 DO whatever END; (unless, or course, you cheat by changing 255C to 254C) -- Roger (crew@polya.stanford.edu) ``Beam Wesley into the sun!''
firth@sei.cmu.edu (Robert Firth) (04/18/88)
In article <2455@pasteur.Berkeley.Edu> seitz@cory.Berkeley.EDU.UUCP (Matthew Eric Seitz) writes:
]_Programming_In_Modula-2_ essentially defines the for statement as the following
]equivalency
]
]"FOR" ident ":=" expression1 "TO" expression2 [ "BY" ConstExpression ] "DO"
] StatementSequence
]"END"
]is equivalent to
]
]ident ":=" expression1;
]"WHILE" ident "<=" expression2 "DO"
] StatementSequence
] [ident ":=" ident "+" ConstExpression (* if "BY" clause used *) |
] ident ":=" ident "+ 1" (* if "BY" clause not used *) ]";"
]"END"
](* ident := undefined *)
It does. And thereby perpetuates the design or implementation error that
has cursed FOR-loops since the days of Algol-60: a loop set to end on the
largest value of the associated type will fail.
This is 1988. Let's at least put THAT right!
chrisj@cup.portal.com (04/20/88)
In 5099@aw.sei.cmu.edu, firth@sei.cmu.edu (Robert Firth) quotes an earlier article about the semantics of FOR loops and says: >... thereby perpetuates the design or implementation error that >has cursed FOR-loops since the days of Algol-60: a loop set to end on the >largest value of the associated type will fail. > >This is 1988. Let's at least put THAT right! This is purely an implementation issue. MacMETH does it correctly, as I'm sure some other compilers do. At the bottom of the loop, MacMETH generates an ADDI or SUBI, followed by either a BVC (INTEGER or LONGINT) or a BCC back to the top of the loop. Note that this correctly handles FOR u := 0 TO MAX(CARDINAL) BY 2 DO ... END; Stopping on >= before the increment, rather than > after the increment, would not help in this case, although I suppose the generated code could decrement the limit by (stepsize-1) before the loop, and then use a >= test before increment. If your compiler doesn't handle these limit situations correctly, gripe at the vendor until they fix it. (Hi, Eli! :-)) Of course this means that a FOR loop is not EXACTLY equivalent to the corresponding WHILE, since the WHILE version will either ignore the carry/overflow or abort execution, depending on the implementation. Christopher Jewell | If God had meant for us to fly, He chrisj@cup.portal.com | would NEVER have given us the railways. ucbvax!sun!cup.portal.com!chrisj | -- Flanders & Swan