8. Loops Rexx has a comprehensive set of instructions for making loops, using the words "do" and "end" which you met briefly in the previous section. a. Counted loops The instructions within a counted loop are executed the specified number of times: /* Say "Hello" ten times */ do 10 say "Hello" end A variation of the counted loop is one which executes forever: /* This program goes on forever until the user halts it */ do forever nop end b. Control loops Control loops are like counted loops, but they use a variable (called the control variable) as a counter. The control variable may count simply in steps of 1: /* Count to 20 */ do c=1 to 20 say c end or in steps of some other value: /* Print all multiples of 2.3 not more than 20 */ do m=0 to 20 by 2.3 say m end It may take a specific number of steps: /* Print the first six multiples of 5.7 */ do m=0 for 6 by 5.7 say m end or it may go on forever: /* Print all the natural numbers */ do n=0 say n end n The "n" at the end of this last example is optional. At the end of any controlled loop, the name of the control variable may be placed after the "end", where it will be checked to see if it matches the control variable. c. Conditional loops A set of instructions may be executed repeatedly until some condition is true. For example, /* I won't take no for an answer */ do until answer \= "NO" pull answer end Alternatively, they may be executed as long as some condition is true: /* It's OK to repeat this as long as there is no error */ do while error=0 pull a if a="ERROR" then error=1 else say a end Note that in this example, the variable "error" must be zero to start with. If there is already an error to start with then the set of instructions will not be executed at all. However in the previous example the instructions will always be executed at least once. That is, the expression after an "until" is evaluated at the end of the loop, whereas the expression after a "while" is evaluated at the start of the loop. d. Controlled conditional loops It is possible to combine forms a or b with form c mentioned above, like this: /* I won't take no for an answer unless it is typed three times */ do 3 until answer \= "NO" pull answer end or this: /* input ten answers, but stop when empty string is entered */ do n=1 to 10 until ans=="" pull ans a.n=ans end The "iterate" and "leave" instructions allow you to continue with, or to leave, a loop respectively. For example: /* input ten answers, but stop when empty string is entered */ do n=1 to 10 pull a.n if a.n=="" then leave end /* print all integers from 1-10 except 3 */ do n=1 to 10 if n=3 then iterate say n end If a symbol is placed after the instructions "iterate" or "leave", then you can iterate or leave the loop whose control variable is that symbol. /* Print pairs (i,j) where 1 <= i,j <= 5, except (2,j) if j>=3 */ do i=1 to 5 do j=1 to 5 if i=2 & j=3 then iterate i /* or "leave j" would work, or just "leave" */ say "("i","j")" end end