TEACH FACES                                       Aaron Sloman Sept 1998
Last changed: 5 Oct 2000
(Removed calls of rc_start. Replaced with rc_new_window_object
and rc_clear_window_object, to avoid unwanted interactions.)

-- What this is about -------------------------------------------------

This Teach file introduces the Poplog editor Ved, and programming in
Pop-11, a powerful general purpose computer programming language
developed originally for artificial intelligence (AI) research, but
capable of being used for a wide range of different applications.

(Use the "Page down" key or downward pointing arrow key to read on.)

Pop-11 is based on Pop2, which was developed at the University of
Edinburgh in the early 70s. Considerable extensions to the language were
made at the University of Sussex, when Pop-11 was enlarged to form the
Poplog system, which also includes other languages. Here in Birmingham
we have made further extensions to Pop-11 including some of the
graphical facilities used in this Teach file. Besides using it for
teaching some of us use it for research, and have built a powerful
toolkit, SimAgent, which you may meet later.

Pop-11 is or has been used for teaching and research in a number of
universities in the UK and elsewhere (e.g. Australia, New Zealand,
Germany, the USA), and there are several companies which sell products
based on it. Integral Solutions Ltd in the UK used to sell both
products and the Poplog System, which includes Pop-11, but since
mid-1999 Poplog has become available free of charge at this site:

    http://www.cs.bham.ac.uk/research/poplog/freepoplog.html

ISL produced a very successful Data Mining product, Clementine, sold
world wide, based on Pop-11, and as a result they were taken over by the
US company, SPSS at the end 1998.  SPSS are now selling Clementine: see
    http://www.spss.com/
    http://www.spss.com/spssatwork

We use Pop-11 for teaching and research in AI because it has a number of
features that make it particularly suitable for those purposes, e.g.
compared with Java or C++. In particular, there is a lot of very useful
teaching material based on Pop-11 for beginners learning about
Artificial Intelligence.

This file does not assume any prior programming experience. By working
through it, you will learn to give simple editing commands which create
instructions in the Pop-11 language. These instructions can be obeyed
directly from the editor. You will use the instructions first to create
very simple pictures, and then to create more complex pictures, such as
happy and sad faces.

This will introduce you to some general programming techniques that are
relevant to a wide range of computing tasks and programming languages.
It will also give you some painless "revision" of some generally useful
concepts and techniques concerned with representation of points and
lines by numbers and equations. Later teach files will teach you much
more. The more you learn the faster subsequent learning will be.

By designing small programs you will begin to understand the difference
between USING a software tool or package that someone else has created,
and DEVELOPING such things yourself.

You are about to be transformed from a USER into a CREATOR.

It takes time, and many things will go wrong on the way. Every
programmer makes mistakes, and one of the things you'll learn is how to
understand your mistakes and correct them (i.e. you will learn how to
"debug" your programs). If you allow yourself to feel bad when things go
wrong, instead of rising to the challenge of identifying and fixing the
problem, your learning will be impeded. So intelligence is not enough:
programming demands a resilient personality.

The computer is tireless, like a very patient teacher, but also very
simple-minded. So it will never guess what you really meant to do: thus
you will have to learn to use great precision in giving instructions.
(Computers of the future may be more intelligent, but that's a topic
for another time.)

Things you will have to learn separately:

    o How to log in
    o How to start up the editor Ved
    o How to get a TEACH file from the online documentation library
      into the editor. (You are reading a teach file now).
    o How to terminate a Ved and Pop-11 session
    o How to log out
    o How to move windows on the screen, using the mouse. E.g. the
        default method set up at Birmingham allows you to drag a window
        by using the mouse pointer on the window's title bar at the top.
        You need to depress the LEFT mouse button. The window manager
        has additional options, including several menus. Further details
        are in the file TEACH CTWM.

You will also learn, later on, how to create files of your own, how to
modify them, how to print them out, how to save them on disc before you
leave the computer. Some of you will also learn about the Unix operating
system and its file store. Others may prefer to focus on the AI
programming techniques.


-- Learning to "drive" Ved and Pop-11: Some tiny examples -------------

Before you read on, try your very first Pop-11 command, namely

    'Hello there ' <> sysgetusername(popusername) =>


Put the editor cursor on that line (using the up or down arrow keys),
and then press the ESC key (usually on the left) followed by the
D key. The ESC-d sequence tells Ved to pass the line of text to Pop-11.
Pop-11 then compiles and runs the instruction. Try that.

You will get a new window called 'output.p', with a greeting in it,
printed by the "print-arrow" i.e. "=>" Move the output.p window to where
you can see the contents without obscuring this file.

Do it a few times. Then try it also on the following line, which causes
Pop-11 to create a list of words and numbers then print out the list

    [The sum of 33 and 66 is ^(33 + 66)] =>

Change the numbers and do it again.

Now consider the following three-line command:

    repeat 10 times
        'Hello there ' <> sysgetusername(popusername) =>
    endrepeat

You can't use ESC-d because that works only on ONE line at a time. So
you can "mark" the three lines and then tell Ved to give all three lines
to Pop-11 in one go, as follows:

Use the UP or DOWN arrow key to put the text cursor on the "repeat" line
above, then "mark" it by pressing the F1 key (top left). You'll see a
vertical bar on the left. Then go down to the "endrepeat" line and press
F2 to extend the marked range.

Remember: If your terminal has been set up properly for Ved,
    F1 means "mark first"
    F2 means "mark last"
There are many other useful commands associated with function keys.

Once you have marked the above three line Pop-11 instruction, you can
compile and run the "marked range". Type Control-D. I.e. hold down the
Control button (on the left usually), and press and release the D key
(while Control remains held down). this is sometimes abbreviated as
CTRL-D, or CTRL-d or ^D. Try it a few times. Instead of CTRL-D you can
press ENTER, then type lmr (for Load Marked Range) then press RETURN.
But you must not confuse ENTER (right hand end of keyboard) and
RETURN (to the right of centre).

Remember:
    ESC  d  means   Compile one line (also called "loadline").
    CTRL d  menas   Compile marked range  (Also ENTER lmr)

Try changing the 'Hello there' text above, between the 'string' quote
marks, and then compile the marked range again.

The command in the middle line, namely
        'Hello there ' <> sysgetusername(popusername) =>

uses the Pop-11 concatenator "<>" to join the string on the left to the
result of applying the procedure systegusername to the value of the
variable popusername. The "print arrow" on the right "=>" causes the
concatenated string to be printed out, preceded by two asterisks.

You can also print out the value of popusername, if you compile just
this line:

    popusername =>

That should print your login name. Print the result of applying
sysgetusername to it:

    sysgetusername(popusername) =>

Another example. The following four line command will prints out a list
of square numbers if you mark the range then compile the range. Do it:

    repeat 3 times
        lvars x;
        [squares : ^(for x from 1 to 10 do x * x endfor) ]=>
    endrepeat;

Try changing it to print numbers that are cubes instead of squares.
(In Pop-11 "*" means "multiply", when used with two numbers.)

-- Pop-11 commands can be partly random -------------------------------

Normally a Pop-11 command is very definite: it tells the computer
exactly what to do. However, Pop-11 commands can also let the computer
make a random choice. E.g. try giving this command several times:

    random(20) =>

Each time it will print a number between 1 and 20, but the number is
"randomly" chosen (using a determinate "random number generator"
program!).

Try this:

repeat 200 times
    pr(random(20)); pr(space);
endrepeat;

You can also make Pop-11 chose randomly from a list of items:

    oneof([cat dog elephant mouse [blue moon] [ripe bananas]]) =>

Use the loadline command several times on that and see what happens.
Note that it treats sub-lists as single entities.

Later you will use "oneof" and "random" to produce random pictures.

-- Your first face ----------------------------------------------------

Now draw your first face, by compiling each of these lines in turn:

;;; make sure the RCLIB package is compiled
uses rclib;

;;; Create a window (then move it so that you can read this text)
;;; Declare a variable called win1 and give it a window
vars win1 =rc_new_window_object(600, 10, 400, 400, true, 'WIN1');

;;; Make your first face in the centre of the picture (0,0),
happy_face(0, 0, 40, 'red', 10, 15, 30, 'blue', 'pink');

;;; The overall radius is 40, the eye radius 10, the mouth radius 15,
;;; the distance between centres of eyes 30, eye colour blue,
;;; mouth colour pink.

