
- TEACH POPCOURSE7 - List processing using iteration

 CONTENTS - (Use <ENTER> g to access required sections)

 -- Iteration using `for'
 -- Using `if' commands with `else' and `elseif'
 -- Iteration using `while'
 -- Exercises
 -- Quick reference
 -- Moving on


-- Iteration using `for' ------------

We have already seen that POP-11 provides a basic looping construct in
the form of the `repeat' command. This command is easy to use but in
many situations, there are alternative loop constructs which will be
more convenient. A particularly useful command in POP-11 is the `for'
loop. Like the `repeat' command, the `for' has the effect of executing a
particular sequence of commands a certain number of times, However,
unlike `repeat' it increments the value of a specified user-variable
each time around the loop.

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
  ** 10

In this example, the `for' command steps through values between 1 and
10, at each step assigning the value its currently on to the variable
`n' and executing all the commands between `do' and `endfor'. Since
there is just one command in this case, namely `n ==>', the command just
prints out every value between 1 and 10.

The `n' here is called the `loop variable'. 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
  ** 7

Experiment: 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 comes into its own 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
  ** scottie

Note 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 ==>
  **  1680

Experiment: 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.

-- Using `if' commands with `else' and `elseif' ------------

`if' commands can include `elseif' sections. These are like `else'
sections except that they have a condition, just like the initial `if'
part. An example of an `if' command with two `elseif' sections is

  if 4 < 3 then
     1 ==>
  elseif 5 = 6 then
     2 ==>
  elseif 2 > 1 and 3 > 2 then
     3 ==>
  else
     0 ==>
  endif;

This causes

  ** 3

to be printed out. 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.)

-- Iteration using `while' --------------

In addition to the `for' command, POP-11 provides a somewhat simpler
command that is useful in some situations. This is the `while' command.
This command repeatedly executes some set of commands until the value of
a particular expression is `<false>'. An example application of a
`while' command is as follows.

  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>'. 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.610291

Note 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.

-- Exercises ------------------------------------

To test your knowledge of the material presented in this file you should
do the following exercises. First, copy them into a file of your own.
Then, edit in answers underneath each question (copying in any relevant
output from your output file) and print out the file.

 (1)  Write a `for' command that uses square-brackets, hats, double-hats
etc. to reconstruct in reverse order a list of four elements stored in
the variable `words'. (Hint: you may find it helpful to have another
variable `revwords' (initialized to the empty list) in which to build up
the reversed list.)

 (3) Write a procedure called `spread' which takes a list and produces a
copy of the list in which every element of the original list is followed
by a 1. It should behave like this

  spread([foo bang ding dong]) ==>
  ** [foo 1 bang 1 ding 1 dong 1]

 (4)  Write a procedure called `merge' that takes two lists of the same
length and interleaves them. When called like this

  merge([a b c d], [1 2 3 4]) ==>

 the value printed should be

  ** [a 1 b 2 c 3 d 4]

 (5) Write a procedure, called `allbefore' that takes a list and a word
and then constructs and returns a list of all the elements that precede
the given word. When called like this

  allbefore([the man opened the door], "opened") ==>

 POP-11 should print

  ** [the man]

 (6)  Write a procedure called `all_pairs' that produces a list of
sublists such that each sublist contains a possible pairing from the two
lists provided as argument. The value printed by

  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]]

 (Hint: try using two `for' commands, one nested inside the other.)

-- Quick reference ------------------------------

The commands introduced in this file are as follows.

  for    steps a variable through range, doing commands each time around
  while  repeats some commands while an expression has value `<true>'

-- Moving on ------------------------------------

The next file in the series is TEACH POPCOURSE8.


--- $poplocal/local/teach//popcourse7
--- Copyright University of Sussex 1997. All rights reserved.
