TEACH ARROW                                   Steven Hardy, October 1981
                                                    Ian Rogers, Feb 1992


This file  describes the  use  of up-arrows  (ie  '^') in  lists.  Prior
reading is TEACH * VARS.

If you want to learn about the assignment arrow (ie. '->') then see
TEACH * ASSIGN.

As  you  will  know,  POP-11  programs  can  manipulate  'lists'   (most
conventional programming languages allow only manipulation of  numbers).
One of the  things that  can be done  with a  list is to  store it  in a
variable, for example:

    [shop eat cook] -> tasks;

Until we  change  the  'value'  of  'tasks'  (with  another  'assignment
statement' using the 'assignment arrow', '->'), the value of tasks  will
remain unaltered and  we can  tell POP-11 to  print it  out whenever  we
wish, for example:

    tasks =>


--ADDING ITEMS TO A LIST -----------------------------------------------

If we wish to add  an extra item, say 'clean',  to our list of tasks  we
have two options. We can type in a complete new value, thus:

    [clean shop eat cook] -> tasks;

or, more easily, we can use the 'up-arrow' notation, thus:

    [clean ^^tasks] -> tasks;

try this second alternative and also the following examples:

    [wash ^^tasks] -> tasks;
    tasks =>
    [scrub ^^tasks] -> tasks;
    tasks =>


-- WHATS GOING ON IN THE ABOVE EXAMPLES --------------------------------

Although this has been described as  'adding a new element' to the  list
'tasks' what  is  actually  going  is  slightly  more  complicated.  The
statement:

    [scrub ^^tasks] -> tasks;

has two main  components. The  first, [scrub ^^tasks],  tells POP-11  to
build a new list  and the second,  '-> tasks', tells  POP-11 what to  do
with the new list. (The semicolon isn't part of the command; it's  there
as a separator). The first part:

    [scrub ^^tasks]

tells POP-11 to build a list  whose components are the word 'scrub'  and
the components of the list which  is the value of the variable  'tasks'.
The second half of the command,  '-> tasks', tells POP-11 to store  this
new list in the  variable 'tasks' (and so  'overwrite' whatever was  the
previous value of that variable).


-- MORE EXAMPLES -------------------------------------------------------

If we ask POP-11 to do:

    [^^tasks are horrible] =>

we are  asking POP-11  to do  two  things; build  a list,  [^^tasks  are
horrible], and then  print that list,  =>. The list  that is built  will
have the elements of the list which is the value of the variable 'tasks'
and then the two words 'are'  and 'horrible'. The value of the  variable
'tasks' is unaffected, as you can check by doing:

    tasks =>

try more examples like this, for example:

    [cook eat] -> tasks;
    [before sleeping i must do ^^tasks] =>
    tasks =>
    [wash cook] -> tasks;
    tasks =>
    [^^tasks ^^tasks] =>
    tasks =>
    [^^tasks ^^tasks] -> tasks;
    tasks =>
    [^^tasks] =>
    [ho ho] -> laugh;
    laugh =>
    [^^laugh ^^laugh] =>
    repeat 5 times
      [^^laugh ^^laugh] -> laugh;
      laugh =>
    endrepeat;


-- HOW TO ASK POP-11 THE LENGTH OF A LIST ------------------------------

You can use the procedure  LENGTH to count the  elements in a list,  for
example:

    length([a b c d]) =>

This tells POP-11 to:

    (a) Build a list
    (b) Give that list to LENGTH
    (c) print what ever LENGTH returns (which will be a number)

Try the following examples:

    [cook eat clean] -> tasks;
    length(tasks) =>
    length([before sleeping i must do ^^tasks]) =>
    length(tasks) =>
    [wash cook] -> tasks;
    length(tasks) =>
    length([^^tasks ^^tasks]) =>
    length(tasks) =>
    [^^tasks ^^tasks] -> tasks;
    length(tasks) =>
    length([^^tasks]) =>
    [ho ho] -> laugh;
    length(laugh) =>
    [^^laugh ^^laugh] =>
    repeat 5 times
      [^^laugh ^^laugh] -> laugh;
      length(laugh) =>
    endrepeat;


-- SUMMARY OF DOUBLE UP-ARROW ------------------------------------------

In summary, square brackets '[' and ']' tell POP-11 that it is to  build
a list. The elements of the list that is built are the words between the
square brackets unless a word is preceded by a double-up-arrow. In  that
event the value of the word should be a list; the elements of THAT  list
are inserted as elements of the list being built.


-- LISTS CAN CONTAIN LISTS AS WELL AS WORDS ----------------------------

Although many lists contain only words, this need not be the case. Lists
may also contain lists! Here is an example:

    [[a list] with [two lists [in it]]] =>

The list built (and printed) by this command has three elements:

    the first is a list, [A LIST]; this has two elements:

            the first element is a word, A
            the second element is a word, LIST

    the second is a word, WITH

    the third  is also  a list,  [TWO  LISTS [IN  IT]], this  has  three
   elements:

            the first element is a word, TWO,
            the second element is a word, LISTS
            the third element is a list, [IN IT]; this has two elements:
                    the first element is a word, IN
                    the second element is a word, IT


-- THE SINGLE UP-ARROW -------------------------------------------------

Since lists can have lists as elements, these pose a problem.  Suppose I
have a list of my tasks, thus:

    [cook eat clean] -> tasks;

and a list of friends

    [tom mary jane] -> friends;

and I want (for some unspecified reason) to build a list like:

    [tasks [cook eat clean] friends [tom mary jane]]

The double up-arrow is no good, as you can see by trying:

    [tasks ^^tasks friends ^^friends] =>

This builds  a long  flat list  - the  double up-arrow  tells POP-11  to
insert the elements of  the list (in the  variable) TASKS into the  list
being built;

It doesn't say to add the list TASKS or the list FRIENDS as ONE  element
of the list. To do this, you must use the single up-arrow, thus:

    [tasks ^tasks friends ^friends] =>

Try it.


-- THE DOUBLE UP ARROW NEEDS A LIST ------------------------------------

The variable used with "^^" must have a LIST as value, otherwise  you'll
get a mishap. Try:
    vars x;
    99 -> x;
    [the number ^^x] =>

-- THE SINGLE UP ARROW WORKS WITH ANY VALUE ----------------------------

With the single up arrow you don't get the mishap:

    99-> x;
    [the number ^x] =>

The value of x, whatever it is, is put in as a single element of the new
list.


-- SUMMARY OF SINGLE UP-ARROW ------------------------------------------

To summarize, the single up-arrow adds  the value of the given  variable
to the list being  built as a single  element. Thus without knowing  the
values of X, Y and  Z we can be  sure that the length  of [^X ^Y ^Z]  is
three. However, the length of [^^X ^^Y ^^Z] is the length of X, plus the
length of Y plus the length of Z. Moreover, in this case X, Y and Z must
all be lists.


-- EXERCISES -----------------------------------------------------------

Here are some puzzles and a little  more POP-11 syntax. If we assign  [A
B] to X, thus:

    [a b] -> x;

then the list [^^X C] is [A B C] and the list [^X C] is [[A B] C].

What values would have to be assigned to X, Y etc so that the  following
were true (some questions have no answer):

    [^^x ^^x] = [a b a b]         ;;; answer is [A B] -> X;
    [^x ^^y] = [[a b] b c]        ;;; answer is [A B] -> X; [B C] -> Y;
    [^^x mother ^^y] = [i love my mother]
    [the height of steve is ^^x] = [the height of steve is 70 inches]
    [every ^^x is a ^^y] = [every fire man is a civil servant]
    [every ^x is a ^y] = [every fire man is a civil servant]
    [^^x i ^^y you] = [sometimes i hate people like you]
    [[^x ^^y] ^^z] = [[a b c d]]
    [^x [^^y] ^z] = [[a b] [c d] [e f]]
    [i saw ^^n ships] = [i saw 3 ships]
    [i saw ^n ships] = [i saw 3 ships]
    [i ^x you] = [i hate computers]
    [^x ^y ^z] = [i hate computers]

Use the computer to  check your answers. For  example, if you think  the
answer to the fourth one is:

    [6 feet] -> x;

then try printing the list:

    [the height of steve is ^^x] =>


-- MATCHES CAN BE USED TO DO THE EXERCISES -----------------------------

The procedure  MATCHES  can  be  used  to  find  the  answers  to  these
questions. To find, say, the values of X and Y such that

    [^^x mother ^^y] = [i love my mother]

you would  use  MATCHES with  the  up-arrows replaced  by  queries.  For
example:

    [i love my mother] matches [??x mother ??y] =>

This will be  TRUE or FALSE  depending on whether  its possible to  pick
values for X and Y. X and  Y will have the appropriate values which  you
can get printed out with the commands:

    x =>
    y =>


-- WORD QUOTES ---------------------------------------------------------

Make sure you understand the difference between:

    X -> Y;           ;;; Copy the value of X
                        ;;;     to be the value of Y
    [X] -> Y;         ;;; Make a one element list of the word X
                        ;;;     to be the value of Y
    [^X] -> Y;        ;;; Make a one element list of the value of X
                        ;;;     to be the value of Y
    [^^X] -> Y;       ;;; Make a list of all the elements of X
                        ;;;     to be the value of Y

Here's the new syntax you were promised (don't get too excited):

    "X" -> Y;         ;;; Assign the word X itself
                        ;;;     to be the value of Y

