Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker!bloom-beacon!eru!luth!sunic!dkuug!freja.diku.dk!skinfaxe.diku.dk!jensting From: jensting@skinfaxe.diku.dk (Jens Tingleff) Newsgroups: comp.lang.modula2 Subject: Re: FOR loops Message-ID: <1990Jul4.074634.645@diku.dk> Date: 4 Jul 90 07:46:34 GMT References: Sender: news@diku.dk (The Netnews System) Organization: Department Of Computer Science, University Of Copenhagen Lines: 116 ROSS@UCF1VM.BITNET (Bri) writes: [..] >Anyone else have any answers as to why Wirth designed such a restriction? could be a continuation of the restriction from Pascal, i.e. a FOR loop index MUST be a locally declared simple integral variable. Having the syntax say ``Ident'' instead of ``Designator'' hints at this restriction (if not enforcing it, UGH! semantics in grammmmar are ugly..). The reason for demanding a local variable is (or could be ?) that a local variable can be detected to be non-aliased. I.E. that no context switch can alter the loop control variable (a context switch such as an interupt). Since only global procedures are allowed as co-routines (see p. 167 of PIM2 ed 3), it's impossible to change the value of a FOR loop index with a co-routine. Modula-2 also requires a local var, incidently, PIM2 ed 3 p. 158. The following is thus illegal (pseducode..) PROCEDURE lotawork(); VAR controlvar, bar : INTEGER; PROCEDURE Dosomework():INTEGER; VAR foo : CARDINAL; BEGIN foo := 0; FOR controlvar := 0 TO 700000 DO (* Not allowed %1 *) foo := foo + 1; END; RETURN foo; END Dosomework; PROCEDURE Stompit; BEGIN controlvar := 1000000; ContinueAfterInterupt(); END Stompit; BEGIN (* lotawork *) SetToInteruptEverySplitSecond(Stompit); (* Not allowed, %2 *) bar := Dosomework(); END lotawork; where the value of `bar' just might be weird. %1 Nonlocal variable leads to disaster for any call to Stompit. %2 local procedure an actual for PROCESS formal parameter, not allowed. So, this mayhem is illegal (phew). This is, however, legal (???) MODULE globalmodule; FROM SYSTEM INPORT ADR; TYPE intptrtyp = POINTER TO INTEGER; VAR intptr : intptrtyp; PROCEDURE Stompit; BEGIN intptr^ := 10000000; ContinueAfterInterupt(); END Stompit; PROCEDURE notsosafe; VAR i : INTEGER; BEGIN intptr := ADR(i); (* Boo, aliasing *) FOR i := 0 TO 700000 DO whatever(); END; END notsosafe; BEGIN (* globalmodule *) SetToInteruptEverySplitSecond(Stompit); notsosafe; END globalmodule; This last example, possible aliasing of `i', CAN be detected by the compiler, at which point a warning may be printed out. ANYWAY. A slightly more levelheaded reason for requiring the FOR control var to be simple and local is that it's easier to decide to make the loop-cntr. var a register var...... . By The Way, new question : Is the FOR loop control var defined after the FOR statement ? Wirth (PIM2 ed 3 p 158) doesn't say not, in fact the paragraph reads "FOR v := S TO B BY C DO SS END expresses repeated execution of the stat. seq. SS with v successively assuming the values A, A+C, A+2C, .., A+nC where A+nC is the last term not exceeding B." It says "v successively assuming the values", but not what v is AFTER the statement. Hmmm. Modula-3 (see page 25 of the revised report) says "FOR id := first TO last BY step DO S END; .. The identifier id denotes a readonly variable whose scope is S and whose type is the common basetype of first & last." ^^^^^^^^^^ right on. Likewise Occam-2 (and algol68 ?) Jens Jens Tingleff MSc EE, Institute of Computer Science, Copenhagen University Snail mail: DIKU Universitetsparken 1 DK2100 KBH O "It never runs around here; it just comes crashing down" apologies to Dire Straits