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