"hello"Technically, this is a POP-11 command (expression) that produces as a value a data-object called a word. We can assign words to variables in the same way we assign numbers. Thus
vars xxx; "hello" -> xxx; xxx ==>causes
** helloto be printed out.
Experiment: Write the POP-11 code to print out the word `goodbye'.
Like variable names, word objects can be made up using alphabetic characters, numeric characters and the underscore. They are not allowed to begin with a number or the underscore and they are not allowed to contain any hyphens.
[1 2 3]Printed out this object looks exactly like what the text we typed in.
[1 2 3] ==> ** [1 2 3]Note the slight difference between POP-11's behaviour with respect to words and lists. When we print out words we do not see the double-quote marks. However, when we print out lists we do see the square-brackets.
If we want to produce, say, the third value in a list, we can do so by putting the number 3 in round brackets after the list itself. Thus
vars numbers; [100 200 300] -> numbers; numbers(2) ==>prints
** 200This is referred to as `subscripting' the list.
If we want to replace a particular item in a list with another item we can assign the value to that position in the list using the same convention. For example
"four" -> numbers(3);The new value of `numbers' is thus
numbers ==> ** [100 200 four]Note that assigning a new value to a particular subscript of a list leaves the rest of the list intact. It does not push the existing elements along. It simply overwrites the subscripted element.
Experiment: load the initial assignment to `numbers' above. Then assign the list [the cat sat] to the variable `sentence'. Finally assign the second element of the list in `sentence' to the third position of the list in `numbers'. After doing this, the value of `sentence' should still be [the cat sat] but the value of `numbers' should now be [100 200 cat]. Note how assigning a value out of a list does not remove it from that list. Note also that assigning a value into a particular position of a list does not affect the values in other positions in any way.
There is no restriction over the values that we can put in a list. This means we can put lists inside lists if we want.
vars allnumbers; [[100 200 300] [1000 2000 3000]] -> allnumbers;If we want to get at the third element of the second list in `allnumbers', we have to subscript the variable twice---once to dig out the second list and again to dig out its third element. Thus
vars list; allnumbers(2) -> list; list(3) ==>prints out
** 3000We can do the two subscripts in one go if we want:
allnumbers(2)(3) ==> ** 3000Experiment: execute the initial assignment to `allnumbers' above and then, using two subscripts, assign the value 4000 to the second position of the first element of `allnumbers'. The new value of `allnumbers' should be [[100 4000 300][1000 2000 3000]].
It is important to note that when POP-11 is constructing a list (i.e., is in between `[' and `]'), it assumes that everything it comes across is either a word or a number. This means that if we do
[2 + 2] ==>POP-11 prints out
** [2 + 2]In this situation it thinks that `+' is a word. POP-11 makes this assumption because lists usually do contain words. Assuming that everything inside list brackets is either a number or a word saves the user the trouble of typing in lots of word-quotes. It means that the list [bug1 bug2 bug3] can be constructed by typing
[bug1 bug2 bug3]rather than
["bug1" "bug2" "bug3"]Experiment: print out this last list and explain why POP-11 prints it out the way it does.
Experiment: construct a list that contains all the whole numbers between 5 and 9. Then declare a variable called `num' and assign the third element of the list to it. Finally, print out the value of `num'. POP-11 should print `** 7'.
vars english roman; [one two three] -> english; [i ii iii] -> roman;we can do this.
[^english ^roman] ==> ** [[one two three] [i ii iii]]When we use the hat symbol this way POP-11 includes the value of the relevant variable without changing it in any way. However, in some situations, the value we want to insert is a list itself. And what we would like is to merge the list in, rather than insert it as a single element.
POP-11 caters to this need with the so-called `double-hat' symbol, which is just two hats in a row, i.e., `^^'. If POP-11 encounters this symbol when constructing a list it merges in the elements of the list, which is just the value of the following variable. If the value of the following variable is not a list, POP-11 complains appropriately.
[^^english ^^roman] ==>prints out
** [one two three i ii iii]but
vars num; 2 -> num; [^^english ^^num] ==>causes a mishap in which POP-11 issues the complaint `LIST NEEDED' because the value of `num' is not a list.
We can use the hat symbol to obtain the value of an arbitrarily long piece of POP-11 code, provided that that code produces at least one value. To make this happen we put the code in round brackets to show where it begins and ends, and precede it with the hat. Thus
[^(2 + 2)] ==>prints out
** [4]and
[^(vars x; 3 -> x; x + x)] ==>produces
** [6]If the value produced by the code in the round brackets is a list, and if we want to merge the elements of that list in, we should use `^^' rather than `^'.
Experiment: test to see what POP-11 does if you miss out the round brackets in the example above.
Experiment: if you have a variable called `num' whose value is 2, what list is constructed by [^num + ^num]?
vars description; [dooby bad bug] -> description;The value of description is just the list we assigned to it. Thus
description ==> ** [dooby bad bug]To overwrite the first element of the list we just execute the relevant assignment to position 1 of the `description' list.
"very" -> description(1); description ==> ** [very bad bug]Using hats and double-hats we can also add items to an existing list. To add element(s) to the front or back of the list we reconstruct the list, using hats and double-hats to include the new elements in the right places. If we want to add the word `a' to the front of the list `description' we have to do this.
[a ^^description] -> description;Here we have constructed a new list which merges in the old value of `description' and assigned it to be the new value of `description'. This achieves the effect of adding `a' to the front of the list. Thus
description ==> ** [a very bad bug]Experiment: write down an assignment that will have the effect of adding the words `Here is' to the front of the list in `description'.
If we want to add the value of a variable to the front of a list then we need to use both the double-hat and the single-hat. For example, if we have a list called `silly' and a variable called `new' set up as follows
vars silly, new; [foo bang ding] -> silly; "zog" -> new;we can effectively add the value of `new' onto the front of `silly' by reconstructing the list using a hat in front of `new' and a double-hat in front of `silly', and assigning the list back to `silly'.
[^new ^^silly] -> silly;The list called `silly' now has the value of `new' tacked on the front.
silly ==> ** [zog foo bang ding]Experiment: load the initializations of `silly' and `new' above and then write down an assignment that will add the value of `new' to the back of the list in `silly'. Next write down an assignment that will assign the word `goo' to the second position of the list `silly'. The value of `silly' should now be [foo goo ding zog].
lib popbugsNow try the following.
1 -> pb_new_world; [[name b1] [shape circle] [position [25 30]] [dimensions [20 20]]] -> pb_spec;The first command initializes the world to contain a single bug. The second effectively creates a circular, static object at the specified coordinates. Note that positions are given by specifying a list containing east-west coordinate (the `X' coordinate) and a north-south coordinate (the `Y' coordinate), with both coordinates being whole numbers between 1 and 100. We can modify and/or add to the attributes of this object by assigning another list to `pb_spec'. Provided that we specify the name we used before, the program knows we want to add to (or change) the attributes for an existing object.
[[name b1][colour pink][dimensions [30 15]]] -> pb_spec;If we use a different name, a new object is created.
[[name b2][colour green][position [80 80]]] -> pb_spec;Note how assignments to `pb_spec' can be used to change the position of an existing object.
vars num, colours, col, x, y; 20 -> y; 0 -> x; 1 -> pb_new_world; 0 -> num; [red green blue yellow cyan black pink brown orange] -> colours; repeat 9 times num + 1 -> num; colours(num) -> col; x + 5 -> x; [[shape box][colour ^col][position [^x ^y]][dimensions [5 5]]] -> pb_spec; endrepeat;In this program we use a `num' variable to hold a number which we increment each time we go around the repeat loop. We also use a `colours' variable which we initialize to be a list of nine colour names. In the repeat loop itself we increment the num variable and then use it to subscript a new colour from the `colours' list. We then create a new, rectangular block with an X coordinate whose value is 5 plus the X coordinate of the previous block, and a Y coordinate of 20. The effect produced is a horizontal wall of nine, differently coloured rectangles.
Experiment: modify the code so that it generates a wall of just three blocks, all in the same colour.
To make this code more useful we could wrap it up into a named procedure like this.
define wall; 0 -> num; [red green blue yellow cyan black pink brown orange] -> colours; repeat 9 times num + 1 -> num; colours(num) -> col; x + 5 -> x; [[shape box][colour ^col][position [^x ^y]] [dimensions [5 5]]] -> pb_spec; endrepeat; enddefine;We can now use the `wall' procedure to produce walls in different positions by calling the procedure after changing the initial values of `x' and `y'.
30 -> x; 60 -> y; wall(); 40 -> x; 90 -> y; wall();Experiment: find out what happens if you the bug crashes into a wall.
Where you have written some code that produces some output, you should include that output (even if it is a mishap message) as part of your answer. The easiest way to do this is to copy your code into the output file (`output.p') and execute it from there. The output will then be printed out right underneath the code.
If you find you are having difficulty with a particular problem, work back through the file looking for relevant information. Use the index mechanism (i.e., the `g' command) and the search command `/' to locate the information you need.
[a b c]; [abc]; [ [a b c] ]; [ ]; [list6]; [6list]; [^^list ^^list] (given that the value of `list' is `[a b c]') [a];
vars u, v, w, x, y, z; a -> w; [b c d] -> u; [d e] -> y; [a b c] -> x; [i j k] -> z;
vars x, y; "one" -> x; [two three] -> y;
vars x, y, z; [one] -> x; [two] -> y; [three] -> z;
[foo] -> list; hello -> list(1); list ==> |
not produce `[hello]'.
"" a pair of double quotes construct a word object (n) a bracketed whole number subscripts the preceding data-object [] a pair of square brackets construct a list of items ^ the hat inserts value of the following variable (or code) ^^ double-hat merges in the elements of following list-variable