Article
Eduard Lebedyuk · Jan 13, 2020 1m read

Difference between while and for

While and for are pretty similar, but sometimes you need to do a not recommended thing - change cycle boundaries.

In this situation while and for are different. For calculates boundaries once per run and while calculates boundaries on every iteration.

Consider this code sample:

set x = 5
for i=1:1:x {
     write "i: ", i,", x: ", x,!
     set x = x+1
}

You'll get this output:

i: 1, x: 5
i: 2, x: 6
i: 3, x: 7
i: 4, x: 8
i: 5, x: 9

Compare to while cycle:

set i = 1
set x = 5
while (i<=x) {
    write "i: ", i,", x: ", x,!
    set x = x+1
    set i = i+1
}

The output is infinite:

i: 1, x: 5
i: 2, x: 6
i: 3, x: 7
i: 4, x: 8
i: 5, x: 9
i: 6, x: 10
i: 7, x: 11
i: 8, x: 12
i: 9, x: 13
i: 10, x: 14

...
11
0 7 217 1

Replies

This also means that For is slightly faster than while, always.

Not necessarily

 set CNT=10e7

 write "for test",!
 set z1 = $zh
 for i=1:1:CNT {
 }
 set z2=$zh-z1
 write "time: ",z2,!


 write "while test",!
 set z1 = $zh
 set i=1
 while i<=CNT {
     set i = i+1
 }
 set z2=$zh-z1
 write "time: ",z2,!

Running this program:

USER>do ^test
for test
time: 2.017099
while test
time: 1.542252

Interesting. But why? While has one extra 'if' per cycle, not?

A FOR loop pushes a new level onto the stack. A WHILE loop does not change the stack level.  

Source

Working with stack takes time.

I probably miss the point of your example.

BUT, the equivalent of your WHILE loop is this FOR loop:

set x=5 for i=1:1 write "i: ",i,", x: ",x,! if $i(x) quit:i>x

and it's immedeatly evident that this loop is endless by design similar as the while construct
 

I thought my for loop would be endless to as x is increased on each cycle.

I see !
And can confirm that this is by design (and ANSI definition) built like a routine call by value.
And you have no chance for a pass by reference.  [ somehow   for i=1:1:.x ]

Funny enough I remember a related discussion when I implemented that piece of  M_interpreter  almost 40 yrs ago (pre Caché in MACRO32)
And the result was: If someone wants a dynamic ended loop he should use the unlimited variant and QUIT it when done.
(WHILE was unknown in the standard definition of '78) 

And for reason of backward compatibility, no one ever tried to change it.