TEACH ARITH A. Sloman, Jan 1983 Using POP11 for Arithmetic ========================== POP11 enables you to refer to different kinds of objects: including words, lists, procedures, and numbers. What follows is an introduction to some of the things you can do with numbers in POP11. You can use POP-11 as a simple calculator, and we'll start by showing you how. Later you can define procedures to do more complex things, like finding averages of lists of numbers. CONTENTS - (Use g to access required sections) -- The 'PRINT ARROW' -- Multiplication -- Defining a procedure- PERIMETER -- Carpeting the room -- Wallpaper required -- The volume of a room -- A "talkative" program -- The role of parentheses -- Precedence -- Using variables to remember values -- "Undef" objects -- Adding a number to an undef object -- Warning messages -- Arithmetical expressions -- Incrementing a variable -- Decrementing a variable -- An UNTIL loop -- FOR Loops -- Arithmetic operators -- Division of two integers sometimes produces ratios -- Making ratios print like decimals -- POP-11 doesn't use algebraic syntax -- Decimal Numbers in POP11 This file assumes you are familiar with the use of VED to develop and test POP-11 programs. (See TEACH VEDPOP). You should also be familiar with variables (TEACH * VARS) and procedure definitions (TEACH * DEFINE). It will be helpful, though not essential, to know how to mark a range in the editor and "load" the marked range. ( HELP * MARK, HELP * LMR) -- The 'PRINT ARROW' -------------------------------------------------- The print arrow "=>" says to POP11, roughly, "print out your results so far" Try: 1 + 3 + 5 => 5 - 5 => 99 + 88 - 77 => The print arrow makes it possible to use POP-11 as a desk-calculator. -- Multiplication ----------------------------------------------------- Multiplication uses the "*" symbol. Try the following: 3 * 5 => 333 * 99 => 22.5 * 6 => We now show how these arithmetical operations can be used in defining some procedures to help you sort out requirements for furnishing and heating a room. Just try defining all the procedures as shown, and don't worry too much if you don't understand the details. As you gain familiarity the language will make more sense. -- Defining a procedure- PERIMETER ------------------------------------ Suppose you know the length and the and the breadth of a rectangular room and you want to know its perimeter. You can add up the lengths of all the walls, thus: define perim(long,wide) -> total; long + wide + long + wide -> total enddefine; Type that into a file, then load it and test it perim(3,4) => perim(10,20) => perim(10,10) => -- Carpeting the room ------------------------------------------------- In order to carpet the room you'll need to know the area of the floor. This procedure will tell you: define floor(long,wide) -> area; long * wide -> area enddefine; Type that in then test it floor(10,10) => floor(8,6) => -- Wallpaper required ------------------------------------------------- If you also know the height of the room you can work out the area of wall-paper required to cover the walls. Imagine the walls all straightened out into one long wall. Then the new wall would be as long as the original perimeter of the room and to find its area you'd only have to multiply that by the height. So you can do define wallarea(long,wide,high) -> total; perim(long,wide) * high -> total enddefine; Put that in a file and test it: wallarea(10,10,10) => wallarea(10,20,8) => -- The volume of a room ----------------------------------------------- If you need to buy an extractor fan, or heating system, you'll need to know the volume of the room. So define volume(long,wide,high) -> vol; long * wide * high -> vol enddefine; Then test it: volume(10,10,10) => volume(8,12, 8) => -- A "talkative" program ---------------------------------------------- You can now combine the different programs to take in the measurements of the room, and print out all the information you need, thus: define estimate(long,wide,high); vars num; perim(long,wide) -> num; [ Your room has a perimeter of ^num feet] => wallarea(long,wide,high) -> num; [ You will need ^num square feet of wallpaper] => floor(long,wide) -> num; [you will need ^num square feet of carpeting ] => volume(long,wide,high) -> num; [The radiator will have to cope with a volume of ^num cubic feet] => enddefine; Now test your procedure: estimate(10,10,10); estimate(8,12,8); Try again with all the procedures traced, so you can see when procedures start and end: trace estimate, perim, wallarea, floor, volume; estimate(10,10,10); estimate(8,6,8); The rest of this file is concerned with some of the nitty-gritty detail of how you use numbers in POP-11. -- The role of parentheses -------------------------------------------- Examine the following carefully and compare the results: 3 * 5 + 4 => (3 * 5) + 4 => 3 * (5 + 4) => Test your understanding of the "precedence" of operators "+" and "*" by attempting to predict what the following will print out: 4 + 5 * 3 => 3 + 5 * 4 + 2 => -- Precedence --------------------------------------------------------- We say that the two 'infix operators' + and * both have a precedence, but that + has a 'higher' precedence: i.e. it stretches over a larger portion of the expression, when bracketing isn't present. Alternatively you can say that * 'binds its arguments more tightly' than +. (In some programming languages 'higher precedence' has the opposite meaning.) Test some more examples, trying first to work out what result will be printed out. 4 - 3 * 5 => (4 - 3) * 5 => 5 * 3 - 2 => (5 * 3) - 2 => 5 * (3 - 2) => -- Using variables to remember values --------------------------------- You can declare a variable and use it to store a number as its value. Try: vars num; 66 -> num; num => It is possible to declare a variable and initialise its value in one instruction: vars big=999; big => -- "Undef" objects ---------------------------------------------------- If a variable is not initialised or assigned a value, its value is an "undef" object: vars xxx; xxx => -- Adding a number to an undef object --------------------------------- Now see what happens if you try adding a number to XX. Type: 1 + xxx => You can only add a number to a number, not to a variable with undefined value. If you assign a number to the variable, then it can be used in an addition. 6 -> xxx; 1 + xxx => -- Warning messages --------------------------------------------------- You can use a variable without declaring it. POP11 will declare it and print out a "warning" message. E.g. type: yyy => The warning message tells you POP11 was declaring yyy as a variable for you. Then it obeyed the instruction "yyy =>" and printed out the value of yyy, which so far is undefined. You can give a value to yyy thus: 2 -> yyy; yyy => You can also get a warning message as a result of doing an assignment to a variable not yet declared. Try 66 -> zzz; -- Arithmetical expressions ------------------------------------------- Now try printing out the value of yyy, and the value of yyy + 4, thus: yyy => yyy + 4 => So we can build complex expressions making use of variables and actual numbers. E.g. vars y, z; 4 -> y; 5 -> z; y + z => y * z => 4 * (y + z) Y and Z are now variables. "Y" is the name of the variable Y. Corresponding to it is a location in the machine where you can store information. By using the assignment arrow "->" you put something new in the location, e.g. 99 -> y; By using the name of the variable without the assignment arrow you ask what is stored in the location, and the result can be printed out, or used in some other computation, e.g. y => y + 2 => y + y => You can use the current value and change the value, in the same command. Try: y + 5 -> y; y => 'Y + 5' USES the value and '-> Y' CHANGES the value. Now give an instruction which says add the current value of Y to itself and make that the new value of Y. Print out the new value. Your answer could have been: y + y -> y; y => -- Incrementing a variable -------------------------------------------- It is often useful to add a certain amount to a variable repeatedly, for example in going through a range of numbers to perform some task. Try: vars y; 6 -> y; y + 2 -> y; y=> y + 2 -> y; y=> y + 2 -> y; y=> -- Decrementing a variable -------------------------------------------- You can gradually decrease the value of X: vars x; 10 -> x; x - 2 -> x; x => x - 2 -> x; x => x - 2 -> x; x=> You can use one variable to control the amount by which another changes. E.g. use the value of Y to control the amount by which X changes. Try the following: 4 -> x; 3 -> y; x => x + y -> x; x => x + y -> x; x => x + y -> x; x => y => -- An UNTIL loop ------------------------------------------------------ You can get the computer to do this sort of instruction repeatedly, without your having to type everything over and over again. Can you guess what the following will do? vars z; 0 -> z; until z > 20 do z => z + 3 -> z; enduntil; Try it. You could use VED to put this in a file called UNTIL.P, so that if you make a mistake you can correct it easily. When you load the file, with ENTER X, the instructions will be obeyed. Make a note of the format: UNTIL DO ENDUNTIL; See how this format relates to the above instructions. The command " Z=> " says print out the current value of Z, and the next command "Z + 3 -> Z" says add three to the value of Z and make the result the new value of Z. Read it as "Z plus three goes to Z". Those two commands (i.e. everything between "DO" and "ENDUNTIL") will be repeated until the "condition" Z > 20 is true, and the process then stops. Try a different instruction like that. E.g. try making the computer print out the numbers 2 4 6 8 10 ... up to 20 using the format ; UNTIL DO ENDUNTIL; (You supply the steps in brackets.) A possible solution would be 0 -> z; until z = 20 do z + 2 -> z; z => enduntil; If the 'initialisation' had been 2 -> Z; how would the rest have had to be different, to get the same things printed out? -- FOR Loops ---------------------------------------------------------- Often it is more convenient to use a "for" loop than an until loop. Try: vars z; for z from 1 by 3 to 25 do z => endfor; You could get POP-11 to print out the square roots of the first 20 integers thus: vars z; for z from 1 to 20 do [the square root of ^z is ^(sqrt(z)) ]=> endfor; -- Arithmetic operators ----------------------------------------------- Various "operations" are provided for arithmetic: + addition * multiplication / division - subtraction Now try the following commands: 6 -> x; 3 * x => (3 + 5) * 10 => 3 + 5 * 10 => 9 / 3 => -- Division of two integers sometimes produces ratios ----------------- Try the following: true -> pop_pr_ratios; ;;; in case the default has been changed 9 / 5 => ** 9_/5 That will print out a 'ratio' (i.e. a rational number) in a form that shows the numerator 9 and denominator 5. POP-11 will remove common factors in the numerator and denominator of a ratio: 44 / 24 => ** 11_/6 You can force it to produce a decimal number instead of a ratio if you replace one of the integers by a decimal number: 9 / 5.0 => ** 1.8 9.0 / 5 => ** 1.8 -- Making ratios print like decimals ---------------------------------- Try the following to make ratios print like decimals: false -> pop_pr_ratios; then 9 / 5 => ** 1.8 44 / 24 => ** 1.83333 If you want ratios always to print as decimals then you can put the above assignment into your 'init.p' file, and it will automatically be done whenever you run POP-11. (See HELP * INITIAL). To make ratios print as ratios, do true -> pop_pr_ratios; 9 / 5 => ** 9_/5 -- POP-11 doesn't use algebraic syntax -------------------------------- The following will produce a mishap message. (3 + 5)(2 + 2) => In POP11 you cant usually have ")" followed immediately by "(", though the following is permitted: (3 + 5) * (2 + 2) => Try it. Here's another crop of "missing separator" examples. Try them: 3 3 3x x 3 (x+5) 2 => But contrast x3 => "x3" is accepted as one word, since words can begin with letters. But "3x" is not treated as one word, since a word cannot (in POP11) begin with a numeral. -- Decimal Numbers in POP11 ------------------------------------------- Whole numbers in POP11, like 3, 5, 976, -2, -359, are called integers. Decimal numbers, like 0.5, 66.66, -22.45 are called reals, or decimals. Try the following: isinteger(3) => isinteger(3.0) => isdecimal(3.0) => isdecimal(3) => Adding a decimal to an integer gives a decimal: 3 + 5.2 => 3 + 0 => 0.0 => isinteger(0.0) => 3 + 0.0 => Similarly with subtraction: 3 - 2 => 3 - 2.0 => isinteger(3 - 0.0) => isinteger(-2) => isinteger(-2.5) => See TEACH * DECIMALS for more on decimals. See HELP * MATH for a summary of available arithmetic facilities. See HELP * LOOPS for more on loops. See REF * NUMBERS for a full account of numbers in POP-11. (For advanced readers only) --- C.all/teach/arith -------------------------------------------------- --- Copyright University of Sussex 1987. All rights reserved. ----------