TEACH REVISE.ANS                                       A.Sloman Oct 1998
                                                Last updated 21 Oct 2000

         CONTENTS - (Use ENTER g to access required sections)

 -- Introduction
 -- Question 1: Logging in and out, files
 -- Question 2: Keys, control keys, keyboard
 -- Question 3: Procedures and files
 -- Question 4: Compile time and run time mishaps
 -- Question 5: More mishaps?
 -- Question 6: Analyse a buggy procedure definition
 -- Question 7: Lengths of lists
 -- Question 8: Boolean expressions
 -- Question 9: Fix and explain a buggy procedure
 -- Question 10: Output locals
 -- Question 11: Program libraries
 -- Question 12: Pop-11 data types
 -- Question 13: Matcher and database utilities
 -- Question 14: Loops
 -- Question 15: vars and lvars
 -- Question 16: Case-sensitive search in Ved
 -- Question 17: Case insensitive search in Ved
 -- Question 18: Searching and substituting with patterns in Ved
 -- Question 19: More on format of files and procedure definitions

-- Introduction -------------------------------------------------------

Here are some answers to the questions in TEACH REVISE. The answers
are separated by quite long gaps to reduce the risk of your reading
the answers to questions you have not yet read.

You can get VED to cross a text gap forward or backward by using the
WORDRIGHT and WORDLEFT keys. These functions are usually mapped onto the
two keys at the bottom of the right hand numeric keypad.

    WORDRIGHT key is marked "." and "Del" usually
    WORDLEFT  key is marked "0" and "Ins" usually

Alternatively you can use the following key sequences

    WORDRIGHT   ESC f
    WORDLEFT    ESC b

Try using WORDRIGHT to cross the gap after this sentence, and WORDLEFT
to come back.


You are strongly advised to write down, or think out in complete detail,
the answer to each question before you read the answers below. Otherwise
you will probably not learn anything from this exercise. Whereas if you
produce your own answers and compare them with those below you will
learn something from the differences. In some cases there are no
definitely right and wrong answers. If you find any typos or anything
unclear please report it by email to A.Sloman, quoting the relevant
bit of the file. (Easy in Ved: use a marked range and "ENTER sendmr").


-- Question 1: Logging in and out, files ------------------------------

(1.a) What does 'logging in' mean?

Inform the computer of the account you wish to use, and start running a
command interpreter or window manager associated with the directory
owned by that account. The account has a user name, and a password.
When you log in various startup files are run to set environment
variables and in some cases start a window manager with your preferred
initial configuration.
(Use WORDRIGHT to get to next answer)


(1.b) What does 'logging out' mean?

Tell the computer to close down all the processes you are currently
using at your current terminal, except those you have deliberately left
to run in the background using "&". If you are using a window system
(e.g. X) you can usually log out by killing the window manager, e.g. by
clicking on an EXIT window if one is provided. The window manager asks
all "clients" to kill themselves. Unfortunately some of them don't do
this and the result can be that a program is left running, and
constantly trying and failing to communicate with the terminal, which is
no longer possible if the user's login session has ended. The worst
culprit is Netscape, but it sometimes happens to Xved and to other
utilities, e.g. Emacs, Pine. So always terminate every process before
you click on EXIT.

It is possible to be logged in on more than one terminal. Logging out on
one terminal should not interfere with the processes you have running on
another, even if both terminals are logged in to the same machine.


(1.c) What is a directory?

Our computers store information (e.g. files, with text, programs,
databases, images) on magnetic discs, which keep their data even when
the machine is switched off. The information in the disc system belongs
to different users. Typically the file system is divided in a
hierarchical fashion into directories containing files and other
directories which contain files and other directories, and so on.

A directory is a region of the disk that has files in it, which may be a
set of files belonging to a particular individual, or a set of files
associated with a particular program or collection of programs. For
example, there will be a directory containing the main poplog system,
and it will have different sub-directories for its help files, teach
files, library files, files related to Pop-11, files related to Prolog,
etc. Each user has a "login directory" containing all the user's files
and sub-directories. If the user's login name is "xyz" then other people
can refer to the directory as ~xyz. Each user can refer to his/her own
login directory as ~, but not when telling other people where to look
for files.


(1.d) What is a file?
A portion of the information on the computing system which has a name,
is located in a directory, and can be treated as a single unit, e.g.
printed, read into the editor, moved to another directory etc. The
contents of a file could be program text for a language like C or Pop11,
shell commands, documentation, images, executable programs, a database,
among other things.


(1.e) Why is it recommended that you use names ending with '.p' for
    files containing end Pop-11 program definitions, e.g. 'respond.p'?

    What difference does it make if you don't use such a name, e.g. if
    you call the file just 'respond'?

If you use the file suffix '.p' that tells the poplog editor Ved that
the file should contain Pop-11 programs. This tells it which compiler to
use when you give compile commands (e.g. not the compiler for Prolog, or
Lisp or ML, each of which uses its own suffix). It also tells Ved not to
break long lines automatically when you type them in, and it tells Ved
what sort of formatting style to use when you give "justify" commands,
e.g. ENTER tidy, or ENTER jp. If you omit the suffix Ved will think you
are editing a plain text file and this may sometimes produce unexpected
results.


-- Question 2: Keys, control keys, keyboard ---------------------------

