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 <ENTER> 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 <condition> DO <action> 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
<initialise Z>;
UNTIL <condition> DO
<actions>
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. ----------