Written by

Senior Cloud Architect at InterSystems
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

...

Comments

Evgeny Shvarov · Jan 13, 2020

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

0
Alexander Koblov  Jan 13, 2020 to Evgeny Shvarov

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
0
Evgeny Shvarov  Jan 13, 2020 to Alexander Koblov

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

0
Dmitry Maslennikov  Jan 13, 2020 to Evgeny Shvarov

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.

0
Robert Cemper · Jan 13, 2020

I probably miss the point of your example.

BUT, the equivalent of your WHILE loop is thisFOR loop:

setx=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
 

0
Eduard Lebedyuk  Jan 13, 2020 to Robert Cemper

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

0
Robert Cemper  Jan 13, 2020 to Eduard Lebedyuk

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.

0