(6) Some keys on the keyboard transmit characters that can be printed,
some modify the signals sent by other keys, and some send their own
signals which are not printing characters. Give an example of each
type of

Modifier keys: SHIFT, CTRL, META, ALT

Other keys;    ESC, all the main keys, most function keys


(7) Which key or key sequences do you press

    a. to delete the last character typed in

Depends how your system has been set up. Usually the Del or Delete key
does this. Sometimes Backspace does it. (Sometimes Backspace works like
the left arrow, not like Delete.) At Birmingham we have set Backspace in
VED to do deletion, for new users. This change is made in your vedinit.p
file.


    b. to delete the whole of the current line

Depends how your system has been set up. Often Control U. It can be
done using the key F4, or the key F3 if you simply want to delete
everthing to the left of the VED cursor. (This is the keyboard setup at
Birmingham. Ved may work differently in other places.)


    c. to delete the word to the left of the cursor

Depends how your system has been set up. Often Control W. It can also
be Control K control B   (^K ^B). In Birmingham we also set the function
key F6 to delete the word on the left. What about key F7?

See HELP XTERMKEYS, HELP VEDKEYS


    d. to quit a VED file

The quickest way is: ESC q


    e. to compile one line of program

LOADLINE is usually set to ESC d


    f. to compile a procedure definition

EITHER
    ESC c

OR
    ENTER lcp
    (load current procedure)


    g. to compile a marked range

In Ved this (VED_LMR) is set to  ^D. You can also do
ENTER lmr, or use the "compiling" menu.


    h. to compile a whole file

ENTER l1

NOTE
If you find it hard to remember those VED commands for compiling, you
can use the ved "compiling" menu. Do
    ENTER menu compiling

or select the "Compiling..." option in the toplevel menu.

(Or read TEACH VEDNOTES, and do a lot of practice.)


ADDITIONAL USEFUL KEYBOARD COMMANDS:

    1. to interrupt a program, e.g. when it is stuck in a loop.

Usually Control C, but it depends on how you have set things up in your
login file.


    2. to abort a program completely

Different defaults are used for this "quit" command.
You have probably had this set to Control \ or possibly Control Y. (It
can be changed using the "stty" unix command.)

Note that if you type the quit command while VED or XVED is running it
should abort your program and do a "setpop". However if it doesn't stop
the program you can type it twice in quick succession. It will then
abort the program and also kill the editor. so if you have not saved
your files recently you'll lose some work.

Your vedinit.p file should include a line something like
    5 -> vedautosave_minutes;       ;;; Frequency of saving

This means that after a crash or quit you should not have wasted more
than about 5 minutes work.

You can change the 5 to 2 if you'd like it to save every 2 minutes.


    3. to signify 'end of file' (to Unix)

Usually set to Control D, but on some systems it may be Control Z
(e.g. VAX VMS)




-- Question 3: Procedures and files -----------------------------------

3.1. What are the differences between creating a new procedure and
creating a new file? (There are several differences.)

[These are approximate answers. For different programming languages, the
answers might be slightly different.]

Files are stored on the disk when you log out or leave the editor.

Procedures when compiled are in the memory used by your pop-11 process.

(In other languages compiled procedures can go into machine code or
binary files, after which they have to be linked. In pop-11 you can
store previously compiled procedures in a saved image.
See HELP SYSSAVE, HELP SYSRESTORE).

A procedure definition is some text in a file. When it is compiled it is
a record in the computer of machine code instructions derived by
translating the definition.

A file can contain many procedure definitions.
A procedure definition must contain legal pop-11 instructions (though it
may also contain comments). A file can contain anything.

A file may consist of nothing but pop-11 instructions. If you load it
the instructions will be obeyed, but there will not necessarily be in
the computer a complete record of the instructions. If you load
(compile) a procedure definition the instructions will not be obeyed,
though a record of them in machine language will be stored. You have to
invoke the procedure later on to get the instructions obeyed, usually
with some additional information in the form of arguments.

Both have names but the names are known to different parts of the
system. The pop-11 system knows about all the procedure that have been
compiled, but not about all the files on the disk. (It can find out
about them.) The operating system knows about the files, but knows
nothing about the procedures in your program.

Files (on unix) are located in a directory and have path names.
procedures are not related to directories. They have names that are
pop11 words, not file path names.


3.2. What do procedures and files have in common?

They can both contain instructions. They can both be re-used.


3.3. Explain what happens when a procedure definition (e.g. your
procedure RESPOND) is read in by the POP11 system.

    In particular, what happens to the POP11 dictionary?


It's actually quite complicated. The procedure name will (normally) be
declared as a global variable and added to the dictionary, unless it was
already there (e.g. when recompiling). The instructions in the procedure
definition are translated to machine code and a procedure record
containing those instructions is created in the heap. The procedure name
is given as its value the procedure record, so that it can be used later
to invoke the procedure.

The process of translation from text to machine instructions has several
stages. One is breaking up the stream of text characters into "lexical"
items, i.e. words strings and numbers. Pop-11 has its own rules for
doing that. Then there is syntactic analysis to make sure that the items
form a legal program. If some of the items are "macros" or "syntax
words" they can temporarily take control of the analysis. The final
stage is creating the machine instructions. Various kinds of errors can
occur during lexical analysis or syntactic analysis. For more
information see
    TEACH STACK
    TEACH VM
    REF POPCOMPILE
    REF PROGLIST

