;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: 4Utility Programs* =Text: 3UTILITY PROGRAMS ed* &optional 1x* 2ed* is the main function for getting into the editor, Zmacs. The commands of Zmacs are very similar to those of Emacs. 2(ed)* or 2(ed nil)* simply enters the editor, leaving you in the same buffer as the last time you were in the editor. It has the same effect as typing 2System E*. 2(ed t)* puts you in a fresh buffer with a generated name (like BUFFER-4). 2(ed 1pathname*)* edits that file. 1pathname* may be an actual pathname or a string. 2(ed 'foo)* tries hard to edit the definition of the 2foo* function. It can find a buffer or file containing the source code for 2foo* and position the cursor at the beginning of the code. In general, 2foo* can be any function-spec (see 4(FUNCTIONS-1)Function Specs*). 2(ed 'zwei:reload)* reinitializes the editor. It forgets about all existing buffers, so use this only as a last resort. 3zwei:save-all-files* This function is useful in emergencies in which you have modified material in Zmacs buffers that needs to be saved, but the editor is partially broken. This function does what the editor's 2Save All Files* command does, but it stays away from redisplay and other advanced facilities so that it might work if other things are broken. 3dired* &optional 1pathname* Puts up a window and edits the directory named by 1pathname*, which defaults to the last file opened. While editing a directory you may view, edit, compare, hardcopy, and delete the files and subdirectories it contains. While in the directory editor type the 2Help* key for further information. 3mail* &optional 1user* 1text* 1call-editor-anyway* Sends the string 1text* as mail to 1user*. 1user* should also be a string, of the form 2"1username3@*hostname*"*. Multiple recipients separated by commas are also allowed. If you do not provide two arguments, 2mail* puts up an editor window in which you may compose the mail. Type the 2End* key to send the mail and return from the 2mail* function. The window is also used if 1call-editor-anyway* is non-2nil*. 3bug* &optional 1topic* 1text* 1call-editor-anyway* Reports a bug. 1topic* is the name of the faulty program (a symbol or a string). It defaults to 2lispm* (the Lisp Machine system itself). 1text* is a string which contains the information to report. If you do not provide two arguments, or if 1call-editor-anyway* is non-2nil*, a window is put up for you to compose the mail. 2bug* is like 2mail* but includes information about the system version and what machine you are on in the text of the message. This information is important to the maintainers of the faulty program; it aids them in reproducing the bug and in determining whether it is one that is already being worked on or has already been fixed. 3print-notifications* &optional 1(from* 301)** 1to* Reprints any notifications that have been received. 2from* and 2to* are used to restrict which notifications are printed; both count from the most recent notification as number 0. Thus, 2(print-notifications 2 8)* prints six notifications after skipping the two most recent. The difference between notifications and sends is that sends come from other users, while notifications are usually asynchronous messages from the Lisp Machine system itself. However, the default way for the system to inform you about a send is to make a notification! So 2print-notifications* 1normally* includes all sends as well. Typing 2Terminal 1 N* pops up a window and calls 2print-notifications* to print on it. 3si:print-disk-error-log* Prints information about the half dozen most recent disk errors (since the last cold boot). 3peek* &optional 1character* Selects the PEEK utility, which displays various information about the system, periodically updating it. PEEK has several modes, which are entered by typing a single key which is the name of the mode or by clicking on the menu at the top. The initial mode is selected by the argument, 1character*. If no argument is given, PEEK starts out by explaining what its modes are. 3time* 1form* Evaluates 1form* and prints the length of time that the evaluation took. The values of 1form* are returned. Note that 2time* with no argument is a function to return a time value counting in 60ths of a second; see 4(DATETIME-1)Elapsed Time in 60ths of a Second*. This unfortunate collision is a consequence of Common Lisp. =Node: 4The Lisp Listen Loop* =Text: 3THE LISP LISTEN LOOP* These functions constitute the Lisp top level read-eval-print loop or 1listen loop* and its associated functions. 3si:lisp-top-level* This is the first function called in the initial Lisp environment. It calls 2lisp-reinitialize*, clears the screen, and calls 2si:lisp-top-level1*. 3lisp-reinitialize* This function does a wide variety of things, such as resetting the values of various global constants and initializing the error system. 3si:lisp-top-level1* 1*terminal-io** This is the actual listen loop. Within it, 2*terminal-io** is bound to the argument supplied. This is the stream used for reading and printing if 2*standard-input** and 2*standard-output** are synonyms for 2*terminal-io**, as they normally are. The listen loop reads a form from 2*standard-input**, evaluates it, prints the result (with escaping) to 2*standard-output**, and repeats indefinitely. If several values are returned by the form all of them are printed. Also the values of 2**, 2+*, 2-*, 2//*, 2++*, 2***, 2+++*, 2**** and 2*values** are maintained (see below). 3break* 1format-string* &rest 1format-args* Enters a breakpoint loop, which is similar to a Lisp top level loop. 1format-string* and the 1format-args* are passed to 2format* to print a message. 3;Breakpoint 1message*; Resume to continue, Abort to quit.* and then enters a loop reading, evaluating, and printing forms. A difference between a break loop and the top level loop is that when reading a form, 2break* checks for the following special cases: If the 2Abort* key is typed, control is returned to the previous break or error-handler, or to top-level if there is none. If the 2Resume* key is typed, 2break* returns 2nil*. If the list 2(return 1form*)* is typed, 2break* evaluates 1form* and returns the result, without ever calling the function 2return*. Inside the 2break* loop, the streams 2*standard-output**, 2*standard-input**, and 2query-io* are bound to be synonymous to 2*terminal-io**; 2*terminal-io** itself is not rebound. Several other internal system variables are bound, and you can add your own symbols to be bound by pushing elements onto the value of the variable 2sys:*break-bindings** (see 4(MISCELL-2)The Lisp Listen Loop*). 2break* used to be a special form whose first argument was a string or symbol which was simply printed 1without evaluating it*. In order to facilitate conversion, 2break* really still is a special form. If the call appears to use the old conventions, it behaves in the old way, but the compiler issues a warning if it sees such code. 3prin1* 1Variable* The value of this variable is normally 2nil*. If it is non-2nil*, then the read-eval-print loop uses its value instead of the definition of 2prin1* to print the values returned by functions. This hook lets you control how things are printed by all read-eval-print loops--the Lisp top level, the 2break* function, and any utility programs that include a read-eval-print loop. It does not affect output from programs that call the 2prin1* function or any of its relatives such as 2print* and 2format*; if you want to do that, read about customizing the printer, on 4(READPRINT-1)What the Printer Produces*. If you set 2prin1* to a new function, remember that the read-eval-print loop expects the function to print the value but not to output a 2return* character or any other delimiters. 3-* 1Variable* While a form is being evaluated by a read-eval-print loop, 2-* is bound to the form itself. 3+* 1Variable* While a form is being evaluated by a read-eval-print loop, 2+* is bound to the previous form that was read by the loop. 3** 1Variable* 3//* 1Variable* While a form is being evaluated by a read-eval-print loop, 2** is set to the result printed the last time through the loop. If there were several values printed (because of a multiple-value return), 2** is bound to the first value. 2//* is bound to a list of all the values of the previous form. If evaluation of a form is aborted, 2** and 2//* remain set to the results of the last successfully completed form. If evaluation is successful but printing is aborted, 2** and 2//* are already set for the following form. Note that when using Common Lisp syntax you would type just 2/*. 3++* 1Variable* 2++* holds the previous value of 2+*, that is, the form evaluated two interactions ago. 3+++* 1Variable* 2+++* holds the previous value of 2++*. 3*** 1Variable* 3////* 1Variable* Hold the previous values of 2** and 2//*, that is, the results of the form evaluated two interactions ago. Only forms whose evaluation is successful cause the values of 2** and 2//* to move into 2*** and 2////*. Note that when using Common Lisp syntax you would type just 2//*. 3**** 1Variable* 3//////* 1Variable* Hold the previous values of 2*** and 2////*, that is, the results of the form evaluated three interactions ago. Note that when using Common Lisp syntax you would type just 2///*. 3*values** 1Variable* 2*values** holds a list of all lists of values produced by evaluation in this Lisp listener. 2(car* 2*values*)* is nearly equivalent to 2//*, 2(cadr *values*)* to 2////*, and so on. The difference is that an element is pushed on 2*values** for each form whose evaluation is started. If evaluation is aborted, the element of 2*values** is 2nil*. 3sys:*break-bindings** 1Variable* When 2break* is called, it binds some special variables under control of the list which is the value of 2sys:*break-bindings**. Each element of the list is a list of two elements: a variable and a form that is evaluated to produce the value to bind it to. The bindings happen sequentially. Users may 2push* things on this list (adding to the front of it), but should not replace the list wholesale since several of the variable bindings on this list are essential to the operation of 2break*. 3lisp-crash-list* 1Variable* The value of 2lisp-crash-list* is a list of forms. 2lisp-reinitialize* sequentially evaluates these forms, and then sets 2lisp-crash-list* to 2nil*. In most cases, the 1initialization* facility should be used rather than 2lisp-crash-list*. Refer to 4(INITIALIZE-0)Initializations*. =Node: 4The Garbage Collector* =Text: 3THE GARBAGE COLLECTOR gc-on* Turns automatic garbage collection on. Garbage collection will happen when and as needed. Automatic garbage collection is off by default. Since garbage collection works by copying, you are asked for confirmation if there may not be enough space to complete a garbage collection even if it is started immediately. 3gc-off* Turns automatic garbage collection off. 3gc-on* 1Variable* 2t* when garbage collection is on, 2nil* when it is not. You cannot control garbage collection by setting this variable; it exists so you can examine it. In particular, you can tell if the system found it necessary to turn off garbage collection because it was close to running out of virtual memory. Normally, automatic garbage collection happens in incremental mode; that is, scavenging happens in parallel with computation. Each consing operation scavenges or copies four words per word consed. In addition, scavenging goes on whenever the machine appears idle. 3si:inhibit-idle-scavenging-flag* 1Variable* If this is non-2nil*, scavenging is not done during idle time. If you are running a noninteractive crunching program, the incremental nature of garbage collection may not be helpful. Then you can make garbage collection more efficient by making it a batch process. 3si:gc-reclaim-immediately* 1Variable* If this variable is non-2nil*, automatic garbage collection is done as a batch operation: when the garbage collection process decides that the time has come, it copies all the useful data and discards the old address space, running full blast. (It is still possible to use the machine while this is going on, but it is slow.) More specifically, the garbage collection process scavenges and reclaims oldspace immediately right after a flip happens, using all of the machine's physical memory. This variable is only relevant if you have turned on automatic garbage collection with 2(gc-on)*. A batch garbage collection requires less free space than an incremental one. If there is not enough space to complete an incremental garbage collection, you may be able to win by selecting batch garbage collection instead. 3si:gc-reclaim-immediately-if-necessary* 1Variable* If this variable is non-2nil*, then automatic garbage collection is done in batch mode if, when the flip is done, there does not seem to be enough space left to do it incrementally. This variable's value is relevant only if 2si:gc-reclaim-immediately* is 2nil*. 3si:gc-flip-ratio* 1Variable* This variable tells the garbage collector what fraction of the data it should expect to have to copy, after each flip. It should be a positive number no larger than one. By default, it is one. But if your program is consing considerable amounts of garbage, a value less than one may be safe. The garbage collector uses this variable to figure how much space it will need to copy all the living data, and therefore indirectly how often garbage collection must be done. 3si:gc-flip-minimum-ratio* 1Variable* This value is used, when non-2nil*, to control warnings about having too little space to garbage collect. Its value is a positive number no greater than one, just like that of 2si:gc-flip-ratio*. The difference between the two is that 2si:gc-flip-ratio* controls when garbage collection is 1recommended*, whereas 2si:gc-flip-minimum-ratio* controls when the system considers the last possible time to do so. If 2si:gc-flip-minimum-ratio* is 2nil*, 2si:gc-flip-ratio* serves both purposes. Garbage collection is turned off if it appears to be about to run out of memory. You get a notification if this happens. You also get a notification when you are nearly at the point of not having enough space to guarantee garbage collecting successfully. In addition to turning on automatic garbage collection, you can also manually request one immediate complete collection with the function 2si:full-gc*. The usual reason for doing this is to make a band smaller before saving it. 2si:full-gc* also resets all temporary areas (see 2si:reset-temporary-area*, 4(AREAS-1)Area Functions and Variables*). 3si:full-gc* Performs a complete garbage collection immediately. This does not turn automatic garbage collection on or off; it performs the garbage collection in the process you call it in. A full gc of the standard system takes about 7 minutes, currently. 3si:clean-up-static-area* 1area-number* This is a more selective way of causing static areas to be garbage collected once. The argument is the area number of a static area; that particular area will be garbage collected the next time a garbage collection is done (more precisely, it will be copied and discarded after the next flip). If you then call 2si:full-gc*, it will happen then. 3gc-status* The function 2gc-status* prints information related to garbage collection. When scavenging is in progress, it tells you how the task is progressing. While scavenging is not in progress and oldspace does not exist, it prints information about how soon a new flip will be required. While a garbage collection is not in progress, the output from 2gc-status* looks like this: 3Dynamic (new+copy) space 557,417, Old space 0, Static 3,707,242,* 3Free space 10,453,032, with 10,055,355 needed for garbage collection* 3 assuming 100% live data (SI:GC-FLIP-RATIO = 1).* 3If GC is turned on, a flip will happen in 397,677 words.* 3Scavenging during cons Off, Idle scavenging On,* 3Automatic garbage collection Off.* 3GC Flip Ratio 1, GC Reclaim Immediately Off* or 3Dynamic (new+copy) space 561,395, Old space 0, Static 3,707,242,* 3Free space 10,453,032, with 10,058,670 needed for garbage collection* 3 assuming 100% live data (SI:GC-FLIP-RATIO = 1).* 3A flip will happen in 394,362 words.* 3Scavenging during cons On, Idle scavenging On,* 3Automatic garbage collection On.* 3GC Flip Ratio 1, GC Reclaim Immediately Off* The ``dynamic space'' figure is the amount of garbage collectable space and the ``static'' figure is the amount of static space used. There is no old space since an old space only exists during garbage collection. The amount of space needed for garbage collection represents an estimate of how much space user programs will use up while scavenging is in progress. It includes a certain amount of padding. The difference between the free space and that amount is how much consing you can do before a garbage collection will begin (if automatic garbage collection is on). The amount needed for a garbage collection depends on the value of 2si:*gc-reclaim-immediately**; more if it is 2nil*. While a garbage collection is in progress, the output looks like this: 3Incremental garbage collection now in progress.* 3Dynamic (new+copy) space 45,137, Old space 972,514, Static 3,707,498,* 3Between 3,701,440 and 4,629,998 words of scavenging left to do.* 3Free space 9,289,795 (of which 928,558 might be needed for copying).* 3Ratio scavenging work/free space = 0.55.* 3Scavenging during cons On, Idle scavenging On,* 3Automatic garbage collection On.* 3GC Flip Ratio 1, GC Reclaim Immediately Off* Notice that most of the dynamic space has become old space and new space is small. Not much has been copied since the flip took place. The maximum and minimum estimates for the amount of scavenging are based on different limits for how much of old space may need to be copied; as scavenging progresses, the maximum decreases steadily, but the minimum may increase. The free space is smaller now, but it will get larger when scavenging is finished and old space is freed up. (The total amounts are not the same now because unused parts of regions may not be included in any of the figures.) 3si:set-scavenger-ws* 1number-of-pages* Incremental scavenging is restricted to a fixed amount of physical memory to reduce its interference with your other activities. This function specifies the number of pages of memory that incremental garbage collection can use. 256 is a good value for a 256k machine. If the garbage collector gets very poor paging performance, use of this function may fix it. =Node: 4Logging In* =Text: 3LOGGING IN* Logging in tells the Lisp Machine who you are, so that other users can see who is logged in, you can receive messages, and your INIT file can be run. An INIT file is a Lisp program which gets loaded when you log in; it can be used to set up a personalized environment. When you log out, it should be possible to undo any personalizations you have made so that they do not affect the next user of the machine. Therefore, anything done by an INIT file should be undoable. In order to do this, for every form in the INIT file, a Lisp form to undo its effects should be added to the list that is the value of 2logout-list*. The 2login-forms* construct helps make this easy; see below. 3user-id* 1Variable* The value of 2user-id* is either the name of the logged in user, as a string, or else an empty string if there is no user logged in. It appears in the who-line. 3logout-list* 1Variable* The value of 2logout-list* is a list of forms to be evaluated when the user logs out. 3login* 1name* &optional 1host* 1inhibit-init-file* Sets your name (the variable 2user-id*) to 1name* and logs in a file server on 1host*. 1host* also becomes your default file host. The default value of 1host* depends on which Lisp Machine you use using; it is called the associated machine (see 4(MISCELL-4)The LMLOCS File*). 2login* also runs the 2:login* initialization list (see 4(INITIALIZE-1)System Initialization Lists*). If 1host* requires passwords for logging in you are asked for a password. Adding an asterisk at the front of your password enables any special capabilities you may be authorized to use, by calling 2fs:enable-capabilities* (4(FILEACCESS-4)File Servers*). Unless 1inhibit-init-file* is specified as non-2nil*, 2login* loads your init file if it exists. On ITS, your init file is 1name* 2LISPM* on your home directory. On TOPS-20 your init file is 2LISPM.INIT* on your directory. On VMS, it is 2LISPM.INI*. On Unix, it is 2lispm.init*. If anyone is logged into the machine already, 2login* logs him out before logging in 1name*. (See 2logout*.) Init files should be written using the 2login-forms* construct so that 2logout* can undo them. Usually, however, you cold-boot the machine before logging in, to remove any traces of the previous user. 2login* returns 2t*. 3log1* &rest 1options* Like 2login* but the arguments are specified differently. 1options* is a list of keywords and values; the keywords 2:host* and 2:init* specify the host to log in on and whether to load the init file if any. Any other keywords are also allowed. 2log1* itself ignores them, but the init file can act on them. The purpose of 2log1*, as opposed to 2login*, is to enable you to specify other keywords for your init file's sake. 3si:user-init-options* 1Variable* During the execution of the user's init file, inside 2log1*, this variable contains the arguments given to 2log1*. Options not meaningful to 2log1* itself can be specified, so that the init file can find them here and act on them. 3logout* First, 2logout* evaluates the forms on 2logout-list*. Then it sets 2user-id* to an empty string and 2logout-list* to 2nil*. Then it runs the 2:logout* initialization list (see 4(INITIALIZE-1)System Initialization Lists*), and returns 2t*. 3login-forms* 1undoable-forms...* 1Macro* The body of a 2login-forms* is composed of forms to be evaluated, whose effects are to be undone if you log out. For example, 3(login-forms* 3 (setq fs:*defaults-are-per-host* t))* would set the variable immediately but arrange for its previous value to be restored if you log out. 2login-forms* is not an AI program; it must be told how to undo each function that will be used immediately inside it. This is done by giving the function name (such as 2setq*) a 2:undo-function* property which is a function that takes a form as an argument and returns a form to undo the original form. For 2setq*, this is done as follows: 3(defun (setq :undo-function) (form &aux results)* 3 (do ((l (cdr form) (cddr l)))* 3 ((null l))* 3 (cond ((boundp (car l))* 3 (push `(setq ,(car l) ',(symeval (car l))) results))* 3 (t (push `(makunbound ',(car l)) results))))* 3 `(progn . ,results))* Undo functions are standardly provided for the functions 2setq*, 2pkg-goto-globally*, 2setq-globally*, 2add-initialization*, 2deff*, 2defun*, 2defsubst*, 2macro*, 2advise* and 2zwei:set-comtab*. Constructs which macroexpand into uses of those functions are also supported. Note that setting 2*read-base** and 2*print-base** should be done with 2setq-globally* rather than 2setq*, since those variables are likely to be bound by the 2load* function while the init file is executed. 3login-setq* 1{variable* 1value}...* 1Macro* 2login-setq* is like 2setq* except that it puts a 2setq* form on 2logout-list* to set the variables to their previous values. 2login-setq* is obsolete; use 2login-forms* around a 2setq* instead. 3login-eval* 1x* 2login-eval* is used for functions that are ``meant to be called'' from INIT files, such as 2zwei:set-comtab-return-undo*, which conveniently return a form to undo what they did. 2login-eval* pushes the result of the form 1x* onto 2logout-list*. It is obsolete now because 2login-forms* is a cleaner interface. 3si:undoable-forms-1* 1undo-list-name* 1forms* &optional 1complaint-string* This is what 2login-forms* uses. 1forms* is a list of forms; they are evaluated and forms for undoing their effects are pushed onto the value of the symbol 1undo-list-name*. If an element of 1forms* has no known way to be undone, a message is printed using the string 1complaint-string*. For 2login-forms*, the string supplied is 2"at logout"*.