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