A simple application of a `for' command is as follows.
vars n; for n from 1 to 10 do n ==> endfor;This prints out
** 1 ** 2 ** 3 ** 4 ** 5 ** 6 ** 7 ** 8 ** 9 ** 10The `n' here is called the `loop variable'. The line `for n from 1 to 10 do' instructs POP-11 to assign 1 to n and then execute the commands between the `do' and `endfor' 10 times, adding 1 to n each time around the loop. The general effect is that the n variable always contains the number of the current cycle, i.e., it effectively counts the number of times the loop has executed.
In this example, there is only command between the `do' and `endfor' and this just prints the value of n. Hence we get all the numbers between 1 and 10 printed out on successive lines. Of course, we do not have to use `n'. We can use any variable we like. And we can also use any range of integers we like. Thus
vars bang; for bang from 4 to 7 do bang ==> endfor; ** 4 ** 5 ** 6 ** 7Experiment: write a `for' command that prints out all the numbers between 3 and 11. Then write a `for' loop that prints out the `squares' of all the numbers between 4 and 8. A square of a number is just the number multiplied by itself. The square of 3 is the value of `3 * 3'.
We can have one `for' command inside another. In fact we can put any combination of commands inside the loop. The following code for example uses two `for' loops---one inside the other---to print out lists containing all pairs of whole numbers between 1 and 3 that sum to more than 2.
for n from 1 to 3 do for m from 1 to 3 do if n + m > 2 then [^n ^m] ==> endif; endfor; endfor;Note the use of indentation here to show how one command is contained within another.
The `for' command is particularly useful when used in conjunction with a list. If we want to do something to every element of a list, all we need is a `for' command whose loop variable steps through all the positions in the list. For example, imagine we set up a list as follows.
vars message; [beam me up scottie] -> message;We could print out each element of the list using the following `for' command.
for position from 1 to 4 do message(position) ==> endfor;The printing produced by this is as follows.
** beam ** me ** up ** scottieNote that there are other versions of the `for' command that achieve this effect more directly. See the POPCOURSE file on `The rest of POP-11'.)
Experiment: construct a `for' command that prints out the `square' of every value in the list [3 46 87 32 0 2], where the square of a value is just the value multiplied by itself.
We can also use a `for' command to add up a list of numbers. To do this we first set up a variable (initialized to 0) that will serve as a place to store a `running total'. We then use a `for' command with a `position' variable to iterate over the list, adding in each element to our running total.
vars numbers, total; 0 -> total; [345 1235 76 21 3] -> numbers; for position from 1 to 5 do total + numbers(position) -> total; endfor;Once we have executed this code the value of total is as follows.
total ==> ** 1680Experiment: modify the code above so that it initializes the `total' variable to the value 10000 and then subtracts each number in the list from it. The final value of `total' should be 8320.
if 4 < 3 then 1 ==> elseif 5 = 6 then 2 ==> elseif 2 > 1 and 3 > 2 then 3 ==> else 0 ==> endif;This causes
** 3to be printed out. As noted, you can have as many `elseif' sections as you like but they have to go after the main `if' and before the `else' section (if there is one).
(For practice, write POP-11 code to assign the value of the expression `23 * 78 / 4 + 6' to a variable called `num'. Then write an `if' command that prints out 1, if the value of `num' is greater than 1000 or less than 100, or 2 if the value is greater than 750 or less than 250, or 3 otherwise. Mark all the code and load it. The value printed out should be 3.)
vars n; 9999 -> n; while n > 1 do n / 2 -> n; n ==> endwhile;This executes all the commands between the `do' and the `endwhile' until such time as the value of the expression between the `while' and the `do' is <false> (which is POP-11 for `no'). Executing the `while' command above prints
** 4999.5 ** 2499.75 ** 1249.88 ** 624.938 ** 312.469 ** 156.234 ** 78.1172 ** 39.0586 ** 19.5293 ** 9.76465 ** 4.88232 ** 2.44116 ** 1.22058 ** 0.610291Note how each time we go around the loop, the value of `n' is halved. Eventually it falls below 1. This causes the value of `n > 1' to become <false> which causes the looping to be terminated.
Experiment: write a `while' command that keeps doubling and printing out the value of `n' (initialized to 1) until its value is greater than 100.
spread([foo bang ding dong]) ==> ** [foo 1 bang 1 ding 1 dong 1]
merge([a b c d], [1 2 3 4]) ==>the value printed should be
** [a 1 b 2 c 3 d 4]
allbefore([the man opened the door], "opened") ==>POP-11 should print
** [the man]
all_pairs([1 2 3], [a b d]) ==>should be
** [[1 a] [1 b] [1 d] [2 a] [2 b] [2 d] [3 a] [3 b] [3 d]]
prune([A B 1 2 C 2 1 B A]) ==> |
should produce
** [A B 1 2 C].
larger([a a a],[b c])=> ** <false> larger([1 2 3],[a b a b])=> ** <true>
for steps a variable through range, doing commands each time around while repeats some commands while an expression has value `<true>'