See also the Pop-11 PRIMER


3.4. If you want to "tidy" or "justify" a procedure definition (produce
indentation showing the structure of the procedure) what command should
you use?

Justify current procedure is

                ENTER jcp


3.5 For the "compile procedure", or "justify procedure" command to work
in Ved, the word "define" at the beginning of the definition needs to be
in the right place. Where?

Against the left margin. I.e. "define" must
NOT be indented, like this

    define silly();

I should be like this:

define silly();

This means that if a teach file contains a procedure definition which is
indented, then if you copy it into your program file, you should
immediately de-indent the first like, so that VED commands, ESC c
and ENTER jcp will work on the procedure definition.


-- Question 4: Compile time and run time mishaps ----------------------

What is the difference between a compile time error and a run time
error?

Compile time errors occur during lexical analysis (e.g. missing string
quote), or during syntactic analysis (e.g. missing separator, missing
closing bracket, unexpected syntax word). Run time errors happen after a
procedure has been created and you have invoked it. E.g. trying to add a
word and a number, or applying a list procedure to a non-list.


Explain what is wrong with each of the following, and whether it
involves a compile time or a run time error:

    (a)     add [steve is happy];

"add" is not an infix operator, so this is syntactically incorrect and
will produce a compile time error. Fix it thus:

        add([steve is happy]);


    (b)  3 -> [x];

A list cannot be the target of an assignment. This will produce a
compile time error. This would work but not achieve anything useful:

    3 -> [x](1);

    3 -> hd(x);


    (c)     [3] * 5 =>

A run time error. You cannot multiply a list by anything.


    (d) x -> 10;
A compile time error. A number cannot be the target of an assignment.

Note, however, that if the variable list holds a list of 10 or more
elements then the Pop-11 command

    x -> 10.list;
is equivalent to
    x -> list(10);

and will store the value of x in the 10th location in the list,
overwriting whatever was there before.


    (e)     if x == 3 then x => endwhile;