;;; Try changing the face by changing the sizes or the colours, and
;;; drawing new ones in new locations (i.e. with coordinates other
;;; than 0,0 for the centre of the face, e.g.

happy_face(-80, 80, 50, 'blue', 15, 18, 35, 'yellow', 'pink');

;;; Later you will learn how to create the procedure that produces such
;;; happy faces. You will also learn how to make a sad face....

sad_face(-80, -80, 50, 'blue', 15, 20, 40, 'yellow', 'green');

Try some more, e.g. faces on the right of the picture (first number
greater than 0).

Now read on.


-- TABLE OF CONTENTS

 -- What this is about
 -- Learning to "drive" Ved and Pop-11: Some tiny examples
 -- Pop-11 commands can be partly random
 -- Your first face
 -- TABLE OF CONTENTS
 -- Introduction: why program?
 -- Choosing a programming language
 -- Long term learning objectives
 -- Getting started
 -- Introduction to Ved's keyboard control sequences
 -- More on the "loadline" command
 -- How does Ved's loadline command work?
 -- Examples of use of loadline (ESC D)
 -- Compile-time and run-time errors
 -- Marking a range of lines
 -- Load Marked Range: (ENTER lmr, or CTRL+d)
 -- Summary: Ved and Pop-11
 -- Warning: Well-meaning "expert" friends can be dangerous
 -- Pop-11 as a desk calculator
 -- What does Pop-11 know about?
 -- Making pictures in Pop-11
 -- The "uses" command for ensuring that libraries are available
 -- Start a window and draw some circles
 -- Giving a loop instruction
 -- Exercise: making a vertical line of circles
 -- Another exercise: what will this do?
 -- Avoiding explicit lists of numbers
 -- Re-starting after logging in
 -- Starting up your own file
 -- Copying text from another file: ENTER ti
 -- Drawing coloured blobs
 -- Making a face
 -- Creating procedures for parts of faces
 -- Defining fixed_eyes
 -- Defining located_eyes
 -- Using located_eyes to define smile_face
 -- Defining sad_face
 -- Using a conditional expression in a procedure
 -- Combining two face types using a conditional expression
 -- Using lists to describe a scene
 -- Making a list of face specifications
 -- Making a procedure to draw lots of faces described in a list
 -- More drawing primitives for more types of faces
 -- Exercise: Making colours and sizes variable
 -- What next?
 -- Working at home

-- Introduction: why program? -----------------------------------------

In order to get computers to do things, you can sometimes use a package
which has been developed by someone else, which has a more or less
friendly "interface" allowing you to instruct the computer by moving a
mouse, pressing buttons, making selections from menus, or typing
commands on the keyboard.

Such tools are often very powerful and may be easy to use, but they are
all restricted insofar as they have been designed to perform a
PARTICULAR range of tasks, e.g. editing and formatting documents,
reading or sending mail, interrogating databases, and so on.

In order to create such tools, or develop new ones, you have to learn to
use a different, more GENERAL, kind of tool, a programming language ---
sometimes several different programming languages at once.

A programming language is a language in which you can specify tasks for
a computer to perform. There are many different kinds of programming
languages designed for different sorts of software development tasks.

Pop-11 is a programming language. It lets you give the computer many
different kinds of commands. The following command uses constructs you
have already met previously, the concatenate operator "<>" to join two
strings, and the print arrow operator "=>" to print out the result.

    'Hello ' <> popusername =>

Note that command uses an "infix" operator "<>" just as the next one
uses the more familiar infix operator "+". Try compiling this line:

    33333 + 66666 =>

The difference is that "+" combines two numbers to produce a new one,
and "<>" combines two strings (or two words, or two lists, or two
procedures, etc.) to produce a new one. Later you will learn about many
more operators and procedures, for manipulating strings, words, numbers,
lists (of many kinds) and even procedures for manipulating procedures.

By learning to program you can get computers to more things the way you
need them to be done, instead of using only software produced by others,
which may not meet your needs.

-- Choosing a programming language ------------------------------------

Some language designers think their languages are perfect for all tasks.

Others believe different languages are suited to different tasks. Pop-11
incorporates features from a fairly wide range of types of languages,
but does not claim to be best for all tasks. However, I think it is one
of the best for learning about a range of programming techniques and
styles. You'll then be ready to learn a variety of programming
languages, including procedural, functional, logical, rule-based, and
object oriented languages.

Each language provides some built in capabilities for performing a wide
range of relatively simple tasks. E.g. "+" and "<>" are built in to
Pop-11. You can use these simple tasks as building blocks for more
complex tasks. For example, later on in this file you will learn how to
start with instructions for drawing coloured blobs on the screen and use
those to perform the more complex task of drawing happy or sad faces.

Programming languages differ both in

    o the variety of simple capabilities they start with, and
    o the ways they allow you to combine instructions so as
      to create more and more complex capabilities.

There are many ways to combine instructions, and often different ways of
expressing complexity are suited to different problem areas. That is one
reason why there are so many programming languages, and why claims that
any one language is perfect for everything are always suspect.

In particular some languages are easy for machines to manipulate, e.g.
in checking that a program does what it is supposed to do, but are hard
for people to use to design new programs. Others (like Pop-11) are much
easier to use to design new programs, but harder for machines to
manipulate in order to do automatic checking. Life is full of difficult
trade-offs!

One of the most interesting aspects of the study of computer science and
AI is the investigation of new languages and tools which can simplify
the human task of instructing computers, or increase the efficiency or
accuracy with which instructions are carried out by the computer, or
reduce the risk of bugs in programs.

In the case of AI there is also the objective of telling machines how
they can work things out for themselves, instead of being instructed
about every detail. Our expectation is that machines will become
increasingly able to solve problems by analysing them, or performing
trial and error explorations, or generalising from previous solutions,
as people do. Later you'll learn some of the techniques relevant to
these and other objectives.

We do this both because it may enable us to make computers more useful,
and also because it may help us develop deeper and better theories about
how human minds work, how we analyse and interpret visual information,
how we learn and use language, how we make plans, how we absorb a
culture, how our motivation develops as we mature, why we are sometimes
emotional (and why some robots will be emotional), and so on.

An introductory course on AI cannot get very deep into these issues. But
getting started requires learning how to design computer programs that
perform increasingly complex tasks. For this you have to learn ways of
constructing complex programs from simpler ones.

Complex programs nearly always have "bugs" (as you may have learnt from
bitter experiences with many widely used packages and operating
systems). Often they are incomplete and only work for a subset of cases
you'd like them to work for. Moreover they also often have to be
combined with other programs, and then bugs can interact, and be hard
to diagnose.

So learning programming also involves learning how to find out

    o why programs go wrong,
    o how they can be generalised,
    o how they can be combined with other programs,
    o what sorts of problems come from complex combinations,

and much besides.

Learning Pop-11 is one good way to learn all this because Pop-11
incorporates many different program development styles, including some
of the simplest styles, e.g. giving a sequence of instructions, and
some of the most sophisticated, including: rule-based programming,
object-oriented programming, functional programming, event-driven
programming and some aspects of logic programming.

(There are a few other languages with similar generality, e.g. Common
Lisp, though many people without a mathematical background find Pop-11
easier to read. It seems to be mainly a matter of taste.)


-- Long term learning objectives --------------------------------------

Thus, starting from a simple core of Pop-11 you can gradually work
"outwards" in several directions, over several months, or even years,
learning more and more techniques which are found in a variety of modern
programming languages used in engineering, commercial and research
activities.

Above all you will stretch your mind in new ways. It will sometimes be
painful, because you will make many mistakes (everyone does), and you
may find your progress is much slower than you had hoped (there are
enormous differences in the rate at which different people take to
programming). But you should find it very stimulating, if you can put up
with the painful times.

Even if you never become a professional programmer, you will have learnt
what programming is about: the subject will have been de-mystified. You
will be better prepared for a range of jobs in which you have to deal
with programmers, select computing systems, analyse tasks in which
computers can be used. You may even become a good systems analyst
working with programmers by helping them to analyse the task objectives,
even if you don't write the programs. Or you may be good at writing
manuals and designing intelligent tutorial packages.

Some of you may become researchers in AI or computer science or
cognitive science, helping future generations to design amazing new
kinds of languages and machines and providing deep new insights into how
human and animal minds work.

-- Getting started ----------------------------------------------------

In order to use a language you have to use a "development environment".
There are many different sorts of development environments, which help
you write and edit programs, compile them test them, debug them and
document them.

One version of Pop-11 is to be found in the Poplog system, which has a
powerful development environment based on the editor Ved which enables
you to perform all the above tasks, first in simple ways and later using
more sophisticated techniques. This teach file introduces the simplest
way of using Ved to develop some programs that will make pictures of
various kinds.

(If you have written programs previously, and are used to an environment
where the editor, compiler, linker, debugger and user program are all
separate processes, forget about all that for now. Ved and Pop-11
combine all that functionality in one process, allowing INCREMENTAL
development and testing, using Pop-11's "incremental compiler". Pop-11
does NOT use an interpreter.)

First you have to learn to use the editor Ved. This is just a word
processor of a special sort. If you are reading this on a computer
terminal you may already be using Ved.  Some people use other editors
for Pop-11 programming, such as Emacs. However (at present) they are not
as well integrated with Pop-11, so it's best to start with Ved when
learning Pop-11.

There are two main ways of using Ved. One requires a workstation or X
terminal with graphical capabilities. You can then use Ved in
"multi-window" mode.

That is known as XVed because it uses the X window system which is
widely available on computers running the Unix operating system.

Alternatively you can use "ordinary" (dumb-terminal) Ved in a single
text window controlled entirely from the keyboard. This window can be
split horizontally so that you see more than one file at a time.

There are teach files that introduce Pop-11 in text-only mode, and you
will meet some later. This teach file is concerned with making pictures,
so you MUST use a graphical terminal with multiple windows.

It is likely that you are using XVed. However it will be referred to
throughout as "Ved" since the commands given below are the same for Ved
and XVed.

Ved can be used to create essays, stories, poems, letters, etc.,
manipulate fonts, format paragraphs, etc., like a word processor, but
its main strength is in helping you create and test and document
programs that you will develop. (It was used to create this file.)

Thus you must be prepared to learn new concepts that are relevant to
writing and testing programs but not writing essays.

This teach file introduces a subset of what you will learn later on. It
is one of many online "teach" and "help" files providing information
about Ved, about Pop-11, and about other languages in the Poplog system,
and about AI programming concepts and techniques.

Here you'll meet only a minimal subset to help you get going. As your
skills develop you can later learn to use more and more of the editor's
facilities to help you with your programming and production of
documentation. You'll also learn how Ved can provide rapid access to
online information about Pop-11, including "help" and "teach" and "ref"
files, and an easy way of looking at the program libraries. It can also
provide an interface for interactive programs, e.g. those that require
the user to type in questions, or answers to questions.

Ved itself is just a collection of programs written in Pop-11, and once
you are fluent in Pop-11 you can re-program portions of Ved to help you
with your tasks, e.g. creating pop-up menus to remind you of some of the
facilities you find most useful.

-- Introduction to Ved's keyboard control sequences -------------------

There is a separate file which introduces some of the ways of
controlling Ved, which you should now read. The printed version is
called TEACH USEFULKEYS, as is the online version. It explains how to
move the Ved cursor around, and how to ask Pop-11 to obey a command you
have typed in to Ved.

Before looking at that file, make a note of the line number you are
looking at in this file so that you can easily get back here later even
if you have to log out first and then log in again later.

You should now look at the USEFULKEYS file, as follows:

Press the ENTER key (far right of keyboard). The Ved cursor should jump
to the status line, above. Then type:
    teach usefulkeys

Then press the RETURN button. That invokes the teach file called
"usefulkeys". Read some of it to get the general idea, and make a note
of it to return to it later, when you need to develop more fluency with
the editor. Then you can leave that file and return to this one by
making sure the mouse cursor is in the file you want to leave, then
press and release the ESC key, and then press and release the "Q" key.
Reminder:

 ESC q  means  "quit the file the mouse cursor is in"


-- More on the "loadline" command -------------------------------------

Previously, you were introduced to Ved's "loadline" command, to compile
one line of Pop-11 using ESC followed by d. Here's an example that uses
four Pop-11 commands to print out some text. Try using "ESC d" with the
cursor on this line:

    pr('Hello there'); pr(space); pr(popusername); pr(newline);

It should print out a greeting followed by your login name.

The "pr( ... )" instruction is one of many printing commands in Pop-11.

Notice that in the first case it is given a string, 'Hello there' which
is printed exactly as it looks. In the other cases it is given
variables, "space", "popusername", "newline", which are treated as names
of objects known to Pop-11, and which are printed differently, depending
on the object referred to. The string is a pop-11 entity. The variables
refer to other entities.

The space and newline are not printed using any visible text. Later you
will learn more about formatted printing. For now, just note the
difference between a string which represents only itself, and a
variable, which represents something else, the value of the variable.

(Some variables will have different values at different times, as you'll
see later: hence the name "variable".)

Here's a different command. Use the Del or Delete key to remove the
XXXX and instead type in your own name between single quotes, e.g.
'joe' or 'suzy'. Then see what happens when you use ESC d on the line.

    pr('Hello there'); pr(space); pr(XXXX); pr(newline);


-- How does Ved's loadline command work? ------------------------------

When you give the loadline command by typing ESC d, the following
happens:
    1. the Editor takes the text in the current line (where the Ved
       cursor is), and hands it to the Pop-11 compiler, which, like Ved,
       is a sub-program in the poplog system.

    2. the Pop-11 compiler translates the line of text into machine
       instructions (which will depend on what sort of computer you
       are using) and asks the computer to obey the instructions.
       (It uses an "incremental compiler", which is very fast.)

    3. The computer obeys the machine instructions. This can perform
       a numerical calculation, create or manipulate symbols, create
       or manipulate files, send messages to another computer, read
       something from the terminal, draw pictures, etc. etc.
       Sometimes the instructions will require something to be printed
       out, e.g. a number or some text.

    4. If the command causes any "results" to be printed out, then
       Pop-11 passes the print instructions back to Ved

    5. Ved puts the text in a file called 'output.p' which should appear
       on your screen if it was not already there.

This diagram may help you remember the effect of giving a Pop-11 command
in Ved:

    Ved  -1->  Pop-11  -2->  computer  -3->  Pop-11  -4->  Ved -5-> file

Things can go wrong at any of these stages. E.g. at stage 1 your command
to Ved may be mistyped and Ved will give you an error message, or simply
"beep".

At stage 2, Pop-11 can find that the text is not grammatical (as
Pop-11), so it cannot translate it into machine code, and a
"compile-time" or "syntax" error will occur (sometimes shown on Ved's
status line).

At stage 3, the computer may find that the instructions cannot be
obeyed, e.g. because you have asked it to add a word to a number or
because you have tried to access a file which does not exist. This is a
"run time" error. A syntactically correct program can sometimes produce
a run time error.

It is rare for anything to go wrong at stages 4 or 5, but a problem can
occur if there is no longer any space in the computer memory for extra
text to be added to the Ved output file, or if something that happened
at an earlier stage caused the Ved files to be corrupted in some way.

Examples:

If you give the loadline command when the Ved cursor is not on a line of
"grammatical" Pop-11 it will give you stage 2 (compile time) error
message on the status line, and possibly print some "DECLARING VARIABLE"
messages in the 'output.p' file.

Try ESC d on a line in this paragraph. Look carefully at the error
message on the status line, before touching any keys, as the error
message on the status line (usually reporting "MISSING SEPARATOR")
disappears as soon as you press a key.

If you ask Ved to do something which is grammatical Pop-11 but which
Pop-11 does not yet know how to do you will get a stage 3, RUN TIME
error. E.g. try ESC d on the following line, which asks Pop-11 to add
the word "three" to the number 5.

    "three" + 5 =>

Look at the MISHAP message in the output.p file. You'll encounter many
of them during your adventures with Pop-11. Later, you'll learn what the
different bits mean.

-- Examples of use of loadline (ESC D) -----------------------------

Here are some more Pop-11 commands that you can obey with ESC D. Try
them but don't worry if they don't make much sense just now. Some will
do nothing because they are "comments". Some will cause a number or a
list of words to be printed in the output file.

    ;;; a line starting with ";;;" is a comment and is ignored
    ;;; find the square root of some numbers
    sqrt(16) =>
    sqrt(160) =>
    sqrt(1600) =>

    ;;; reverse a list of words
    rev([a b c d e]) =>
    rev([here i am]) =>

    ;;; find the length of a list of words
    length([the cat on the mat])=>
    ;;; or the length of a list of words and numbers
    length([99 66 the cat 105 on the mat 44])=>

    ;;; The print arrow "=>" prints out the "result" of a computation
    6 + 5 =>
    ;;; Join two lists together, and print out the combined list
    [the cat sat] <> [on a blue mat] =>

    ;;; Join three strings
    'the cat sat' <> ' ' <> 'on a @#$#@$ mat' =>


-- Compile-time and run-time errors -----------------------------------

    ;;; Some commands produce compile time error messages because they
    ;;; are grammatically incorrect Pop-11. Try this one
    rev [a b c d] =>

    ;;; There was probably a "beep" and an error message shown on the
    ;;; editor's "status" line (also known as the "command" line, for
    ;;; reasons that will become clear later.) If you did not see the
    ;;; error message. try ESC d again, on that line.

    ;;; What sort of error will this produce: compile time or run time?
    "six" + "five" =>
    ;;; that produces a "MISHAP" message in the output.p file. Later you
    ;;; will learn to read such messages very carefully, to get clues
    ;;; about what your program is doing wrong.

    ;;; What sort of error will this produce: compile time or run time?
    6 plus 5 =>
    ;;; Try it.