Try doing this and then do the following:

    Y =>
    [^Y] =>
    [the value of Y is ^Y and not [X]] =>
    [these are the elements of the list Y - ^^Y] =>
    [why did that last one not work] =>
    [think about it] =>
    [but dont worry if its not clear yet] =>


-- MORE ON MATCHES -----------------------------------------------------

The POP-11 system  has been instructed  on how to  work out what  values
must be assigned to variables for two lists to be equal. If you want  to
find if there  are possible values  for X and  Y such that  [^^X is  ^Y]
denotes the list [2 plus 2 is 4] then try doing:

    [2 plus 2 is 4] matches [??x is ?y] =>

This will return true or false and  also set X and Y to the  appropriate
values. MATCHES is a kind of reverse to building. Up-arrows are replaced
by question  marks (one  up-arrow  by one  question  mark and  a  double
up-arrow by  a double  question  mark). MATCHES  returns TRUE  or  FALSE
(hence it is most useful between IF and THEN). It also sets the 'queried
variables' if possible.

If you are SURE that something will match and are interested only in the
values for  the  variables, use  the  'matching assignment  arrow',  for
example:

    [2 plus 2 is 4] --> [??x is ?y];

It causes a MISHAP  if you use the  matching assignment arrow, '-->'  if
the data doesn't match the pattern. The following would cause a MISHAP:

    [2 plus 2 is 4] --> [??x times ??y];

If you have not yet done TEACH * MATCHES, you may find that useful.

For more on constructing lists, see TEACH * PERCENT.

--- C.all/teach/arrow --------------------------------------------------
--- Copyright University of Sussex 1988. All rights reserved. ----------