Compile time syntax error: needs "endif".


    (f)     define fred(x, y;
                [silly] =>
            enddefine;


Compile time syntax error: missing ")" in header


-- Question 5: More mishaps? ------------------------------------------


NOTE: where there is nothing wrong the example is described as "OK".
You should nevertheless work out what would be printed out by each
command and then try it to check.


What do the following print out? Explain the mishap messages (if any)
if you can.

    (a) 1 + 2 * 3 =>

** 7


    (b)     vars x; [if] -> x; x =>


OK. Try it


    (c)     vars if; [x] -> if; if =>


Compile time error. You can't declare "if" as a variable, since it is a
syntax word.


    (d)     vars x = sqrt(16); x*x =>

OK


-- Question 6: Analyse a buggy procedure definition -------------------

The following procedure is meant to take a list containing a name and produce
as its result a list containing a greeting including the name. What is wrong
with it? (There is more than one thing wrong!)

        define greet([name]) -> x;
            [pleased to meet you name] -> x;
        enddefine;


You can't have square brackets in the header of a procedure, even if the
argument is expected to be a list.

If you want the value of the variable "name" to be included in the list
that's created, use "^" before "name"


-- Question 7: Lengths of lists ---------------------------------------

TEACH ARROW will help you with this question.

The procedure LENGTH when given a list produces as its result the number of
things in the list. When given a word, LENGTH returns the number of
characters in the word.

What are LENGTHs of the values of the following expressions?


ANSWERS are not given here since you can apply length to each
expression, e.g. Try

    length([a b c]) =>

    length([abc]) =>


    (a)     [a b c]

    (b)     [abc]

    (c)     [ [a b c] ]

    (d)     [ ]

    (e)     [list6]

    (f)     [6list]

    (g)     ["a"]

    (h)     [ % "a" % ]

    (i)     After the instruction [a b c] -> list;
            what are the lengths of these lists:
                [^^list ^^list]
                [^^list ^list]
                [^list ^list]
                [[^^list]]
                [[^^list] ^list]
                [list]

What is the result of applying LENGTH to the result of each of the following:

    (j)     tl([a b c d])

    (k)     hd([cat on mat])

    (l)     hd([ [a b c] ])

    (m)     hd(tl([a b c]))

    (n)     tl([ [a b c] ])


-- Question 8: Boolean expressions ------------------------------------

Which of the following are true?


NOTE: you can work out the answer yourself, by evaluating the expression
(on a separate line) followed by a print arrow, with ESC d (LOADLINE),
e.g.
     1 + 2 * 3 > 1 * 2 + 3 =>
     ** <true>
     [this list] = [this list] =>
     ** <true>

    (a)     1 + 2 * 3 > 1 * 2 + 3;

load this line to test it:
    1 + 2 * 3 > 1 * 2 + 3 =>

and so on...
    (b)     [this list] = [this list]

    (c)     [this list] == [this list]

    (d)     [this list] matches [that list]

    (e)     [this list] matches [??that list]

    (f)     [1 + 2] matches [3]

    (g)     [ % 1 + 2 % ] matches [3]

    (h)     [ % 1 + 2 % ] == [3]

    (i) [A B] <> rev(tl([C D E])) matches rev([E D C] <> tl([A B]))

    (j) [A B] <> rev(tl([C D E])) matches rev([D E] <> tl([C B A]))

    (k) "x" = x


Try the above again, after each of
    vars x = 99;
    vars x = "x";

    (l) isword(x)


Try the above again, after each of
    vars x = 99;
    vars x = "x";


    (m) isword([])

    (n) isword([x])

    (o) isword(hd([x]))

    (p) isinteger("three")

    (q) isinteger(33 + 55)

    (r) isinteger(33 * 55)

    (s) isinteger(33 / 55)


for more on the last one read TEACH ARITH, or HELP MATH


-- Question 9: Fix and explain a buggy procedure ----------------------

Explain what is wrong with the following procedure definition,, correct
it and say what it then does.


    (a) define smaller(numa, numb) -> ans;
              if numa > numb then
                  numb -> ans
              else
                  numa
            enddefine;


There is no assignment to ans if the condition is false. I.e. the else
clause should be

        numa -> ans

There's a missing "endif" before "enddefine"


Now correct these tests:

    (b)     smaller(5, 6) =>

Nothing wrong with that.


    (c)     smaller(10 6) =>

Missing comma.


    (d)     smaller(4;4) =>

Use "," not ";" as expression separator in an argument list.


-- Question 10: Output locals -----------------------------------------

Q. What is an 'output local' variable?

Answer:
It is a variable, indicated by "->" in a procedure header, whose value
is left on the stack when the procedure terminates. There may be more
than one output local variable, e.g. using this syntax:

        define fred(input1, input2) -> (result1, result2, result3);

See TEACH STACK for more, or Chapter 3 of the PRIMER.


Q. Explain the meaning of '-> zzz' in

    define xxx(yyy) -> zzz;

Answer: this procedure header defines zzz as an output local variable of
the procedure xxx (see above).


Q. What happens if nothing inside the procedure definition assigns any
value to the output local (e.g. to zzz)?


Answer: in that case the value of zzz on exit from the procedure is
undefined, and it could be any junk that happened to be in the portion
of memory allocated to that variable. That junk will be left on the
stack when the procedure exits. On Suns, the default value of an
uninitialised output variable will typically be the integer 0. On
Digital alpha machines it could be anything that was previously in one
of the machine registers. That can cause obscure bugs. So make sure
that you always give your output local variables a value.


Q. .... i.e. complete the following

    vars p, q, r;
    powers_of(99) ->


powers_of(99) -> (p, q, r);

;;; test that

p,q,r =>


or, equivalently

powers_of(99) -> r -> q -> p;

    (See TEACH * STACK, or chapter 3 of the Pop-11 Primer.)


Q. Try completing the definition of powers_of:

define powers_of(x) -> (xsquare, xcube, xfourth);
    x*x -> xsquare;
    xsquare*x -> xcube;
    xcube*x -> xfourth
enddefine;

Note: the output local variables and the input variable are all
automatically declared as "lvars", i.e. lexically scoped local
variables. For more on what this means, and the differences between
local and global variables, see

    TEACH VARS_AND_LVARS


-- Question 11: Program libraries -------------------------------------

11.a What is the difference between these two Pop-11 commands.

    lib river
        Search the directories held in the variable popuseslist to see
        if there is a file called 'river.p', and if there is, compile
        it. If there is no such file, produce an error message.
            ;;; MISHAP - LIBRARY FILE NOT FOUND

    uses river
        Check to see if the variable river has already been declared
        and given a value. If so do nothing more. Otherwise do the same
        as "lib river". Thus the "lib" command ALWAYS compiles the
        library even if it has already been compiled in the current
        session. The "uses" command doesn't recompile if they library
        has already been compiled (and defines a variable or constant
        with the same name as the library).


11.b Which VED command can be used to examine a library file?

    ENTER showlib <filename>
e.g.
    ENTER showlib river

    ENTER showlib eliza


11.c What is the difference between an autoloadable library and a
     non-autoloadable library?


If an identifier is defined by a file in an autoloadable library then
you do not need to use "uses" or "lib" to ensure that they library is
compiled. e.g. "present" is in an autoloadable library and therefore if
you use a command of the form

    if present([ ....]) then

when the compiler finds the word "present" and notes that it is no
already declared (in the dictionary) as a variable, then it looks
through the directories in the list popautolist to see if there is a
file called present.p. If there is it compiles that file, even though
the user has not explicitly requested compilation using "lib" or "uses".
Autoloadable libraries make certain extensions to Pop-11 seem like parts
of Pop-11.


Names of directories containing autoloadable libraries are in the list
popautolist. The list popuseslist includes the things in popautolist and
also some other directories containing libraries which are not
autoloadable.


11.d What does the "ENTER sourcefile xxx" command do?
     (See HELP SOURCEFILE)

If "xxx" is the name of a procedure in one of the Pop-11 libraries, and
you want want to look at the definition of the procedure, you can use
    ENTER sourcefile xxx

The ved_sourcefile command looks to see if the argument "xxx" is in one
of the indexes in the pop-11 library, and if it is there, that index
tells Pop-11 which library defines xxx. That library file will be read
into Ved.


11.e. Why should the "uses" and "lib" commands appear at the beginning
of a file, not in the middle or at the end?

The "uses" and "lib" commands are used to load library files. If your
program uses a library file then the file should be compiled *before*
your procedures are compiled, otherwise you will get
    DECLARING VARIABLE
warning messages.

More importantly, in some cases the library will define an EXTENSION
to the syntax of Pop-11 and you must compile the library before you use
the extended syntax. Otherwise your programs will not compile. For
example if your program uses Poprulebase, that provides new syntax for
defining rulesets. Then you must have
    uses poprulebase
at the top of the file (or in another file which you always compile
first).


11.d. What is wrong with the following:


    define river_solve();

        lib river;

        start();
        .......
        .......
    enddefine;


A "lib" or "uses" command is used to compile a library. It should be
used at the top of the file BEFORE your procedure definitions commence.
If you included a lib command in a procedure definition it will attempt
to compile the library EVERY time the procedure runs, which is almost
certainly not what you intended. (It could be required in some special
cases.)


-- Question 12: Pop-11 data types -------------------------------------

12.1. Try writing down from memory a list of all the different types of
objects a POP11 program can refer to.

Start with: words, numbers, ....


See the Primer, Chapter 2 for an introduction. For a more complete
overview look at REF DATA (experts only)


12.2. What are the different kinds of numbers in Pop-11. (See HELP MATH)

Answer:
integers, bigintegers, decimals, ddecimals, complex numbers, ratios.


12.3. The Pop-11 concatenator <> (infix operator) can be used to
concatenate several different types of pop-11 objects, e.g. two lists,
two strings. Which others?

Two vectors, two words, two procedures.

Examples:

            [a b c] <> [d e f] =>
            'a b c' <> 'd e f' =>
            {a b c} <> {d e f} =>
            "tea" <> "spoon" =>
            sqrt <> sqrt =>

The last one produces a procedure which if applied to a number returns
the square root of its square root, i.e. the fourth root, whereas the
next one creates a procedur which takes the square root of a number then
rounds the result.

            sqrt <> round =>

    vars rounded_root = sqrt <> round;

    rounded_root(9) =>
    ** 3
    rounded_root(10) =>
    ** 3
    rounded_root(13) =>
    ** 4


-- Question 13: Matcher and database utilities ------------------------

Explain what the following do.

    matches

This is a procedure which takes a list and a pattern as input and
produces a boolean result.

The pattern is just another list which may contain pattern elements,
including =, ==, ? and ??.

When the procedure runs it compares the list and the pattern according
to the matcher rules. If the list matches the pattern the result of the
of the procedure is TRUE, otherwise FALSE.

A "side effect" of running the matcher is that some variables in the
pattern may be given new values, derived from the contents of the list.

"matches" is an infix operator.


    add
This is a procedure which takes a list as input and produces no result.
As a side effect it adds the list to the list held in the global pop-11
variabel called "database." It is not an infix operator, since it is
used in the format:
    add(list);


    remove
This is a procedure which takes a pattern as input and produces no
result.
As a side effect it will remove an item in the pop11 database which
matches the pattern. If nothing matches a mishap will result.

Compare the procedure flush(<pattern>), which removes EVERYTHING in the
database that matches the pattern, and produces no mishap if nothing
matches.


For the next three items see HELP DATABASE
    present

    lookup

    flush

For the next item see HELP MATCHES
    -->
This is an infix operator.


Which of the above procedures make use of MATCHES?
    matches
    remove
    present
    lookup
    flush
    -->


See HELP MATCHES, HELP DATABASE

Harder: Explain what "!" does when used before a pattern.


-- Question 14: Loops -------------------------------------------------

14.1. If you want a program to loop forever, obeying a sequence of
instructions, which words should go before and after the instructions?

    repeat ..... endrepeat


14.2 Which instruction can be used to make Pop-11 jump to the next
instruction after the end of a loop?

    quitloop();


14.3 Which instruction makes Pop-11 jump to the end of a procedure?

    return();


14.4 Explain the difference between the following, assuming "x" has
previously been declared as a variable.

    for x in [a b c d e] x=> endfor;

    for x on [a b c d e] x=> endfor;

Answers:
    for x in .... do
        This assigns each element of the list in turn to x

    for x on .... do
        This assigns first the whole list to x, then its tail, then
        the tail of the tail, etc. and eventually the empty list.

    See HELP * FOR


-- Question 15: vars and lvars ----------------------------------------

15.1 What is the difference between vars and lvars?


The full difference is very complex. Both can be used inside or outside
a procedure definition. If a variable is declared outside any procedure
definition (i.e. at top level) using vars then it is global and can in
principle be accessed by any other part of the program (unless you use
sections, as described in HELP SECTIONS). If a variable is declared at
top level using lvars, then it can be accessed only in the same file,
not in other files.

Inside a procedure
    vars x;
        Makes the variable x local to the procedure only in the sense
        that any changes made to x while the procedure is running are
        undone when the procedure finishes. It is still possible for
        other procedures to access that variable x as a global
        procedure.

    lvars x;
        Makes the variable x "lexically" local to the procedure. I.e.
        nothing outside the procedure can possibly access that variable.
        Normally pattern variables [ ...?x ... ??x ...] will not be able
        to access the variable x if it was declared as lvars. However
        if the pattern is preceded with "!", then the pattern variables
        inside a procedure will be lvars.

        Using lvars for local variables makes it much less likely that
        your program will have obscure bugs. See TEACH * VARS_AND_LVARS


15.2 What sort of bug is avoided by making local variables in a
procedure lvars rather than vars variables?

Suppose
    1. a procedure F declares a variable using "vars x;"
    2. another procedure G in which x is not a local variable has
       an instruction like "99 -> x;"

Then when F is running x will have some value. If F calls G, or calls
some other procedure which (eventually) calls G, the execution of the
assignment to x by G, may change the value of x in F, which is probably
not intended. (This will not happen if F calls H, which declares x
locally using "vars x;" and H calls G. Instead the problem will occur in
H, not in F!).

If a procedure F uses "vars" to declare a local variable, then any other
procedure using that variable as NON-LOCAL can interfere with the value
of the variable in F if F is on the procedure call stack at the time.
These unwanted interactions caused by "dynamically scoped" local
variables are a common source of bugs. The problem cannot occur with
"lvars" variables.

However, sometimes exactly that kind of interaction is useful when a
variable is used to control the environment in which things occur, e.g.
the current output channel, the current database, etc. That is why
Pop-11 supports the use of local "vars" in special cases. (In older
versions of Pop-11 only "vars" was supported, not "lvars". That's why
some of the older text books, and some of the older teach files still
use "vars" for local variables, alas.)

A full understanding of all this requires an understanding of the
mechanisms used by dynamically scoped local variables (vars).
See TEACH * VARS_AND_LVARS


15.3 What difference does "!" make to a pattern used with the matcher.

Putting "!" before a pattern used in a procedure definition makes the
pattern variables work like lvars variables. I.e. they cannot be
accidentally updated by other procedures. See HELP * READPATTERN
for more information.


15.4 In the following procedure definition

    define silly(w, x, y) -> z;
        w * x * y -> z
    enddefine;

Some variables are automatically declared. Which are they? Are the
declared as "vars" or as "lvars". Which is the output local variable?

Answer:
w, x, y, and z are all automatically declared. Since Poplog Version 15.0
they will all automatically be declared as "lvars". Previously they
would have been declared as "vars".

    w, x, and y are "input locals", also known as "arguments" or
                    "formal parameters"

    z is an "output local".

    See TEACH * VARS_AND_LVARS


15.5 What kind of mistake can produce a compile time warning message of
the form:
;;; WARNING DECLARING PATTERN VARIABLE person AS LVARS


answer:
If you define a procedure which uses the variable "person" in a pattern,
and you use the "!" pattern prefix, e.g. in a conditional expression
like this:

    if list matches ![ ?person likes me] then ....

then you need to define "person" as a local variable of type "lvars",
inside the procedure before that pattern occurs. E.g.

    lvars person;

    if list matches ![?person likes me] then ....

If you don't do that, you will get a warning during compilation, when
the pattern is read in. It is not strictly an error since the pattern
will be compiled AS IF the lvars declaration had been there. But if you
thought you were accessing a global variable your program will not work.

Note: the pattern prefix "!" can occur in many other contexts, e.g.

    lookup(![?person likes ?another]);

also with present, foreach, etc. I.e. it is not restricted to
conditionals.

See TEACH * VARS_AND_LVARS

NB whenever you get a "WARNING" message while your program is being
compiled you should examine the message carefully and look closely at
the portion of program that causes the message. Try to fix your program
so that you don't get the message, even if you leave pop11 (or VED) and
restart the same file and recompile it.


-- Question 16: Case-sensitive search in Ved --------------------------

16.1 How do you get Ved to search forward for "enddefine"

    ENTER /enddefine/

You can drop the final "/" if the search string does not end with a
space:
    ENTER /enddefine


16.2 How do you get Ved to search backwards for "enddefine"

    ENTER \enddefine\
or
    ENTER \enddefine

I.e. use "/" to search forwards, and "\" to search backwards.


16.3 How do you get Ved to search forward for the same string as last
time, without re-typing the string?

    ESC /


16.4 How do you get Ved to search backward for the same string as last
time, without re-typing the string?

    ESC \


16.5 How do you get Ved to search forward for the word "the" in such
a way that it does not find the embedded occurrence in "these"?
(Non-embedded search)

    ENTER "the"
or
    ENTER "the

Try that and also try
    ENTER /the

with the Ved cursor HERE ->


    these the

See which command finds "these" and which finds "the".


16.6 How do you get Ved to search backward for the word "the" in such
a way that it does not find the embedded occurrence in "these"?

    ENTER `the

Compare the above command and ENTER \the

Summary:
                    EMBEDDED    NON-EMBEDDED
        DIRECTION
        forwards        /           "
        backwards       \           `

For more on the above see TEACH * VEDSEARCH

More complex searching operations are described in

    TEACH * REGEXP
    REF * REGEXP


-- Question 17: Case insensitive search in Ved ------------------------

17.1 How do you get Ved to search forward for the next occurrence of
"the" or "The". I.e. you want a case insensitive search for a string
containing those letters in any combination of upper and lower case?

    ENTER ss the

Use "ss" (i.e. String Search) for case-insensitive forward search.


17.2 How do you get Ved to search backward for the next occurrence of
"the" or "The". I.e. you want a case insensitive search backwards.

    ENTER bss the

Use "bss" (i.e. BACKWARD String Search) for case-insensitive backwards
search.


17.3 How do you do a case insensitive search forwards again for the
last case insensitive search string you used.

    ENTER ss

I.e. if no argument is provided, the same caseless search as last time
will be repeated in the forward direction.


17.4 How do you do a case insensitive search backwards again for the
last case insensitive search string you used.

    ENTER bss

I.e. if no argument is provided, the same caseless search as last time
will be repeated in the backward direction.


17.5 How do you do a non-embedded case insensitive forward search, e.g.
you want to find "the" or "The" but not "these" or "These"?

    ENTER ww the

I.e. search forward for a WHOLE WORD, not an embedded string.

If there's no argument (i.e. simply ENTER ww) the last caseless search
string will be re-used.


17.6 How do you do a non-embedded case insensitive backward search, e.g.
you want to find "the" or "The" but not "these" or "These"?

    ENTER bww the

I.e. search backward for a WHOLE WORD, not an embedded string.
If there's no argument (i.e. simply ENTER bww) the last caseless search
string will be re-used.

For more on case insensistive search see HELP VED_SS

You can constrain caseless search to a procedure, or a range.


-- Question 18: Searching and substituting with patterns in Ved -------

18.1 How do you search for 'define' at the beginning of a line, so that
it does not find 'define' in this line, but does find this:
define

Answer:
    ENTER /@adefine/

the pattern element "@a" in a Ved search string matches the beginning of
a line.

Note: you can use the word quote to ensure that you don't find an
occurence of "defined". I.e. for non-embedded search:

    ENTER "@adefine"

You can omit the final occurrence of '/' unless you want to include a
space, e.g. to finde a line starting with "define" followed by a space:

    ENTER /@adefine /


18.2 How do you search for 'then' where it is the last thing on a
line?

Answer: just as "@a" matches the beginning of a line, so "@z" matches
the end of a line, e.g.

    ENTER /then@z/

will find the next occurrence of "then" at the end of a line, e.g. then

The '/' at the end is actually redundant.


18.3 How do you interactively search for occurrences of 'this' and
replace them with 'that' ?

Ved has an "interactive search and replace" facility. There are various
versions of this, but the simples one uses "ENTER s/string1/string2/"
to search for occurrences of string1 and replace them with string2, e.g.

    ENTER s/this/that/

Note 1. Instead of the string delimiter '/' you can use any other
character that does not occur in either the search string or the
substitute string, e.g.
    ENTER s;this;that;

Note 2: If you want to find only non-embedded occurrences of the search
string, use '"' as delimiter, e.g. to replace 'the' with 'The', but not
inside 'these' use:

    ENTER s"the"The"

Note 3: Before each substitution the Ved cursor moves to the location
where the string was found to draw your attention to it. You then have
the option to decide whether to go ahead with the substitution, to
continue or to stop, by pressing a key, as follows:

    KEY
    y       - do the substitution and stop
    n       - don't do the substitution, just stop
    RETURN  - do the substitution and continue to the next occurrence
    Del     - don't do the substitution, and continue to the next
              occurrence of the search string.
    g       - do the substitution globally (i.e. change all occurrences)

Note 4: you can use search patterns in the first string, as explained
above and in TEACH * VEDSEARCH

Note 5: you can restrict the "ENTER s" command (and the search back or
forwards commands) to look only in a specified part of the current file,
e.g. the current procedure definition, the marked range, the current
line. You restrict the search and replace region by using a keyword
after the final delimeter, thus:

    KEYWORD       REGION
    file        - the whole file (the default)
    range       - the marked range
    procedure   - the current procedure
    line        - the current line
    paragraph   - the current paragraph
    selection   - the current selection (XVed only)
    sentence    - the current sentence
    word        - the current word
    window      - the visible text
    toendfile   - from cursor position to end of file
    tostartfile - from cursor position to start of file

So to consider only substitutions in the current procedure definition do

    ENTER s/list/list1/procedure

(You can abbreviate the keyword to a unique initial sequence, e.g.
'pa' for 'paragraph')


18.4 How do you replace all occurrences of 'result' in a procedure with
'output'?

Answer: use the "Global Substitute in Procedure" command:

    ENTER gsp/result/output/

or with any other delimiter not included in the strings:

    ENTER gsp;result;output;

Use the delimeter '"' to prevent replacement of embedded occurrences,
e.g.
    ENTER gsp"list"numlist"

will replace 'list' on its own with 'numlist', but not an embedded
occurrence as in 'list5'.

The "ENTER gsp" command is one of a whole collection of "global" search
and replace (global substitute) commands, where "global" means replace
all occurrences. The different commands can specify different regions of
the file in which to make the replacement, e.g.

    ENTER gsl   - globally substitute in the current line
        e.g. to replace all spaces with commas in the current line
                ENTER gsl/ /,/

    ENTER gsr   - globally substitute in the marked range


It is possible to make the search and replace command "ENTER gs" use a
caseless search by using the '-case' qualifier after the command.


WARNING: the patterns used by VED when searching text files have nothing
to do with the pop-11 pattern matcher used for comparing lists.


For more information

    TEACH * VEDSEARCH
    HELP  * VED_SS

For experts:
    REF   * VEDSEARCH
    TEACH * REGEXP
    REF   * REGEXP


-- Question 19: More on format of files and procedure definitions -----


19.1 Why should test instructions be put inside comments?
e.g.

/*

riv_setup([man fox chicken boat],[grain],[]);
database ==>

*/


Answer:
If the test instructions are not inside comment brackets like that, then
every time you load the file the test instructions will be run. That is
generally not what you want. It can even cause a mishap to occur if the
tests occur above the procedure definition, since then pop-11 will
attempt to run the tests before the procedure has been compiled and
you will get both a warning
;;; DECLARING VARIABLE  ....
;;; IN FILE /home/staff/axs/docfiles/revise.ans

and an error which will prevent the rest of the file being compiled:
;;; MISHAP - enp: EXECUTING NON-PROCEDURE


19.2 In which order should the following occur in a file

a. test instructions
b. procedure definitions
c. procedure headers
d. file header
e. commands to load libraries
f. commands to load other files used by this one
g. comments
h. global variable declarations

Answer:

First:
    d. file header

This should come at the top of your file, giving the name of the file,
the creation and last alteration dates, the purpose, etc. You can create
a template file header in any file using this VED command

    ENTER fileheader

Near the top of the file:

    e. commands to load libraries
    f. commands to load other files used by this one
    h. global variable declarations

You should have all "lib", "uses" or "load" commands near the top of the
file, before your own procedure definitions start, so that any required
procedure definitions or syntax extensions have already been loaded
before your own procedure definitions are read in.

You can have your own global variable declarations (with comments saying
what the variables are for) either before you load the library files or
after.

Sometimes it is useful to declare and initialise your global variables
BEFORE the "lib" or "uses" command since they can then usefully affect
the manner in which the library is compiled.  More often it is best to
do this AFTER the libraries have been compiled, so that you can easily
change default values which have been set up in the library. Use the
library's documentation to decide.


In various places:
    a. test instructions

There are different sorts of test instructions. Some tests are used only
during program development and debugging. These must always be inside
comments and are often most usefully located near the procedures they
test, either immediately above or immediately below. However, some
people prefer to put all test commands in one place, e.g. at the end of
the file, or even in a quite different file full of test instructions.

Some "test commands: are used to demonstrate the program and are usually
run only when the whole program has been completed and compiled. It is
often useful to put these near the top of the file, inside a comment
explaining what to do to run the program. Alternatively if your program
is very big, you can break it up into several different files, and have
an instruction file which includes commands for loading all the other
files (using "load" or "compile") and gives instructions for running the
program.


Throughout the file
    b. procedure definitions
    c. procedure headers

When a program includes lots of procedure definitions they can be
inserted in a sensible order within the file, after the file header, the
commands to load libraries and global variable declarations.

For each procedure there should be a comment explaining what it does,
including what sorts of inputs it takes, what sorts of outputs it
produces and what side effects it has. In simple cases this can be in a
comment immediately after the procedure header, which makes it easy to
move the comment if ever you move the procedure definition. Where the
comment is more complicated you can create a procedure header template
above the procedure using the command:
    ENTER procheader
If you have the command
    uses ved_procheader
in your vedinit.p file, then you can use the key sequence ESC ! to
insert a procedure header.
See HELP * VED_PROCHEADER


EVERYWHERE:
    g. comments

Comments of different sorts should occur throughout the file, including
comments in the middle of procedure definitions explaining what is going
on (except where it is so obvious that no comment is needed.)


19.3 How can you prepare an index of procedure definitions in a file?

See HELP * VED_INDEXIFY

The first time you want to produce an index of procedures in a file,
choose the place you want the index to go (e.g. it may be useful near
the top of the file, or near the end of the file). Prepare opening and
closing comment brackets to include the index.
/*

*/
Put the VED cursor between the brackets and give the command
    ENTER indexify define

After that, you can redo the indexify command each time you add new
procedures, but you no longer need to tell VED where to put the index.
It will use the same location as before, and will correct the index.
(However all your procedure definitions MUST start at the beginning
of a line. The word "define" must not be indented.)
Having created the index you can use
    ENTER gg
to go to the index, or to go to a procedure in the index.

If you wish to create a temporary index in a separate file, you can do
    ENTER headers
and then the command
    ENTER gp
in the temporary index file will take you to the desired procedure.
See HELP * VED_HEADERS


19.4 How can you search for a procedure called foo in the current file?

    ENTER f foo

The "ENTER f <name>" command searches for the next occurrence of
"define" containing the word <name> in an appropriate position to be the
name of a procedure. If you have created a procedure index using
indexify it may find the index entry for the procedure. If so, simply
press the REDO key (Top right key on numeric keypad) to search again.


19.5 How can you search for the next procedure after the current one?

    ENTER "define

If you wish to define the escape sequence ESC 4 to do that, you can put
the following in your vedinit.p file

    vedsetkey('\^[4', veddo(%'"define'%));


19.6 How can you search backwards for the procedure before the current
one?

    ENTER `define

If you wish to define the escape sequence ESC 5 to do that, you can put
the following in your vedinit.p file

    vedsetkey('\^[5', veddo(%'`define'%));


See TEACH VEDNOTES

If you want to find out more about VED programming see
    HELP VEDSET
    HELP VEDSETKEY
    REF  VEDCOMMS
    REF  VEDPROCS


--- $poplocal/local/teach/revise.ans
--- Copyright University of Birmingham 2000. All rights reserved. ------