ALWAYS LOOK AT AND TRY TO UNDERSTAND YOUR ERROR MESSAGES. THAT IS PART
OF THE LEARNING PROCESS.

-- Marking a range of lines -------------------------------------------

Some Pop-11 commands cannot fit easily one line, including most
definitions of re-usable procedures, out of which you will construct
complex programs. So you cannot use ESC d (loadline) on those commands.

Previously you learnt how to get get Pop-11 to load (or compile) more
than one line by using the function keys F1 and F2 to "Mark a range" in
the file. You could then ask Ved to get Pop-11 to compile, or "load"
the Marked Range (lmr).

Put the Ved cursor on the line of asterisks below, e.g. using the arrow
keys to move to the location. You can tell Ved that is to be the
BEGINNING of a marked range by pressing F1. (There are other ways of
doing it if that doesn't work, e.g. ESC followed by m, or using a menu
invoked by the mouse). Make the next line the beginning of a range:
    ******

Now make the line of "+" signs, below, the end of the marked range. Move
the Ved cursor down to that line, and then press the key marked F2.
(or ESC M, i.e. ESC followed by SHIFT+M ):
    ++++++

You should now see a vertical bar on the left indicating the whole range
you have marked. You can use the ESC key followed by "g" or "G" to make
the Ved cursor "Go" to the beginning or the end of the marked range.

    ESC followed by g:  Go to Range Start
    ESC followed by G:  Go to Range End. (ESC then SHIFT+g)

Try marking different ranges of lines (using F1 and F2), and then use
those "Go to" commands.

There are many different things you can ask Ved to do with text or
commands in a marked range, including asking it to move the range,
delete the range, format the range, load (compile) the range, copy the
range to another file, send the range as an email message.

E.g. you can Transcribe(Copy) the marked range with the ENTER t command.
Mark a (short) range then put the Ved cursor on the next line and do
ENTER t. The range is copied to immediately after this line.

Later you can read TEACH MARK to find out more about marked ranges and
things you can do with them.

-- Load Marked Range: (ENTER lmr, or CTRL+d) --------------------------

Previously you learnt to get Pop-11 to comple a command which extends
over several lines. For practice, do it with these four lines:

    33 + 5 +
    99 + 270 + 33
    + 24 - 66 -100
    + 777 =>


Use either CTRL d or ENTER lmr. (Don't confuse ENTER and RETTURN).

The result of obeying that multi-line arithmetical command should appear
in the output.p file.

Here's a similar extended Pop-11 command. Mark the range and ask Pop-11
to load it (ENTER lmr, or CTRL+d):

    33 + 5 + (66 * 5)
    + 99 - (33 * 270) + 33
    + 33 - 66 - 100
    + 777 =>

Now change the command. Edit some of the numbers, using the arrow move
keys and the Delete key (often labelled "Del") (or if that doesn't work
use the BackSpace key). After changing some numbers repeat CTRL+d and
see how a different number is printed in your output.p file.

You can even try extending the calculation, using the RETURN key to
insert an extra line in the middle, so that you can put in some more
stuff like this.
    + 66*32 - 99*5


-- Summary: Ved and Pop-11 --------------------------------------------

Ved is an editor which is integrated with the program development tools
in the Poplog system. This means, for example, that in order to ask the
editor to perform a command written in Pop-11, all you have to do is
"mark" the portion of the file containing the command, using the
editor's "mark range" facilities, then ask it to load (or, in other
words, compile) the marked range.

Memorise this (with the help of notes on paper that you can look at
again):

    Mark start of range:    Use F1 key, or ESC m

    Mark end of range:      Use F2 key, or ESC M

    Load marked range:      CTRL+d or ENTER lmr

    Load one line:          ESC d

    Go to index or section: ENTER g

As you learn more Ved commands, add them to your notes.

There are MANY more things you can do with Ved, and there are hundreds
of online help files available and also printed documentation, giving
overviews. Later you will learn how to explore online HELP and TEACH and
REF files.

What you have learnt about Ved so far should suffice while you learn
more about programming. Later you can extend your knowledge of Ved to
make your programming work easier.

This can include learning how to use Ved to send mail to your tutor or
friends, and how to read mail. This will be specially useful when you
have programming queries.

-- Warning: Well-meaning "expert" friends can be dangerous ------------

Warning: you may have friends who are experienced programmers who will
try to teach you things not mentioned in the course, or who will try to
change your window manager or your login files. Beware: if you follow
their advice you may find that something carefully set up for this
course stops working.

