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 => ** [this list] = [this list] => ** (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 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(), 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 " command searches for the next occurrence of "define" containing the word 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. ------