TEACH VARS A. Sloman May 1987 Introduction to POP-11 variables ================================ If you are not familiar with the use of POP-11 and the editor, first work through TEACH VEDPOP. Then do TEACH MARK and TEACH LMR to see how to compile POP-11 programs from the editor. CONTENTS - (Use g to access required sections) -- INTRODUCTION AND OVERVIEW -- WHY VARIABLES ARE USEFUL -- VARIABLES CAN BE USED OUTSIDE PROCEDURE DEFINITIONS -- AN EXERCISE -- VARIABLES CAN BE USED TO STORE LISTS -- YOU CAN HAVE ANY NUMBER OF VARIABLES -- CASE IS SIGNIFICANT IN POP-11 -- A VARIABLE CAN BE USED TO STORE ANY TYPE OF OBJECT KNOWN TO POP -- DECLARING AND INITIALISING VARIABLES -- LOCAL AND GLOBAL VARIABLES -- ASSOCIATED DOCUMENTATION -- INTRODUCTION AND OVERVIEW ------------------------------------------ This teach file introduces the notion of a variable, which has a name (e.g. "num3" "list" "x" etc) and can have a value. Variables can be used inside procedures as "local variables" or outside procedures as "global" variables. Variables can be "declared" using "vars". A value can be assigned to a variable using the operator "->" read as "goes to". The value assigned to a variable can be any of the kinds of things POP-11 knows about - words, lists, numbers, procedures, etc. By associating an object with the name, you can then refer to that object in different instructions. For example, you may wish to test whether the object has some property and if it does then perform a certain action on it otherwise test if it has another property and if it does, then perform another action on it, and so on. -- WHY VARIABLES ARE USEFUL ------------------------------------------- The way the word "it" was used in the previous sentence illustrates why variables are useful in programming languages. By using the word "it", I was able to say something general about an unspecified object and refer to the same object in different parts of my sentence. Similarly, in a programming language you often need to define some general procedure for operating on objects of a certain kind, and spell out the instructions in a way that will be the same for all objects. You can then use a variable to refer to that object. E.g. in the following pseudo-English instruction I use "x" as a variable referring to an unspecified number. to double x do (x + x) That isn't POP-11. The pop-11 equivalent would be define double(x); return(x + x); enddefine; Notice the three occurrences of "x". One, in the first line, saying that the procedure double is to have one input, which is going to be called x, then in the second line saying what to do with x. Use the MARKLO and MARKHI keys (as explained in TEACH MARK) to mark that definition, then load the marked range using lmr (as explained in TEACH LMR). POP-11 will read in and compile the definition but will not print anything out. You can check that it has read it by asking it to print out what double is. Mark and load (lmr) the next line. double => it should print, in your 'output' file: ** saying that "double" is now the name of an object which is a procedure. Now you can get POP-11 to RUN the procedure with the number 5 as input, if you mark and load the following. double(5) => POP-11 will give x the value 5 and return (5 + 5) i.e. 10, and => will print it out. Try that. Try defining and testing a procedure called "treble", which takes a number and produces a result that is three times that number. Instead of "x" you could use some other name, e.g. "fred" for the input number. So your definition might start: define treble(fred); complete that and test it by marking and loading it, then, in your 'output' file mark and load: treble(5) => to check that it prints out the right number. -- VARIABLES CAN BE USED OUTSIDE PROCEDURE DEFINITIONS ---------------- In the definition of double, the use of "x" in the first line told POP-11 that you wanted to use "x" as a variable. I.e. the variable was automatically "declared" as a variable that was "local" to that procedure. This is sometimes called an "implicit" declaration. If you want to use a variable outside a procedure, e.g. to store some value for future use, then you should tell POP-11 by "declaring" the variable using the special syntax word "vars", as shown below. vars num; Mark and load it. (Nothing should be printed out.) That is an EXPLICIT declaration of a global variable, global because it is not inside the definition of a procedure. You can then give the variable a value, using the "assignment" operator "->". For example, suppose we want to give the word "num" the value 1. We can assign 1 to it thus: 1 -> num; Read that as "one goes to num". Now mark and load that line. Nothing is printed out, but you can now ask POP-11 to print the value of the variable num: num => Mark and load that. The printout will go to your 'output' file. You can now give an instruction to POP-11 to add one to num and an instruction to print out the value: num + 1 -> num; ;;; read as "num plus 1 goes to num" num => ;;; print the value of num Now mark those two lines and then load them using lmr. The new value of num is printed in your output file. If you use the REDO key to repeat the LMR instruction, and do it over and over again you'll see the value of num grow. -- AN EXERCISE -------------------------------------------------------- Try the following exercise, modelled on the "num" example above. Before doing it first look back at the "num" example so that you remember all the details. (Perhaps write them down, including all the semi-colons). Then read up to the next heading, so that you know what is coming. You could type the example into a file of your own called 'test.p': ved test.p (a) Declare a variable with any name you like, e.g. num1, fred, or whatever, using "vars" as was done above with num. Mark and load it. (You may accidentally choose a name that is already reserved by POP-11. If you get an obscure error message, try changing the name of the variable.) (b) Type in an instruction to assign 2 to your variable, using "->" (c) Mark and load the assignment. (So far, nothing should have been printed out, if you made no mistakes). (d) Type in an instruction to multiply the value of your variable by 2 and assign the result to the same variable. The multiplication symbol in POP-11 is "*" (i.e. the asterisk). (e) Type in an instruction to print out the value of the variable, using the print-arrow "=>" (f) Mark and load your two instructions. This should print something into your 'output' file. (g) Then REDO the load command several times to see how the value of your variable changes. If you type your POP-11 commands into another file ('test.p') and the output goes into a file called 'output', then if you are using a VDU screen that allows only two files to be shown at a time, this TEACH file will no longer be visible. You can get back to it by typing teach vars or using e as explained in TEACH BUFFERS. -- VARIABLES CAN BE USED TO STORE LISTS -------------------------------- Try giving POP-11 the following three commands, by marking and loading the next three lines: vars shopping; [fruit meat soap] -> shopping; shopping => The first command declares "shopping" as a variable. The second tells POP-11 to create a list containing the three words "fruit", "meat" and "soap" and assign the list to the variable, i.e. make it the value. The third says that you want the 'value' of "shopping" printed out. Square brackets should always be put around lists which are directly typed in to POP-11 and POP-11 will always put square brackets around any lists it prints out. Here's a second example for you to mark and load. vars tasks; [shopping cleaning] -> tasks; tasks => Try extending both lists by typing in extra words between the square brackets. You can then mark and load the commands and get different values printed out. Later you will learn to do more interesting things with lists. (E.g. TEACH MATCHES, TEACH DATABASE) -- YOU CAN HAVE ANY NUMBER OF VARIABLES -------------------------------- You can create any number of variables. A variable name need not be a meaningful English word - it can be any letter followed by any sequence of letters or digits. The following example gives some idea of the range of possible names: vars cat, goat, x, y13, dx, c3po, r2d2, k9, fhuasf, goal, earlier_state_of_conciousness, people, steve; All these names are now available for use. Notice how the underscore can be used to increase legibility. The underscore "_" should not be confused with the hyphen "-". They generally look different on the keyboard. You can't use the hyphen as it doesn't "join up" with letters, in POP-11. On the whole, it is better to use mnemonic variable names if you want your programs to be easily read by people (the computer doesn't care - the word "earlier_state_of_conciousness" is as meaningful to it as "fhuasf" or "x"). Occasionally you will decide on a variable whose name is already reserved as a system name by POP-11. Then you will get an error message, e.g. vars length; The mishap message says: MISHAP: IDW: ILLEGAL DECLARATION OF WORD (missing ; after vars?): INVOLVING: length If you are really curious to know what this means, you can use the HELP IDW command to get more information, but don't worry about that for now if you are learning programming for the first time. -- CASE IS SIGNIFICANT IN POP-11 -------------------------------------- In POP-11, upper case and lower case letters are different, and so you can have two variables with the same letters but one in capitals and the other lower case, e.g. "x" and "X" are different, as in: vars x, X; [hello]-> x; 2-> X; x=> ** [hello] X=> ** 2 Some of the TEACH files use UPPER case for the POP-11 examples to make them stand out from the English text. You should always type them without capital letters. The rules for legal formation of variable names in POP-11 are rather more complicated than shown here. HELP * WORDS gives more details. (You can access that help file by putting the cursor on the asterisk then typing h.) -- A VARIABLE CAN BE USED TO STORE ANY TYPE OF OBJECT KNOWN TO POP ----- Any type of object known to POP-11 can be 'assigned' to a variable. We have already seen that numbers and lists can be assigned to variables. It is also possible to assign a word. The following is rather confusing example. Try to understand what is going on. vars w,z; "z" -> w; "w" -> z; z => ;;; print out the value of z ** w w => ;;; print out the value of w ** z "w" => ;;; print out the word "w" itself ** w "z" => ;;; print out the word "z" itself ** z If you wish to check those examples, mark and load each line, apart from the lines with "**", which tell you what should be printed out into your output file. -- DECLARING AND INITIALISING VARIABLES ------------------------------- In the examples given above variables were first declared and then given some value (initialised). However, these operations can be combined with the use of the '=' sign e.g., so instead of vars x; [hello] -> x; you can do: vars x = [hello]; x=> ** [hello] Try it. You can also declare and initialise several variables in one "vars" instruction, though you have to remember to put commas between them, thus: vars y = x, p = [goodbye], n = [how are you]; y=> ** [hello] n=> ** [how are you] p=> ** [goodbye] -- LOCAL AND GLOBAL VARIABLES ----------------------------------------- It is possible for the same variable to be used both globally and locally, though in general that is a bad policy, since it can cause confusion. Here is an example to illustrate the fact that local variables do not affect the values of global variables, when the procedure has finished running. define triple(list); return([^^list ^^list ^^list]) enddefine; This defines a procedure that can be given a list as input, and produces as a result a new list containing all the elements of the original list, three times over. Mark and load it, and then test it: triple([ho]) => ** [ho ho ho] triple([three blind mice]) => ** [three blind mice three blind mice three blind mice] The variable "list" can also be used as a global variable, and given a list of numbers as values. (Actually, POP-11 doesn't care what value you give it, even though its name is "list".) vars list = [1 2 3 4 5]; ;;; declare and initialise "list" list => ** [1 2 3 4 5] Now if we run the procedure triple again: triple([hee]) => What will happen to the value of the variable list? While triple is running, list will have the list [hee] as its value. But when triple is finished, the previous value of list will be restored, namely [1 2 3 4 5] Using mark and LMR, check that out for yourself. -- ASSOCIATED DOCUMENTATION ------------------------------------------- When you have finished reading this, type ENTER Q to quit this file. You'll find out more about variables from other TEACH and HELP files. You can use the keys and n to move the cursor to the next asterisk. When the cursor is on the asterisk you want, type h to get the help or teach file. TEACH *DEFINE - more information on defining procedures, and local variables. TEACH *LISTS - information on lists, with examples TEACH * MATCHES - using the POP-11 pattern matcher, with variables in the patterns. For more advanced information (for experienced programmers) try: HELP *WORDS - the format for legal POP-11 words HELP *VARS - more advanced information on variables Note for experienced programmers. Because of its history POP-11 variables declared by "vars" and those implicitly declared as input or output variables of procedures are dynamically scoped. It is also possible to use lexically scoped variables in POP-11, and for all programs other than toy demonstrations this is the preferred method. However, at present (1987) the pattern matcher does not work with lexically scoped variables, though this will be changed. For more information see: HELP *LVARS - the use of lexically scoped variables HELP *LEXICAL - more on lexically scoped variables REF * VMCODE - for computer scientists and others interested in implementation details. --- C.all/teach/vars ------------------------------------------------------ --- Copyright University of Sussex 1987. All rights reserved. ----------