Do not take such advice from anyone without first checking with your
course tutor that it is OK, unless you have already been on this course
for at least a month, so that you have learnt how to use our standard
environment, and you have enough previous experience to be able to undo
the changes if things go wrong.

Later, when you have more knowledge and more confidence, advice from
friends with more experience can be a major source of learning.


-- Pop-11 as a desk calculator ----------------------------------------

It should now be clear that it is very easy to use Pop-11 as a desk
calculator, as long as you remember the right formats. E.g. the next
command adds up five numbers, finds the square root of the total,
multiplies it by 60, and prints out the final result. Try the loadline
command on this:

    sqrt( 1 + 2 + 3 + 4 + 5) * 60 =>

Unlike most desk calculators: the combination of Ved and Pop-11 makes it
easy to go back and change one bit of the calculation and redo the rest.
E.g. you can change the "1" to 100" , or a "+" to a "-" then redo the
loadline command. But desk calculators are relatively boring.

Pop-11 allows you to do much more interesting things, including writing
programs that analyse sentences, make plans, search for solutions to
complex problems, etc. As a step towards learning more complex things
you can now try using Pop-11 to make some pictures.

First you will give simple separate drawing commands, and then you will
see how to group those commands into re-usable procedures.

You will also learn how to create a new file on the disc, containing
your own procedure definitions and commands, instead of using only
examples in this teach file.


-- What does Pop-11 know about? ---------------------------------------

The language Pop-11 has built in abilities to handle a variety of types
of objects, and its libraries, including libraries developed here at
Birmingham, extend those abilities.

In particular, it can handle, among many other things:

    words
           Examples are: "cat", "red", "asdfasdf", "Fred", "fred", ...
           Some words are used as variables which are names of other
           things (e.g. "space" and "newline" and names of procedures
           like "rev" and "length") while others are simply used as
           symbols manipulated by the program. Note that words use
           the double quote character: "

    strings
           These, like words, are composed of sequences of characters,
           but treated differently in subtle ways about which you will
           learn later. Strings use the single quote character:
           Examples are: 'cat', 'red', 'asdfasdf', 'Fred', 'fred',
           'space', 'newline', 'rev'. Strings can also contain spaces
           and combinations of characters which would not be allowed as
           legal words in Pop-11, e.g. '123asdf', '*&*&*&scat', and
           'the big fat &&&& dog'. Below, you will use strings to
           specify colours in drawing programs, e.g. 'red', 'blue'

    numbers
           These include positive and negative integers, such as 3, 99,
           and -5000, decimal numbers such as 0.655, -27.999, and other
           kinds of numbers which you may meet later.

    windows on the screen.
           These are objects which can be created, moved, deleted and
           have pictures drawn on them.

Other things you may learn about later include lists, vectors, arrays,
procedures, properties, classes, sockets, pipes, processes, and much
more. (Not all students will learn about all these things.)

Knowing about these types of things requires Pop-11 to have built in
procedures (commands) for creating them, manipulating them, combining
them, analysing them, printing them, etc. But different commands are
appropriate to different kinds of objects.

-- Making pictures in Pop-11 ------------------------------------------

You can now learn some commands that are relevant to making pictures.

This is a way of learning some of the syntax (grammar) of Pop-11, which
you will need to use in other contexts.

First you learn to give a command for starting up a graphical window,
then some separate commands for drawing things.

Then you will learn how a collection of commands can be grouped together
into a procedure which is given a name, so that you can use the name to
repeat the command, instead of re-typing all the separate commands in
the group. You'll see how giving the procedure "input variables" enables
it to do slightly different things each time it is invoked, e.g. drawing
the same picture at different locations on the screen.

Then you will learn how a procedure can be made even more general or
flexible by including a "conditional" instruction.

On the way you will learn some examples of "looping" constructs in
Pop-11. These allow you to construct one complex command, which repeats
a simpler instruction many times with slight differences each time.
There are several different forms of looping commands.

People who already have a lot of programming experience may like to read
the Pop-11 Primer to find out more about the range of facilities in
Pop-11. Beginners should wait until they have had a few weeks of
programming experience before reading the primer.

-- The "uses" command for ensuring that libraries are available -------

Some of the Pop-11 commands (e.g. the arithmetic operators for adding,
subtracting, multiplying numbers) are built in to the language.

Others are available as optional extensions in libraries in disc files
accessible from the computer you are using.

Some libraries are automatically accessed: they are "autoloadable". To
make the other libraries available you may have to use the "uses"
command, e.g. in the examples that follow there are these two commands
to make some libraries accessible.

    uses rclib;
    uses rc_window_object;

Note also that Pop-11 commands must normally end with either a
semi-colon, or the print-arrow, i.e. either ";" or "=>", or, in some
cases, "==>" which makes complex lists print in a more readable form.

What follows is a mixture of Pop-11 comments (preceded by ";;;") and
Pop-11 commands. Read the comments, and obey the one-line commands by
giving the LOADLINE command (ESC then d). Obey the longer commands by
marking the range (F1 and F2) and then giving the Load Marked Range
command (CTRL+d).


;;; First tell Pop-11 that you want to use the RCLIB library, which
;;; provides commands for drawing pictures. Load this line (ESC d):
uses rclib;

;;; You will also need the rc_window_object library, so load this line:
uses rc_window_object;

NB: you should make a note that if you leave VED and restart it later on
you cannot run the graphical examples below unless you have repeated
those two commands.

    uses rclib;
    uses rc_window_object;

-- Start a window and draw some circles -------------------------------

;;; You will shortly tell Pop-11 to make a graphical window called win1.
;;; When it appears you may have to move it so that you can go on
;;; reading this text. How you move the window will depend on the window
;;; manager you are using.

;;; Make a window to be referred to in Pop-11 commands as win1, with its
;;; top left corner at screen location 600, 10, and a width and height
;;; of 400 "pixels" (screen units). It should have 'WIN1' as the label
;;; on its title bar.

;;; Declare a variable called win1
vars win1;

;;; Create a window and use "->" to assign it to the variable win1

rc_new_window_object(600, 10, 400, 400, true, 'WIN1') -> win1;

;;; That command has two main parts: a bit to create a window, and
;;; "-> win1" which assigns the new object to the variable win1.

;;; Make win1 the current window object for drawing on:
win1 -> rc_current_window_object;

;;; Compare that with the previous assignment. Pop-11 assignments
;;; mostly go left to right, unlike many other languages. I.e. first you
;;; create or specify something, then you assign it.

;;; You can use the rc_move_to procedure to alter the location of the
;;; window win1, e.g. moving it to screen location (550, 5) with the
;;; following command;

rc_move_to(win1, 650, 5, true);

;;; The "true" at the end informs Pop-11 that you want the window to
;;; remain visible. Don't worry about it for now. The window manager
;;; may adjust the location slightly, if it thinks more space is needed
;;; for the "title bar".

;;; Note that location (0,0) is top left of the screen. (550,5) is
;;; probably somewhere just to the right of centre, near the top of the
;;; screen.

;;; In order to draw pictures in the window win1 we have to tell Pop-11
;;; where to draw in the window, just as we had to tell it where to
;;; put the window on the screen. That means using numbers as
;;; coordinates for points inside the window win1.

;;; The Pop-11 RC (Relative Coordinates) graphical library uses
;;; coordinates relative to a frame of reference which users can change.

;;; The window win1 has a "default" frame of reference with a horizontal
;;; axis (the X axis) in the middle with X increasing to the right, and
;;; a vertical axis (the Y axis) also in the middle with Y increasing
;;; upwards. The point where the axes meet is the "origin", the centre
;;; of the window in this case

;;; Use the following commands to get a feel for where different points
;;; are on the window win1 (not on the screen).

;;; Draw several little circles of radius 5, specifying the location
;;; using two numbers, the X coordinate and the Y coordinate.

;;; A circle in the middle, i.e. at the origin: X = 0 and Y = 0.
rc_draw_circle(0, 0, 5);

;;; A circle 50 pixels higher up (i.e. same X, but increased Y)

rc_draw_circle(0, 50, 5);

;;; A circle 50 pixels DOWN from the origin (i.e. decreasing Y)

rc_draw_circle(0, -50, 5);

;;; Now 100 units to the LEFT of the origin: x = -100
rc_draw_circle(-100, 0, 5);
;;; 100 units to the RIGHT
rc_draw_circle(100, 0, 5);

;;; Some points on the diagonal going up to the right. Do each of these
rc_draw_circle(10, 10, 5);
rc_draw_circle(50, 50, 5);
rc_draw_circle(75, 75, 5);
rc_draw_circle(100, 100, 5);
rc_draw_circle(125, 125, 5);


;;; Clear the picture
rc_clear_window_object(win1);

;;; Exercise:
;;; type in a command to draw a circle at location 25,25 with radius 3

;;; Now try points on the diagonal going up to the left
rc_draw_circle(-10, 10, 5);
rc_draw_circle(-50, 50, 5);
rc_draw_circle(-75, 75, 5);
rc_draw_circle(-100, 100, 5);
rc_draw_circle(-120, 120, 5);

;;; Try changing those commands to make the circles appear on the
;;; diagonal going DOWN to the LEFT from the centre, starting from
;;; location 0,0.

;;; Now try changing them to make the circles appear on the diagonal
;;; going DOWN to the RIGHT from the centre.

;;; Notice how points on a diagonal have the same numerical value for X
;;; and for Y, even though the SIGN may be different (e.g. one positive
;;; and one negative.

;;; Can you make a line of 5 circles go up to the right starting
;;; from one at location 30,0?

-- Giving a loop instruction ------------------------------------------

;;; It's tiresome giving lots of separate drawing commands to produce
;;; a collection of circles in a straight line. Instead we can use a
;;; Pop-11 "loop" instruction.

;;; Clear the window

rc_clear_window_object(win1);

;;; As a taste of things to come, we'll now introduce a Pop-11 "loop"
;;; command, a "for ... endfor loop". It starts with "for" and ends with
;;; "endfor". It does the same general command repeatedly but with a
;;; variable taking a succession of different values.

;;; A variable is a word that the user can introduce into Pop-11, and
;;; then assign a value to it which could be a number a list, a string,
;;; or any other kind of Pop-11 object. E.g. previously we introduced
;;; the variable win1, and assigned a window to it. Associated with
;;; each variable is something like a pigeon-hole which can have
;;; different contents at different times. More precisely, it is a
;;; location in the machine's memory which is associated with the word.

;;; Let's declare a variable x for use in the next looping command;

vars x;

;;; This variable will be given a succession of numbers as values.

;;; Now give a loop command using different values of x extracted from a
;;; list, but always a fixed value of y, i.e. 30. This is a four line
;;; command, so you will have to mark the range (F1, F2) and then load
;;; the range (CTRL+d).

for x in [-100 -75 -50 -25 0 25 50 75 100] do
    rc_draw_circle(x, 30, 5);
    syssleep(50);
endfor;

;;; Look carefully at the instructions and what they do. The command
;;; syssleep(50) tells Pop-11 to pause for 50/100ths of a second, i.e.
;;; half a second. That is so that you can see the individual circles
;;; being drawn. Note that there is a circle drawn for each value of x
;;; in the list, in square brackets, as if you had typed nine commands
;;; of the form
;;;    rc_draw_circle(-100, 30, 5);
;;;    rc_draw_circle(-75,  30, 5);
;;;    rc_draw_circle(-50,  30, 5);
;;; etc.

;;; If you try again without the syssleep command it happens very fast.
;;; E.g. clear the window and redraw
rc_clear_window_object(win1);
vars x;
for x in [-100 -75 -50 -25 0 25 50 75 100] do
    rc_draw_circle(x, 30, 5);
endfor;

;;; This occurrence of "vars x" was not really necessary, since the
;;; previous declaration of x is remembered, as it was a "global"
;;; declaration.

;;; However the declaration of x will not be remembered if you leave Ved
;;; and Pop-11, and start them up again later, e.g. after logging out
;;; and logging in.

;;; Try changing details in the for ... endfor range you have marked,
;;; then re-do the load marked range command (CTRL+d).
;;; E.g. change the 30 to some other value, e.g. 65, or -50 and try it
;;; again. You can also give the circles a different radius, e.g. 3
;;; instead of 5.

;;; You can also try putting different positive and negative numbers in
;;; the list between the square brackets, to give additional values for
;;; the variable x.

;;; What happens if you use the same value of x for both X and Y
;;; coordinates, i.e. changing the command in the middle line from
    rc_draw_circle(x, 30, 5);
;;; to:
    rc_draw_circle(x, x, 5);

;;; Go back and try that. Notice that Pop-11 doesn't care whether you
;;; use the variables called "x" or "y" or something else for the X and
;;; Y coordinates. E.g. you could use the word "fred" like this

vars fred;
for fred in [-100 -75 -50 -25 0 25 50 75 100] do
    rc_draw_circle(fred, fred, 8);
endfor;

;;; Notice the duplicated occurrence of "fred" in the drawing command.

;;; What about making the Y value 50% bigger than the x value by
;;; multiplying it by 1.5

rc_clear_window_object(win1);
vars fred;
for fred in [-100 -75 -50 -25 0 25 50 75 100] do
    rc_draw_circle(fred, fred * 1.5, 8);
    syssleep(50);
endfor;

;;; Note that Y increases by a bigger amount than X each time, so
;;; the line slopes more steeply upwards than before.

;;; Change that to draw smaller circles (e.g. replace 8 with 3 and
;;; then recompile the last four lines (from "for" to "endfor").

;;; Try other multipliers, e.g. 0.25 instead of 1.5, to make Y increase
;;; more slowly than X. What will that do to the slope of the line of
;;; circles?


-- Exercise: making a vertical line of circles ------------------------

;;; Can you do for Y what was done above for X, i.e. make the Y value
;;; change while X remains fixed? Declare a variable called "y"

vars y;

;;; and then construct a for loop with values of y coming from a list of
;;; numbers and x fixed at some number like 20, or -50? Copy the
;;; above loop command, between "for" and "endfor", and change
;;; the roles of x and y. You should be able to get a vertical row
;;; of circles drawn.

;;; Use this command to clear the window.

rc_clear_window_object(win1);

;;; If you wish to avoid typing in the whole command you can copy the
;;; original for ... endfor loop and then edit it. First go and mark the
;;; range you want to copy (using F1 and F2). Then come back here (e.g.
;;; use ENTER with the line number). Then put the Ved cursor at the end
;;; of this paragraph, and give the command "ENTER t". "t" stands for
;;; "Transcribe". I.e. it copies the marked range to immediately after
;;; the current line. Do that then edit the copied text, to keep X
;;; fixed and Y ranging over numbers in a list. Try obeying the modified
;;; loop, to see if it makes a vertical line of circles. If not, fix it.

;;; Ask for help if you get stuck.

-- Another exercise: what will this do? -------------------------------

;;; Look at the following and try to work out what it will do.
;;; Then mark and load the range.

rc_clear_window_object(win1);
vars x;
for x in [-125 -100 -75 -50 -25 0 25 50 75 100 125] do
    rc_draw_circle(x, 0, 5);
    rc_draw_circle(0, x, 5);
    syssleep(50);
endfor;

;;; try changing the order of the numbers in the list, and do it again.

;;; The exercises so far have been designed to help you get used to
;;;     (a) giving Ved commands of various sorts
;;;     (b) thinking about picture locations in terms of X and Y
;;;     (c) giving Pop-11 commands through the editor, using
;;;         loadline (ESC d) and load marked range (CTRL+d)

-- Avoiding explicit lists of numbers ---------------------------------

;;; In the drawing commands given above we used the format:
;;;  for x in <list> do <action> endfor
;;; In the list expression we typed the numbers to be used for values
;;; of x. Instead we can get the computer to work out the numbers.
;;; E.g. suppose we want it to use the numbers from -150 to +150
;;; increasing by 10, we can replace "in <list>", with the Pop-11
;;; sub-expression: "from -150 by 10 to 150", as follows, using "z" as
;;; a variable, just for a change.

;;; clear the window
rc_clear_window_object(win1);
vars z;
for z from -150 by 10 to 150 do
    rc_draw_circle(50, z, 5)
endfor;

;;; That should draw a vertical line of contiguous circles.
;;; Try changing it to draw a horizontal line of circles.

;;; Then try changing it to draw a diagonal line of circles sloping up
;;; to the right.

;;; Then try changing it to draw a diagonal line of circles sloping up
;;; to the left.


;;; Then see what happens if you increase the value "by 5" instead of
;;; "by 10". Try other variations, including using two different drawing
;;; commands (based on rc_draw_circle) in the middle of the loop.

;;; You'll learn fastest if you always experiment.


-- Re-starting after logging in ---------------------------------------

You may find it useful to make notes of the useful editor commands you
have learnt. include ENTER t for Transcribe in your notes.

Please memorise the following (with the help of notes):

    If you log out and leave the computer, then when you return you can
    restart Ved (or XVed) and continue with this teach file (giving Ved
    the command "ENTER teach faces"),

    You can get back to the text at a line number, e.g. line 1150, by
    giving the Ved command
        ENTER 1282

    Or go to a desired section by using this command:
        ENTER g

    When you re-start, you will also need to reload the libraries you
    have been using, with these commands:

        uses rclib;
        uses rc_window_object;
        ;;; Later you'll learn to store them in a file, for easy
        ;;; re-use

    And you can re-create a window in which to draw pictures
    with commands like these two:

        vars win1
            = rc_new_window_object(600, 10, 400, 400, true, 'WIN1');

        win1 -> rc_current_window_object;

-- Starting up your own file ------------------------------------------

So far you have given Pop-11 commands only by marking and loading
examples in this teach file. However, when you log out any commands you
have typed into this file will be forgotten.

It is useful therefore to create your own file, on the computer's hard
disc drive, in which you can store commands that will still be there
when you next log in. That makes it much easier to re-do those commands
next time.

You can create a file called 'faces.p', which will be in your own
directory, i.e. a portion of the magnetic disc that is associated with
your login name, and which you can access easily whenever you log in.

When creating Pop-11 program files it is desirable to use the
two-character file suffix '.p' in the file name, because that will
enable the editor to recognize the file as containing Pop-11 commands,
and therefore give you more help.

Create a new file called 'faces.p' with this command

    ENTER ved faces.p

I.e. press the ENTER key. That moves the Ved cursor to the "status"
line, then type the remaining characters shown, and then press the
RETURN key to tell Ved that your command is complete.
This will start up a blank file called 'faces.p'. You can later use Ved
to put programming commands and explanatory text comments in there.

A useful Ved command when you are switching between files is the
SWAPFILES command, consisting of ESC followed by x. Try it a few times
and see what happens. (Add "ESC x" to your list of useful commands to
memorise. Alternatively you can select a file by moving the mouse
cursor into it and clicking on button 1.)

After starting the blank file, ensure that the Ved cursor is in that
file, and give the command

    ENTER fileheader

This will create a file header with some information about the file,
which you can edit and complete later on. (This may not work if you are
not using Ved at Birmingham.)

The header will be enclosed in Pop-11 comment symbols, starting with
"/*" and ending with "*/". Later you can create your own comments
enclosed between those symbols.

Note: Pop-11 has two sorts of comments.
  ";;;"
    introduces  an "end of line" comment. Everything to the right of it
    in the same line is ignored by the compiler.

  "/*" .... "*/"
    Are comment brackets. Everything between them is ignored by the
    compiler. That can include text extending over many lines or part
    of a line.

Edit the parts of the header that have "???". At this stage it is not
really important what you put there.

Below the header (after the "*/"), you can insert the following lines,
which can be marked and loaded every time you want to use the picture-
drawing facilities in this file. Read on to see how to transfer these 9
lines to your new file:

;;; Set up graphical libraries
uses rclib;
uses rc_window_object;

;;; Create a window in which to draw pictures
vars win1 = rc_new_window_object(600, 10, 400, 400, true, 'WIN1');

;;; Make win1 the current drawing window.
win1 -> rc_current_window_object;

-- Copying text from another file: ENTER ti ---------------------------

An easy way to insert all those Pop-11 commands in your new file without
having to type them in is to mark them and copy them in, as follows.

1. Mark the complete range of commands (e.g. using F1 and F2).
2. Move the Ved cursor to the new file (e.g. ESC x)
3. Give the "Transcribe In" command: ENTER ti

That should copy the marked range from the last file the Ved cursor was
in, namely this file. If it doesn't work, ask for help.

You should now have a file called 'faces.p' with a header produced by
the "ENTER fileheader" command, followed by some commands to load
libraries and start a new window and make it current.

The file will automatically be saved on the disk from time to time, but
as a precaution you can force it to be saved by asking Ved to "write
all your files". Put the cursor in the new file and do

    ENTER w

From now on type all your Pop-11 commands into the new faces.p file.
Also remember the ENTER ti (transcribe in = copy in) command as it will
often be useful later on.

The next few sections assume you are using a screen which can handle
coloured pictures. If you are using one that handles only black and
white then most colours will come out black. However we are mainly
going to use only two colours, i.e. 'red' and 'blue'. So if you
change 'blue' to 'white' in all the examples, they should work on a
monochrome terminal.

-- Drawing coloured blobs ---------------------------------------------

;;; clear the graphics window before proceeding.

rc_clear_window_object(win1);

;;; Before moving on to making faces, let's look at a useful drawing
;;; procedure which is different from rc_draw_circle.
;;; rc_draw_blob takes four arguments, an X coordinate, a Y coordinate,
;;; a radius and a string representing a colour name. The format is
;;;     rc_draw_blob(<number>, <number>, <number>, <string>)

;;; E.g. try this:

rc_draw_blob(0, 0, 35, 'pink');

;;; Can you predict what these commands will produce?
rc_clear_window_object(win1);
rc_draw_blob(0, 120, 120, 'grey');
rc_draw_blob(0, 60, 60, 'red');
rc_draw_blob(0, 30, 30, 'white');
rc_draw_blob(0, 15, 15, 'blue');

;;; Try changing the numbers and redo the commands if you
;;; don't understand what's happening.

;;; You can also draw hollow squares and rectangles, of specified
;;; location, size, colour, and linewidth, as follows. Again, things
;;; will be different if you are using a black and white only terminal.
;;; So when the squares overlap make some 'black' and some 'white'

rc_clear_window_object(win1);
;;; square at location (0, 0), side 40, colour green, linewidth 5
rc_draw_centred_square(0, 0, 40, 'green', 5);

;;; different location, size, colour and linewidth
rc_draw_centred_square(100, 100, 60, 'pink', 35);

;;; rectangle at location (-100, 50), width 200, height 50,
;;; colour yellow, linewidth 10
rc_draw_centred_rect(-60, 55, 200, 50, 'yellow', 10);
rc_draw_centred_rect(-60, 55, 50, 20, 'blue', 5);

;;; Notice that a complex pop-11 command can be spread over several
;;; lines, like this (mark and compile it (CTRL+d) at least 20 times):

rc_draw_blob(
    0, 30,
    random(150),
    oneof(['red' 'green' 'yellow'])
    );

;;; Notice that the colour is randomly chosen from 'red', 'green',
;;; 'yellow', and the size is a random number between 1 and 150

;;; What about this next one -- try it repeatedly, using load marked
;;; range over all five lines (F1, F2 to mark, then CTRL+d):

rc_draw_blob(
    random(200) - 100,      ;;; random x coordinate
    random(200) - 100,      ;;; random y coordinate
    random(100),            ;;; random diameter (max 100)
    oneof(['red' 'green' 'blue' 'white' 'yellow' 'orange' 'black']));

;;; Do it as often as you like, till you get bored, noting what
;;; happens when one blob partially obscures another of a different
;;; colour. We'll use that later in making faces.

;;; Look at that command carefully. Each of the X and Y coordinates was
;;; created at random using the following instruction, which uses the
;;; Pop-11 random number generator and produces a random number whose
;;; value is always between -99 and 100. Why?
;;;     random(200) - 100
;;; The radius was a value between 1 and 100 created using:
;;;     random(100)
;;; The colour is chosen at random by the oneof procedure from the
;;; list of colour names (all strings) given to it as input.

;;; If you wish, try changing the numbers or adding new colour names,
;;; e.g. 'azure' 'beige' 'cyan' 'gold' 'ivory' 'khaki'
;;;      'lavender' 'magenta' 'navy'
;;; The list of colour names can extend over several lines, as long
;;; as the list starts with "[" and ends with "]" (list brackets).
;;; (Not all colour names that you know will be understood by the
;;; computer, but most will. To get a list of known colours do:
;;;     ENTER HELP xcolours RETURN)

;;; You have just used a complex Pop-11 expression, in which a
;;; procedure (rc_draw_blob) is given several inputs (sometimes called
;;; "arguments") which themselves use complex expressions.

;;; This illustrates one of the ways in which Pop-11 can construct
;;; complex commands from simpler ones, by "functional composition",
;;; in addition to the obvious method illustrated previously, namely
;;; using a sequence of simple commands.

;;; You will learn many ways of constructing more complex commands
;;; from simpler ones.

;;; E.g. Try putting "repeat 40 times" in front of that command and
;;; "endrepeat" after it.


-- Making a face ------------------------------------------------------

;;; That experiment should have given you some idea of what happens if
;;; you draw coloured blobs on top of one another. In particular you get
;;; some interesting crescent shapes. We'll now aim to produce a face,
;;; using one big red blob for the whole face, two small blue blobs
;;; for the eyes, and a red and a blue blob to create a blue crescent
;;; for a smiling mouth.

;;; But first clear the window

rc_clear_window_object(win1);

;;; Draw a red blob of radius 70 pixels in the centre (location 0,0)
rc_draw_blob(0, 0, 70, 'red');

;;; draw a couple of smaller blue blobs (radius 15), at locations
;;; (-35, 15) and (35, 25), to make eyes.
rc_draw_blob(-35, 25, 15, 'blue');
rc_draw_blob(35, 25, 15, 'blue');

;;; Question: can you turn that into a face with a blue smiling mouth?
;;; One way is to draw a blue blob, centrally below the eyes, then
;;; blot out part of it with another red blob which will blend with
;;; the "background" of the red face.

;;; On monochrome, make the first blob white, then the second black,
;;; to blend with the black background.

;;; See if you can construct two commands to produce such a crescent, by
;;; putting numbers in place of x1, y1, r1, x2, y2, r2 in these two
;;; commands (NB you can't run them till you replace the names with
;;; numbers):

rc_draw_blob(x1, -y1, r1, 'blue');  ;;; or 'white'
rc_draw_blob(x2, -y2, r2, 'red');

;;; You can always go back to this command to clear
;;; the picture and start again:
rc_clear_window_object(win1);

;;; Here's a possible way to make a smiling mouth:
;;; Try these two commands.
rc_draw_blob(0, -25, 35, 'blue');
rc_draw_blob(0, -15, 35, 'red');

;;; Look at the blue crescent at the bottom. Now do both again,
;;; replacing 'pink' with the background colour, 'red'.
;;; See how you get a smile? Does it make you smile?

;;; You may wish to experiment with different combinations of sizes and
;;; locations till you are happy with the result. Don't make your face
;;; too big since later you'll be asked to make several faces in the
;;; same window.

;;; Clear the window and try to make a sad face.
rc_clear_window_object(win1);

;;; Now redraw the blank red blob plus two blue eyes:
;;; Draw a red blob of radius 70 pixels in the centre (location 0,0)
rc_draw_blob(0, 0, 70, 'red');
;;; Draw the two blue eyes.
rc_draw_blob(-35, 25, 15, 'blue');
rc_draw_blob(35, 25, 15, 'blue');

;;; Can you use the same techniques as before to make a SAD
;;; face with a drooping mouth, i.e. curving down, not up?
;;; Try putting numbers in place of x1, y1, r1, x2, y2, r2 in these
;;; two commands (they will not work till you put in numbers):
rc_draw_blob(x1, -y1, r1, 'blue');
rc_draw_blob(x2, -y2, r2, 'red');


;;; When you have chosen your values for the six numbers, compare the
;;; effects of your commands with these two (drawing the big red blob
;;; with two blue (or white) blobs for eyes):
rc_draw_blob(0, -30, 30, 'blue');
rc_draw_blob(0, -40, 30, 'red');

;;; Once again, if you can't see what's happening try replacing 'red'
;;; with 'pink', then go back to 'red'.

-- Creating procedures for parts of faces -----------------------------

What if you want to show both a happy face and a sad face at the same
time? At present your drawing instructions don't make that possible
because they occupy the same location. We can produce a new version of
each face which is capable of being drawn more than once, in different
locations.

For that we need the following ideas.

1. A group of instructions can be collected together in a procedure
   which which performs all the instructions. For this you'll need
   to learn to use the Pop-11 "define .... enddefine" syntax.

2. We can make the procedure take in two numbers specifying a location
   for the centre of the face. Then different faces can be drawn in
   different locations using the same procedure.

3. Both the happy face and the sad face have a common part consisting of
   three instructions (draw the big circle, draw the left eye, draw the
   right eye).

We'll do this in stages.

-- Defining fixed_eyes ------------------------------------------------

;;; To introduce the idea of a named procedure we'll start with a simple
;;; one which merely draws the big circle and the two eyes. We'll call
;;; the procedure fixed_eyes (Pop-11 allows alphabetic characters to be
;;; joined by the underscore character "_" to make a long word. So we'll
;;; call the procedure fixed_eyes rather than fixedeyes or FixedEyes,
;;; both of which could be used.)

;;; Define a procedure which takes no inputs, and draws three blobs
define fixed_eyes();
    rc_draw_blob(0, 0, 70, 'red');
    ;;; change the next two to 'white' for monochrome
    rc_draw_blob(-35, 25, 15, 'blue');
    rc_draw_blob(35, 25, 15, 'blue');
enddefine;

;;; This defines a RE-USABLE procedure called fixed_eyes. If, after
;;; compiling it you try to run it with the Pop-11 command
;;; "fixed_eyes();" it will perform the instructions in the three lines
;;; in the "body" of the definition.

;;; You can mark that procedure definition, and compile it using LMR,
;;; or, instead, to save time, put the cursor in the middle and do
;;; ESC c. That invokes Load Current Procedure (lcp), and works only if
;;; the Ved cursor is inside a procedure definition. The definition must
;;; start with "define" with no spaces to the left of the "d".

Remember:   ESC c = "load/compile current procedure" (= ENTER lcp).

;;; After compiling the procedure, clear the graphical window
rc_clear_window_object(win1);

;;; Invoke fixed_eyes
fixed_eyes();

;;; Thus one command now does what was previously done by three.

;;; Two more commands (remember them?) will produce a similing face, or
;;; a sad face. We'll add those in a more ambitious procedure later.

-- Defining located_eyes ----------------------------------------------

;;; We are still stuck with a procedure that draws only in one place.

;;; So let's introduce a definition of a procedure, called located_eyes,
;;; which will take information about the location of the centre of the
;;; face, in the form of two numbers. Call them x and y. We use those
;;; two numbers to specify where to draw the big circle, and then we
;;; have to make the locations of the two small circles RELATIVE to the
;;; centre of the big circle.

;;; How?  When the big circle had its centre at location (0, 0), the
;;; left eye had its centre at (-35, 25), i.e. 35 units left and 25 up.

;;; So if the big circle has its centre at (x, y) the left eye has its
;;; centre at (x - 35, y + 25). Where is the right eye?

;;; See if you can complete this definition. Put it in your file called
;;; faces.p. Replace the two occurrences of "????" with appropriate
;;; Pop-11 expressions for computing the X and Y coordinate of the right
;;; eye.

define located_eyes(x, y);
    ;;; draw the main circle for the face, centred at (x, y)
    rc_draw_blob(x, y, 70, 'red');
    ;;; draw the left eye, radius 15
    rc_draw_blob(x - 35, y + 25, 15, 'blue');
    ;;; draw the right eye, radius 15
    rc_draw_blob( ????, ????, 15, 'blue');
enddefine;

;;; When you have finished typing in the proper expressions, you can
;;; compile that whole procedure, using LMR, or ESC c.

;;; Then test it by drawing faces with a pair of eyes in various
;;; locations, after clearing the window. (This will produce a "mishap"
;;; if you have made a mistake in your procedure. If so fix it!)
rc_clear_window_object(win1);
located_eyes(0, 0);
located_eyes(120, 120);
located_eyes(-120, -120);

;;; If you get a mishap and cannot understand it, ask for help.

;;; Can you make it appear in the top left and bottom right corners
;;; of the window?

-- Using located_eyes to define smile_face ----------------------------

;;; Can you guess how to define a procedure called smile_face, which
;;; has this beginning and end, which you should copy into your file
;;; called faces.p (somewhere after the definition of located_eyes).

define smile_face(x, y);
    ;;; draw a happy face centred at location (x, y)

    ?????

enddefine;

;;; What should go in place of the question marks. See if you can
;;; complete the definition, using the procedure located_eyes, followed
;;; by two invocations of rc_draw_blob to make the mouth. Look back to
;;; see how you previously made a smiling mouth composed of a blue blob
;;; and a red blob which left a blue crescent, thus:
    rc_draw_blob(0, -25, 35, 'blue');
    rc_draw_blob(0, -15, 35, 'red');

;;; You'll have to modify those two commands to make them draw RELATIVE
;;; to whatever location is given as x and y.

;;; If you manage to complete the definition of smile_face, try it out
;;; in various places in the window.

rc_clear_window_object(win1);
smile_face(0, 0);
smile_face(120, 120);
smile_face(-120, -120);
smile_face(0, -120);


;;; If you had difficulty completing the definition of smile_face,
;;; compare the following with your attempts at defining smile_face.
;;; Copy this definition into your faces.p file.
;;; Then compile it (using lmr, or ESC c), then test it with the
;;; commands above.

define smile_face(x, y);
    ;;; draw a happy face centred at location (x, y)

    ;;; Start with full face and two eyes
    located_eyes(x, y);

    ;;; Add a crescent mouth
    rc_draw_blob(x, y - 25, 35, 'blue');
    rc_draw_blob(x, y - 15, 35, 'red');
enddefine;

;;; Compile your definition, then try the test commands above.


-- Defining sad_face --------------------------------------------------

;;; Using the same method as for smile_face, try defining sad_face, also
;;; relative to two input values, x and y, specifying a location in the
;;; window.

define sad_face(x, y);
    ;;; draw a sad face centred at location (x, y)
    ?????
enddefine;

;;; Part of the definition will be the same as for happy face, and part
;;; will be different.

;;; When you have completed your definition of sad_face, in your file
;;; faces.p, test out a mixture of happy and sad faces, with commands
;;; like these:

rc_clear_window_object(win1);
sad_face(0, 0);
smile_face(120, 120);
sad_face(-120, -120);
smile_face(0, -120);
sad_face(-120, 120);

;;; If you have difficulty completing the procedure sad_face, ask for
;;; help

-- Using a conditional expression in a procedure ----------------------

;;; It will often be useful to define a procedure which is flexible in
;;; that it does not always do the same thing, but decides what to do by
;;; testing some condition.

;;; For example, here is a procedure which uses a conditional expression
;;; based on the time of day, to decide whether to say 'good morning'
;;; 'good afternoon' or 'good evening'. It implicitly defines two
;;; variables "person" and "time", used for inputs to the procedure.

define greet(person, time);
    ;;; person is a string, time a number representing the time,
    ;;; using the 24 hour system

    ;;; Start the greeting with appropriate words, followed by the
    ;;; name of the person, joined using the concatenator "<>"

    if time < 12 then
        'good morning ' <> person
    elseif time < 18 then
        'good afternoon ' <> person
    else
        'good evening ' <> person
    endif =>

enddefine;

;;; Compile that procedure definition, and then test it with
;;; the following commands:

greet('fred', 8);
greet('suzy', 19);
greet('mary', 14);

;;; Try using other times, and your own name, between the single
;;; string quotes.

;;; See if you can insert another line starting "elseif" which
;;; makes it say things like
;;;     ** you are working late fred
;;; if the time is after 10pm (i.e. > 22).

;;; Notice that the bit following "else" is the DEFAULT action,
;;; which is taken only if all the preceding conditions fail.
;;; The conditions are tested in order. If one is satisfied, its
;;; action is performed, and the processing jumps to just after the
;;; occurrence of "endif".

;;; Now we return to making faces, using a conditional expression to
;;; control the choice of mouth.

-- Combining two face types using a conditional expression ------------

;;; You've probably noticed that the definitions of procedures
;;; smile_face and sad_face, start off with the same command:
;;;    located_eyes(x, y);
;;; followed by different commands for drawing the mouth.

;;; Instead of having two different procedures which are partly the
;;; same, it is sometimes useful to define a single procedure which can
;;; do both jobs. But you then need an additional piece of information
;;; to give the procedure to tell it which job is to be done. Thus we
;;; could define a new procedure called "make_face" which instead of
;;; only two inputs, the numbers, x and y, takes three inputs, the third
;;; one, called type, being a word: "happy" or "sad".

;;; To do this we need to use a conditional instruction in the
;;; procedure, similar to the conditional instruction in procedure
;;; greet above. E.g. make_face could use an instruction of the form
;;;     if type = "happy" then
;;;         ????
;;;     elseif type = "sad" then
;;;         ????
;;;     endif;

;;; Where the "????" bits will be replaced by instructions for drawing
;;; the happy mouth or the sad mouth.

;;; Copy this partial definition into your file faces.p
;;; after the other procedure definitions.


define make_face(x, y, type);
    ;;; draw the main face and eyes at location x,y
    located_eyes(x, y);

    ;;; now add appropriate type of mouth, depending on
    ;;; which word has been given for "type"
    if type = "happy" then
        ;;; add a crescent mouth
        rc_draw_blob(x, y - 25, 35, 'blue');
        rc_draw_blob(x, y - 15, 35, 'red');
    elseif type = "sad" then

        ????????

    else
        ;;; Cause a mishap message if the face type is not
        ;;; recognized
        mishap('Unrecognized face type', [^type])
    endif;
enddefine;

;;; Now edit the portion marked "????????", so as to draw the
;;; sad looking mouth, using the instructions you previously used
;;; in defining procedure sad_face

;;; When you have completed the definition, compile it, and test it
;;; with the following commands and similar commands. Note that we
;;; here use the double-quote symbol to indicate that the input is a
;;; word, not a string (for now don't worry about the difference).

rc_clear_window_object(win1);
make_face(0, 0, "happy");

make_face(0, 0, "sad");

make_face(-100,-100, "happy");

make_face(100,-100, "sad");

;;; You can make a constantly changing face picture if you wish, using a
;;; "repeat .... endrepeat" command, like this, using syssleep to
;;; produce pauses of 60/100 seconds (0.6 seconds).


rc_clear_window_object(win1);

repeat 10 times
    make_face(0, 0, "happy");
    syssleep(60);
    make_face(0, 0, "sad");
    syssleep(60);
endrepeat;



;;; What happens if you ask for a type of face that is not recognized?

make_face(0, 0, "angry");

;;; It starts drawing the face, and then finds that it cannot complete
;;; the face, and triggers the "mishap" instruction.
;;; Later you may have time to add more face types that are recognized,
;;; by adding more "branches" to the conditional expression.

-- Using lists to describe a scene ------------------------------------

So far you have created faces by directly giving commands using
procedures like rc_draw_blob, located_eyes, smile_face, sad_face, or the
more general procedure make_face.

If you wanted to specify in a more descriptive form what sorts of faces
you wanted you use lists of words and numbers. For example, you could
use a list containing two numbers and a word, to specify a location and
a type of face, as in:

    [100 -100 sad]

In Pop-11 the square brackets "[" and "]" can be used to make list
structures, containing sequences of arbitrary objects, including
embedded lists.

The above expression denotes a list containing two numbers, 100, -100
and a word "sad". Inside a list expression you don't need to put the
double quotes around words as you did when you invoked the procedure
make_face, e.g. in the form

    make_face(100, -100, "sad");

because in a list words are automatically quoted by default: they refer
to themselves. Thus the third element of the list [100 -100 sad] is the
word "sad".

Outside a list, words in Pop-11 normally refer to something else, e.g.
procedures, syntax forms, or the values of variables, e.g. the variables
"x" and "y", used above in expressions like this:

        rc_draw_blob(x, y, 35, 'red');

In this context, the words refer to numbers. If we had used "x" and "y"
in that context, i.e.

        rc_draw_blob("x", "y", 35, 'red');

it would have produced a complaint that numbers were needed, whereas the
two words "x" and "y" were provided.

Anyhow, for now all you need to remember is that between the list
brackets you do not need to put the double quotes around words if you
wish the words to be quoted, i.e. refer to themselves.

(Later you'll learn how to make words refer to their values instead of
to themselves in a list).

-- Making a list of face specifications -------------------------------

So if you want to specify a collection of faces of different types in
different locations you can create a list of lists. E.g. we can declare
a variable called faces, and assign a list of lists to it, thus:

vars faces;

[ [100 -100 sad] [100 100 happy] [-100 100 sad] [-100 -100 happy]
    [0 0 happy]] -> faces;

;;; Start copying the following into your faces.p file.

;;; Pop-11 allows a declaration plus assignment to be abbreviated to
;;; a single "initialised declaration", thus:

vars faces =
    [ [100 -100 sad] [100 100 happy] [-100 100 sad] [-100 -100 happy]
        [0 0 happy]];

;;; Mark and load that and then print out the list faces:

faces =>

;;; or using the double print arrow, which formats the printing
;;; differently:

faces ==>

;;; ("=>" is the print arrow, "==>" the "pretty print arrow")

-- Making a procedure to draw lots of faces described in a list -------

We can now begin to define a procedure which we could call something
like "make_all_faces" to take a list like the above (i.e. faces), and
then draw all the faces specified.

It needs to select face description at a time, i.e. one list of the
form:

    [<number> <number> <word>]

at a time, and use the previously defined procedure make_face with those
three items.

I.e. we are aiming towards a command of the form

    make_all_faces(faces);

which will be defined so as repeatedly to invoke commands of the form

    make_face( ... , ... , ... );

The basic idea is simple. We'll build a procedure using the Pop-11
construct
    for <variable> in <list> do <action> endfor;

which you previously encountered in a format like this

for x in [-100 -75 -50 -25 0 25 50 75 100] do
    rc_draw_circle(x, 30, 5);
endfor;

I.e. the variable takes each element of the list in turn as its value,
and then that value is used in the command (or commands) between "do"
and "endfor". However, now each element of the list is going to be a
more complex structure, another list, describing a face. I.e. the
format will be something like this.

We'll declare a variable that is local to our new procedure, called
face, using this declaration:

    lvars face;

And then we'll make that variable take one list at a time from the list
of lists, i.e. using a "for ... endfor" loop of this form.

    for face in lists do
        ....draw the face....
    endfor;

However, in order to draw the face we have to extract the elements of
the face description. But that's easy. If the variable face refers to a
list which has three elements, then

    face(1)     refers to the first element
    face(2)     refers to the second element
    face(3)     refers to the third element

Check this out, by compiling the following

rc_clear_window_object(win1);
vars face = [50 -100 sad];

make_face(face(1), face(2), face(3));

I.e. the last command was equivalent to

    make_face(50, -100, "sad");

So we can now use the following format to define make_all_faces

define make_all_faces(facelist);
    ;;; facelist is a list of lists, where each list contains
    ;;; three elements specifying a face, two numbers and a word

    lvars face;
    for face in facelist do
        ;;; ???? you fill in this bit ????
    endfor

enddefine;

Copy that to your faces.p file and try to complete the bit in the
middle.

Then try testing it

rc_clear_window_object(win1);
vars faces =
    [ [100 -100 sad] [100 100 happy] [-100 100 sad] [-100 -100 happy]
        [0 0 happy]];

make_all_faces(faces);

You could also try a different, bigger list of face descriptions,
drawing lots of faces, including overlapping faces.



-- More drawing primitives for more types of faces --------------------

If you are feeling adventurous, and have time to spare, you can try
extending the procedure make_face with additional "elseif ... then ...."
clauses, i.e. extra conditions and extra actions, to make it draw
additional sorts of faces, with different kinds of mouths, or extra
facial features. E.g.

    elseif type = "angry" then
        ....
    elseif type = "neutral" then

If you add new types make sure you test each one.

Various psychologists have studied ways in which emotions are expressed
in facial expression, or recognized when we see faces. (I suspect there
are considerable cultural influences.)

In creating additional face types you may find it useful to employ
additional commands for making pictures.

You have already met these two procedures:

rc_draw_centred_rect(x, y, side, side, colour, width)
rc_draw_centred_square(x, y, side, colour, width);

    These two procedures draw squares or rectangles centred around the
    location (x, y). The lines are drawn using the specified colour (a
    string, or false) and width (a number or false).

Here are some additional drawing commands you may find useful

rc_draw_bar(x, y, height, len, col);
    Draw a horizontal bar of given height, length and colour starting at
    location x, y (middle of left end).

rc_drawline(x1, y1, x2, y2)
    Draw a (thin line of the current default colour, usually black)
    from point (x1, y1) to point (x2, y2)

rc_draw_square(x, y, side);
rc_draw_rect(x, y, width, height);
    Draw a square or rectangle with top left corner at location (x, y),
    of specified side, or width and height.

The last two procedures use the current default drawing colour for the
window. Usually that is black.


-- Exercise: Making colours and sizes variable ------------------------

This exercise may be difficult if you have no previous programming
experience, or have not really understood how procedure definitions
work.

You have seen in the procedures located_eyes, smile_face, make_face, how
it is possible to provide location inputs (x and y) which are used along
with some fixed information about relative sizes and colours to draw
pictures.

If you wish you can define modified versions of those procedures
in which you replace some of the fixed numbers and colours with
variables, which are then provided as inputs when the procedure is run.

This requires using more "input" variables in each procedure, and
careful changes to the internal commands to make them use the inputs
properly. (Inputs are sometimes called "arguments" for historical but
not logical reasons.)

The simplest change would be to change the procedures to accept two
additional inputs which are strings used as colour names, to replace
'red' and 'blue' throughout. They could be 'skin_colour',
'feature_colour'. Or you could use separate colours for eyes and mouth.

If you have not run out of time for this part of the course, try
generalising the procedures.


-- What next? ---------------------------------------------------------

You have now got to the end of your basic introduction to programming,
using the editor Ved and the language Pop-11. There is a great deal more
that you can learn about the editor, about the language, and about
programming in general.

You could also spend many happy hours learning about additional
graphical commands which can be used to make pictures, and Pop-11
instructions for making a graphical window respond to actions performed
with the mouse, which can be useful for designing computer games,
control panels, etc.

For example, try marking and loading all this, to see how Pop-11
can be used to make a control panel, with text fields and action
buttons:

uses rc_control_panel;

vars panel;

rc_control_panel("left", "top",
    [
        [TEXT :
            'Demonstrating an automatically'
            'formatted graphical panel']

        ;;; some action buttons
        [ACTIONS {cols 2} {width 100} :
            ['TEACH RIVER' 'teach river']
            ['HELLO THERE'
                [INVED
                    'HELLO THERE ' <> sysgetusername(popusername) =>] ] ]

        [TEXT : 'Another action button' ]
        [ACTIONS {width 80}: {blob 'DISMISS' rc_kill_panel} ]
    ], 'DEMO WINDOW') -> panel;


However, if you are on a course with limited time you'll need to focus
your efforts, and move on to more important (and more challenging)
tasks, as well as learning more basic techniques.

In particular you need to learn a bit more about the editor, including
learning how to send and receive email using it. There are other email
interfaces but if you learn to use Ved you can more easily ask for help
with programming problems because you can easily include your Pop-11
commands and any error messages, or puzzling bits of teach files.

You can get more practice using Ved, and learn how to send and read
email using this teach file:
    TEACH RHYME

Practice doing things with marked ranges in this file:

    TEACH MARK

If you find it hard to remember commands for compiling a line of text, a
procedure, a marked range, you could give the Ved command
    ENTER menu compiling

which will bring up a menu which you can use to select the compilation
command or other commands, using the mouse.

The next programming teach file to look at is

    TEACH RIVER

which introduces a problem solving task, and instructions to get the
computer to solve the task. This will partly repeat things you have
already learnt, and partly add some new information, about the Pop-11
database.

After that look at

    TEACH RESPOND

which introduces several more programming techniques and shows you how
to define an "Eliza" program that appears to be able to hold very simple
conversations. That introduces a collection of new ideas, including the
idea of a program that interacts with the user using the
procedure readline in an endless loop, and the very important notion of
using a pattern matcher to recognize and analyse list structures.

Additional exercises and projects will continue extending your grasp of
programming in general, Pop-11 programming in particular, and Artificial
Intelligence concepts and techniques. These include

    TEACH MATCHES
    TEACH DATABASE
    TEACH GRAMMAR
    TEACH RIVER2
    TEACH RIVERCHAT
    TEACH TOWER
    TEACH RULEBASE
    TEACH OOP

and many more. Most students can't get through all of this in their
first term of programming, so later on you'll make a selection to suit
your needs and abilities.

After you have had more experience getting to know Pop-11 you may find
it helpful to get a copy of the Pop-11 primer, and read it to get a
better overview of the language. A printed version of the primer is
available for a small charge from the librarian in the school of
computer science. There is also an online version, TEACH PRIMER. Do
not try to print the online version as it will waste a huge amount of
paper.

A useful introduction to AI and Cognitive Science, based on Pop-11, can
be found in the very readable book:

    Mike Sharples, M. et al.
    Computers and Thought, MIT Press, 1989

-- Working at home ----------------------------------------------------

If you have a powerful PC with at least 16 (preferably 32 or more)
Mbytes of memory, and you have a lot of spare disc space, then you could
consider obtaining the linux operating system to use on your PC. You can
get it free, but installing it can be tricky and you may need help from
an expert friend, or perhaps a computer dealer. Once you have Linux you
can switch the PC between Linux and Windows.

If you have Linux then you can also get a copy of Poplog, the teaching
system used for this course, and also copies of all our online teaching
materials. That will enable you to do some of the work at home, which
may be specially useful when you are doing your project, though
initially you will need to work in the lab to get help from
demonstrators.

Since July 1999 all versions of Poplog, including Poplog for Linux, are
available free of charge, and can be fetched by FTP from this site:

    http://www.cs.bham.ac.uk/research/poplog/freepoplog.html

Aaron Sloman.


--- $poplocal/local/rclib/teach/faces
--- Copyright University of Birmingham 2000. All rights reserved. ------
