Digital PDFs
Documents
Guest
Register
Log In
AA-EV0OBA-TE
May 1986
298 pages
Original
16MB
view
download
Document:
VAX LISP/ULTRIX User's Guide
Order Number:
AA-EV0OBA-TE
Revision:
000
Pages:
298
Original Filename:
OCR Text
0 VAX LISP/ULTRIX User's Guide Order Number: AA-EV08A-TE 0 May 1986 This document contains information required by a LISP language programmer to interpret, compile, and debug VAA LISP programs. 0 Operating System and Version: ULTRIX-32 Version 1.2 ULTRIX-32m Version 1.2 Software Version: VAA LISP/ULTRIX Version 2.0 0 0 digital equipment corporation maynard, massachusetts First Printing, May 1986 The information in this document is subject to change without notice and should not be construed as a commitment by Digital Equipment Corporation. Digital Equipment Corporation assumes no responsibility for any errors that may appear in this document. · Q ij The software described in this document is furnished under a license and may be used or copied only in accordance with the terms of such license. No responsibility is assumed for the use or reliability of software on equipment that is not supplied by Digital Equipment Corporation or its affiliated companies. © Digital Equipment Corporation 1986. All Rights Reserved. 0 Printed in U.S.A. A postage-paid READER'S COMMENTS form is included on the last page of this document. Your comments will assist us in preparing future documentation. The following are trademarks of Digital Equipment Corporation: .Q DEC DECUS MicroVAX VAXstation DECnet ULTRIX-32 ULTRIX-32m UNIBUS VAX MicroVAX II VAXstation II ULTRIX PDP VMS MicroVMS AI VAXstation ULTRIX-11 0 0 CONTENTS 0 PREFACE Part I VAX LISP/ULTRIX SYSTEM CONCEPTS AND FACILITIES CHAPTER 1 o· 0 1.1 OVERVIEW OF VAX LISP 1.1.1 vaxlisp Shell Command 1.1.1.1 Interpreter 1.1.1.2 Compiler 1.1.2 Error Handler 1.1. 3 Debugging Facilities 1.1.4 Pretty Printer 1.1. 5 Call-Out Facility 1.1. 6 Alien Structure Facility 1.1. 7 VAX LISP/ULTRIX Function, Macro, and Variable Descriptions_ 1.2 HELP FACILITIES 1. 2 .1 ULTRIX HELP 1. 2. 2 LISP HELP 1.3 ULTRIX FILE SPECIFICATIONS 1. 3 .1 File Name 1. 3. 2 Pathname 1.3.2.1 Directory Names 1.3.2.2 Slash(/) Separators 1.3.2.3 Sample Pathname 1.3.2.4 Host Names 1.3.3 Default Values 1. 3. 4 VAX LISP Default File Types O CHAPTER 2 2.1 2.2 2.3 2.4 2.5 0 INTRODUCTION TO VAX LISP 2.6 2.7 2.8 2.9 2.9.1 2.9.2 2.9.3 2.9.4 2.10 2.10.1 1-2 1-3 1-3 1-3 1-4 1-4 1-4 1-4 1-5 1-5 1-5 1-5 1-6 1-7 1-7 1-7 1-8 1-8 1-8 1-8 1-8 1-9 USING VAX LISP INVOKING LISP EXITING LISP ENTERING INPUT DELETING INPUT ENTERING THE DEBUGGER USING CONTROL KEY SEQUENCES CREATING PROGRAMS LOADING FILES COMPILING PROGRAMS Compiling Individual Functions and Macros Compiling Files Advantages of Compiling LISP Expressions Advantage of Not Compiling LISP Expressions vaxlisp COMMAND OPTIONS Three Ways to Use the vaxlisp Command iii 2-1 2-2 2-2 2-2 2-3 2-3 2-4 2-5 2-6 2-6 2-6 2-8 2-8 2-9 2-14 COMPILE 2.10.2 ERROR_ACTION 2.10.3 [NO]INITIALIZE 2.10.4 [NO]LISTING 2.10.5 [NO]MACHINE_CODE 2.10.6 MEMORY 2.10.7 [NO]OPTIMIZE 2.10.8 [NO]OUTPUT_FILE 2.10.9 RESUME 2.10.10 [NO]VERBOSE 2.10.11 [NO]WARNINGS 2.10.12 USING SUSPENDED SYSTEMS 2.11 Creating a Suspended System 2.11.1 Resuming a Suspended System 2 .11. 2 CHAPTER 3 ERROR HANDLING ERROR HANDLER 3.1 VAX LISP ERROR TYPES 3.2 Fatal Errors 3.2.1 Continuable Errors 3.2.2 Warnings 3.2.3 CREATING AN ERROR HANDLER 3.3 Defining an Error Handler 3.3.1 Function Name 3.3.1.1 Error-Signaling Function 3.3.1.2 Arguments 3.3.1.3 Binding the *UNIVERSAL-ERROR-HANDLER* Variable 3.3.2 CHAPTER 4 2-15 2-16 2-17 2-18 2-19 2-20 2-21 2-22 2-23 2-23 2-24 2-25 2-25 2-26 3-1 3-1 3-2 3-3 3-4 3-5 3-5 3-6 3-6 3-7 3-7 0 0 0 DEBUGGING FACILITIES CONTROL VARIABLES 4.1 CONTROL STACK 4.2 ACTIVE STACK FRAME 4.3 BREAK LOOP 4.4 Invoking the Break Loop 4.4.1 Exiting the Break Loop 4.4.2 Using the Break Loop 4.4.3 Break Loop Variables 4.4.4 DEBUGGER 4.5 Invoking the Debugger 4.5.1 Exiting the Debugger 4.5.2 Using Debugger Commands 4.5.3 Arguments 4.5.3.1 Debugger Commands 4.5.3.2 Using the DEBUG-CALL Function 4.5.4 Sample Debugging Sessions 4.5.5 STEPPER 4.6 Invoking the Stepper 4.6.1 Exiting the Stepper 4.6.2 iv 4-3 4-3 4-4 4-4 4-4 4-5 4-6 4-7 4-7 4-8 4-9 4-9 4-11 4-13 4-18 4-18 4-20 4-20 4-21 0 0 0 0 Stepper Output Using Stepper Commands 4.6.4 Arguments 4.6.4.1 Stepper Commands 4.6.4.2 Using Stepper Variables 4.6.5 *STEP-FORM* 4.6.5.1 *STEP-ENVIRONMENT* 4.6.5.2 Example Use of Stepper Variables 4.6.5.3 Sample Stepper Sessions 4.6.6 TRACER 4.7 Enabling the Tracer 4.7.1 Disabling the Tracer 4.7.2 Tracer Output 4.7.3 Tracer Options 4.7.4 Invoking the Debugger 4.7.4.1 Adding Information to Tracer Output 4.7.4.2 Invoking the Stepper 4.7.4.3 Removing Information from Tracer Output 4.7.4.4 Defining When a Function or Macro Is Traced 4.7.4.5 Tracer variables 4.7.5 *TRACE-CALL* 4.7.5.1 *TRACE-VALUES* 4.7.5.2 4. 6. 3 CHAPTER 5 0 0 5.1 5.2 5.2.1 5.2.2 5.2.3 5.2.4 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4 5.5 5.6 5.7 5.7.1 5.7.2 5.7.3 5.8 5.9 4-21 4-:2 4 4-25 4-26 4-28 4-28 4-28 4-29 4-31 4-32 4-33 4-33 4-34 4-35 4-36 4-36 4-36 4-37 4-37 4-37 4-37 4-38 PRETTY PRINTING AND USING.EXTENSIONS TO FORMAT PRETTY PRINTING WITH DEFAULTS HOW TO PRETTY-PRINT USING CONTROL VARIABLES Explicitly Enabling Pretty Printing Limiting Output by Lines Controlling Margins Conserving Space with Miser Mode EXTENSIONS TO THE FORMAT FUNCTION Using the WRITE FORMAT Directive Controlling the Arrangement of Output Controlling Where New Lines Begin Controlling Indentation Producing Prefixes and Suffixes Using Tabs Directives for Handling Lists DEFINING YOUR OWN FORMAT DIRECTIVES DEFINING PRINT FUNCTIONS FOR LISTS DEFINING GENERALIZED PRINT FUNCTIONS ABBREVIATING PRINTED OUTPUT Abbreviating Output Length Abbreviating Output Depth Abbreviating Output by Lines USING MISER MODE HANDLING IMPROPERLY FORMED ARGUMENT LISTS 0 v 5-2 5-3 5-3 5-4 5-4 5-5 5-5 5-7 5-8 5-11 5-13 5-14 5-15 5-16 5-18 5-19 5-21 5-23 5-24 5-24 5-25 5-26 5-28 CHAPTER 6 VAX LISP/ULTRIX IMPLEMENTATION NOTES 6.1 DATA REPRESENTATION 6 .1.1 Numbers 6.1.1.1 Integers 6.1.1.2 Floating-Point Numbers 6 .1. 2 Characters Arrays 6 .1. 3 6 .1. 4 Strings PATHNAMES 6.2 6.2.1 Name strings 6.2.2 When to Use Pathnames 6.2.3 Fields in a COMMON LISP Pathname 6.2.4 Field Values of a VAX LISP Pathname 6.2.5 Three Ways to Create Pathnames 6.2.6 Comparing Similar Pathnames 6.2.7 Converting Pathnames into Namestrings 6.2.8 Functions That Use Pathnames Using the *DEFAULT-PATHNAME-DEFAULTS* Variable 6.2.9 6.3 GARBAGE COLLECTOR 6.3.1 Frequency of Garbage Collection Static Space· 6.3.2 6.3.3 Messages Available Space 6.3.4 Garbage Collection Failure 6.3.5 6.4 INPUT AND OUTPUT 6.4.1 Newline Character 6.4.2 Terminal Input 6.4.3 Terminal Output 6. 4 .·4 End-of-File Operations 6.4.5 File Organization 6.4.6 Functions 6.4.6.1 OPEN Function 6.4.6.2 WRITE-CHAR Function KEYBOARD FUNCTIONS 6.5 6.6 COMPILER 6.6.1 Compiler Restrictions 6.6.1.1 COMPILE Function 6.6.1.2 COMPILE-FILE Function 6.6.2 Compiler Optimizations 6.7 FUNCTIONS AND MACROS 6-20 6-2 6-2 6-3 6-5 6-6 6-7 6-7 6-8 6-8 6-9 6-9 6-10 6-12 6-12 6-13 6-13 6-14 6-15 6-15 6-16 6-16 6-16 6-16 6-17 . 6-18 6-18 6-18 6-19 6-19 6-19 6-19 , 6-20 6-21 6-21 6-21 6-21 6-22 6-24 0 0 0 Part II VAX LISP/ULTRIX Function, Macro, and Variable Descriptions APROPOS Function APROPOS-LIST Function BIND-KEYBOARD-FUNCTION Function BREAK Function CANCEL-CHARACTER-TAG Tag CHAR-NAME-TABLE Function vi 1 3 4 7 :o 0 0 0 0 0 COMPILEDP Function COMPILE-FILE Function *COMPILE-VERBOSE* Variable *COMPILE-WARNINGS* Variable CONTINUE Function DEBUG Function DEBUG-CALL Function *DEBUG-PRINT-LENGTH* Variable *DEBUG-PRINT-LEVEL* Variable DEFAULT-DIRECTORY Function DEFINE-FORMAT-DIRECTIVE Macro DEFINE-GENERALIZED-PRINT-FUNCTION Macro DEFINE-LIST-PRINT-FUNCTION Macro DELETE-PACKAGE Function DESCRIBE Function DIRECTORY Function DRIBBLE Function *ERROR-ACTION* Variable EXIT Function Format Directives Provided with VAX LISP GC Function *GC-VERBOSE* Variable GENERALIZED-PRINT-FUNCTION-ENABLED-P Function GET-GC-REAL-TIME Function GET-GC-RUN-TIME Function GET-INTERNAL-RUN-TIME Function GET-KEYBOARD-FUNCTION Function HASH-TABLE-REHASH-SIZE Function HASH-TABLE-REHASH-THRESHOLD Function HASH-TABLE-SIZE Function HASH-TABLE-TEST Function LOAD Function LONG-SITE-NAME Function MACHINE-INSTANCE Function MACHINE-VERSION Function MAKE-ARRAY Function *MODULE-DIRECTORY* Variable *POST-GC-MESSAGE* Variable PPRINT-DEFINITION Function PPRINT-PLIST Function *PRE-GC-MESSAGE* Variable *PRINT-LINES* Variable *PRINT-MISER-WIDTH* *PRINT-RIGHT-MARGIN* Variable PRINT-SIGNALED-ERROR Function *PRINT-SLOT-NAMES-AS-KEYWORDS* Variable REQUIRE Function ROOM Function SHORT-SITE-NAME Function STEP Macro *STEP-ENVIRONMENT* Variable *STEP-FORM* Variable vii 11 12 15 16 18 19 20 21 22 23 25 28 30 32 33 35 37 38 39 40 43 44 45 46 48 so 51 52 53 54 55 56 58 59 60 61 63 64 65 67 70 71 72 73 75 77 78 80 83 84 85 86 SUSPEND Function THROW-TO-COMMAND-LEVEL Function TIME Macro *TOP-LEVEL-PROMPT* Variable TRACE Macro *TRACE-CALL* Variable *TRACE-VALUES* Variable UNBIND-KEYBOARD-FUNCTION Function UNCOMPILE Function UNDEFINE-LIST-PRINT-FUNCTION Macro UNIVERSAL-ERROR-HANDLER Function *UNIVERSAL-ERROR-HANDLER* Variable WARN Function WITH-GENERALIZED-PRINT-FUNCTION Macro APPENDIX A A.1 A.1.1 A.1.2 A.1. 3 A.1.4 A.1.5 A.1.6 A.1. 7 A.1.8 A.1.9 A.2 A. 3 A.4 87 90 91 92 93 104 105 106 107 108 109 110 111 112 PERFORMANCE HINTS DATA STRUCTURES Integers Floating-Poi~t Numbers Ratios Character's Symbols Lists and Vector's Strings, General Vector's, and Bit Vectors Hash Tables Functions DECLARATIONS PROGRAM STRUCTURE COMPILER REQUIREMENTS 0 A-1 0 A-2 A-2 A-2 A-3 A-3 A-4 A-5 A-6 A-6 A-6 0 A-10 A-12 INDEX 0 FIGURES 5-1 Variables Governing MiseI' Mode 5-26 1-1 VAX LISP File Type Specifications Control Key Sequences Options of the vaxlisp Shell Command Option Modes for the vaxlisp Command EI'rOI'-Signaling Functions Debugging Functions and Macros Debugger Commands Debugger Command Modifiers Stepper Commands 1-9 TABLES 2-1 2-2 2-3 3-1 4-1 4-2 4-3 4-4 viii 2-3 2-12 2-14 3-7 4-1 4-10 · 4-12 4-24 '----" n 0 5-1 6-1 6-2 6-3 6-4 1 2 3 Format Directives Provided by VAX LISP 5-6 VAX LISP Floating-Point Numbers 6-3 Floating-Point Constants 6-4 VAX LISP Pathname Fields 6-10 Summary of Implementation-Dependent Functions and Macros 6-25 ~ormat Directives Provided with VAX LISP 40 Data Type Headings 81 TRACE Options 94 0 0 0 0 ix 0 0 0 0 0 0 PREFACE Manual Objectives 0 The VAX LISP/ULTRIX User's Guide is intended for use in developing and debugging LISP programs, and for use in compiling and executing LISP programs on ULTRIX-32 and ULTRIX-32m systems. The VAX LISP language elements are described in COMMON LISP: The Language.* Intended Audience O This manual is designed for programmers who have a working knowledge of LISP. Detailed knowledge of ULTRIX-32 is helpful but not essential. However, some sections of this manual require more extensive understanding of the operating system. _In such sections, you are directed to the appropriate manual(s) for additional information. Structure of This Document An outline of the organization and ofollows: PART I: chapter content of this manual VAX LISP/ULTRIX SYSTEM CONCEPTS ARD FACILITIES Part I consists of six chapters, which explain VAX LISP describe the VAX LISP facilities. concepts and • Chapter 1, Introduction to VAX LISP, provides an overview of VAX LISP, explains how to use th~ help facilities, and describes ULTRIX file specifications. • Chapter 2, Using VAX LISP, explains how to invoke and exit from VAX LISP, use control key sequences, enter and delete input, create and compile programs, load files, and use Q*Burlington, Guy L. Steele Jr., COMMON LISP: The Language, Digital Press (1984), Massachusetts. xi PREFACE suspended systems. In addition, Chapter ULTRIX vaxlisp command and its o~tions. 2 • Chapter 3, Error Handling, error-handling facility. the • Chapter 4, Debugging Facilities, explains how to use LISP debugging facilities. the VAX • Chapter 5, The Pretty Printer, explains how LISP pretty printer. the VAX • Chapter 6, VAX LISP/ULTRIX Implementation Notes, describes the features of LISP that are defined by or aie dependent on the VAX implementation of COMMON LISP. PART II: .describes to describes the VAX use 0 LISP VAX LISP/ULTRIX FUNCTION, MACRO, ARD VARIABLE DESCRIPTIONS Part II describes functions, macros, and variables specific to VAX LISP and any COMMON LISP objects that have specific implementation characteristics in VAX LISP. Each function or macro description explains the function's or macro's use and shows its format, applicable arguments, return value, and examples of use. Each variable description explains the variable's use and provides examples of its use. 0 0 Associated Documents The following documents are relevant to VAX LISP/ULTRIX programming: • VAX LISP/ULTRIX Installation Guide • COMMON LISP: • VAX LISP/ULTRIX System Access Programming Guide • ULTRIX-32 Programmer's Manual • ULTRIX-32 Supplementary Documentation • VAX Architecture Handbook The Language 0 0 xii PREFACE Conventions Used in This Document 0 The following conventions are used· in this manual: Convention Meaning ( Parentheses used· in examples of'-LISP c0de indlcate beginning and end of a LISP form. For example: ) the (SETQ NAME LISP) [ ) Square brackets enclose For example: elements that are optional. [doc-string] 0 UPPERCASE Defined LISP characters, functions, macros, variables, and constants are printed in uppercase characters; however, you can enter them in uppercase, lowercase, or a combination of uppercase and lowercase characters. lowercase italics Lowercase italics in function and macro descriptions and in text indicate arguments that you supply; however, you can enter them in lowercase, uppercase, or a combination of lowercase and uppercase characters. Q bold Names of ULTRIX commands and command options text (not in examples) are in bold type. in the In LISP examples, a horizontal ellipsis indicates not pertinent to the example and not shown. code A vertical ellipsis indicates that all the information that th~ system would display in response to the particular function call is not shown; or, that all the information a user is to enter is not shown. 0 { } In function and macro format specifications, braces enclose elements that are considered to be one unit of code. For example: {keyword value} { }* In function and macro format specifications, braces followed by an asterisk enclose elements that are considered to be one unit of code, which can be repeated zero or more times. For example: {keyword value}* 0 xiii PREFACE Convention Meaning &OPTIONAL In function and macro format specifications, the word &OPTIONAL indicates that the arguments after it are defined to be optional. For example: O PPRINT object &OPTJONAL package Do not specify &OPTIONAL when you invoke a function macro whose definition includes &OPTIONAL. &REST or In function and macro format specifications, the word &REST indicates that an indefinite number of arguments may appear. For example: BREAK &OPTIONAL format-string &REST args Do not specify &REST when you invoke the macro whose definition includes &REST. &KEY function In function and macro format specifications, the word &KEY indicates that keyword arguments are accepted. For example: COMPILE-FILE input-pathname &KEY {keyword value}* Do not specify &KEY when you invoke the macro whose definition includes &KEY. <RET> A symbol indicates example: function or Q with a 1- to 3-character abbreviation that· you press a key on the terminal. For <RET> or <ESC> In examples, carriage returns are implied at the end of each line. However, the <RET> symbol is used in some examples to emphasize carriage returns. <CTRL/x> Q <CTRL/x> indicates a control key sequence where you hold down the CTRL key while you press another key. For example: <CTRL/C> or <CTRL/Y> command(n) The (n) after a command is the section number of the ULTRIX-32 Programmer's Manual that contains a description of that command. For example: vi(1) 0 xiv PREFACE 0 Convention Meaning Black print In examples, output lines and prompting characters that the system displays are in black print. For example: Lisp> (CDR '(ABC)) (BC) Lisp> Red print , In examples, user input is shown example: in red print. For Lisp> (CDR '(ABC)) (BC) Lisp> ( 0 0 0 0 xv 0 0 0 0 0 0 PART I 0 0 0 0 ( l VAX LISP/ULTRIX SYSTEM CONCEPTS AND FACILITIES 0 0 0 0 0 0 CHAPTER 1 INTRODUCTION TO VAX LISP 0 0 Q LISP is a general purpose programming language. The language has been used extensively in the field of artificial intelligence for research and development of robotics, expert systems, natural-language processing, game playing, and theorem proving. The LISP language is characterized by: • Computation with symbolic expressions and numbers • Simple syntax • Representation of data by symbolic expressions lists • Representation of LISP programs as LISP data, which enables data structures to execute as programs and programs to be analyzed as data • A function named EVAL, which is the language's definition interpreter or multilevel and • Automatic storage allocation and garbage collection VAX LISP is implemented on both the VMS and the ULTRIX-32 operating systems. VAX LISP as implemented on the VMS operating system is formally named VAX LISP/VMS. VAX LISP as implemented on the ULTRIX operating system is formally named VAX LISP/ULTRIX. Both VAX LISP/ULTRIX and VAX LISP/VMS are the same language but with some differences. For the differences, see the VAX LISP/ULTRIX Release Notes. These notes are kept on line in the VAX LISP product by default, /usr/lib/vaxlisp, in the file vaxlispnnn.mem, I directory, where nnn is the VAX LISP version number (for example, lisp020.mem for version 2.0) 0 This manual describes VAX LISP/ULTRIX but refers to VAX LISP/ULTRIX by VAX LISP where practicable. 1-1 INTRODUCTION TO VAX LISP This chapter provides an overview of the VAX LISP language. The overview is arranged so that it parallels the structure of t h i o manual. In addition to ,the overview, the chapter describes: 1.1 • On-line help facilities for ULTRIX and for LISP • ULTRIX file specifications OVERVIEW OF VAX LISP The VAX LISP language runs on the ULTRIX-32 and the ULTRIX-32m operating systems. This manual refers to both operating systems as ULTRIX except in a few situations where the operating systems differ. VAX LISP is an extended implementation of the COMMON LISP languageo defined in COMMON LISP: The Language. In addition to the features supported by COMMON LISP, VAX LISP provides the following extensions: • VAX LISP shell command, vaxlisp • Error handler • Debugging facilities • Pretty printer • Facility for calling languages • Facility for defining non-LISP data structures • VAX LISP functions, macros, and variables 0 out to c and other ULTRIX compiled These extensions are described in Sections L 1.1 through 1.1. 7. Q NOTE VAX LISP does not support ·complex numbers. However, you can manipulate complex numbers by the use of the alien structure and call-out facilitie~. Some of fhe functions, macros, and facilities defined by COMMON LISP are modified for the VAX LISP implementation. Chapter .6 provides implementation-dependent information about the following topics: • Data representation • Pathnames 0 1-2 INTRODUCTION TO VAX USP .-~ u 1.1.1 o· 0 • Garbage collector • Input and output o Compiler o Functions and macros vaxlisp Shell Command You can invoke VAX LISP from either shell (the C Shell or the Bourne shell) with the shell command vaxlisp. Depending on the option(s) you use with the vaxlisp command, you can start the LISP interpreter or the LISP compiler. Chapter 2 describes the vaxlisp shell command and all the options you can use with it. Chapter 2 also explains how to: • Invoke LISP • Exit LISP • Create programs • Load files • Compile programs • Use suspended systems 1.1.1.1 Interpreter - The VAX LISP interpreter reads an expression, evaluates the expression, and prints the results. You interact with the interpreter in l~ne-by-line input. QWhile in the interpreter, you can create LISP programs. You can also use programs that are stored in files if you load the files into the interpreter. Chapter 2 explains how to create LISP programs and how to load files into the VAX LISP interpreter. 1.1.1.2 Compiler - The VAX LISP compiler is a LISP program that translates LISP code from text to machine code. Because of the translation, compiled programs run faster than interpreted programs. 0 You can use the compiler to compile a single function or macro or to compile a LISP source file. If you are in the LISP interpreter, you can compile a single function or macro with the COMPILE function (see Chapter 2). 1-3 INTRODUCTIOf\l TO VAX LISP You can compile a program either from the shell or in LISP. If you are in the shell, you must specify the vaxlisp command with t h e o ' compile (-c) option; if you are in LISP, you must invoke the COMPILE-FILE function. Chapter 2 explains how to compile LISP programs that are stored in files. 1.1.2 Error Handler VAX LISP contains an error handler, which is invoked when errors occur during the evaluation of a LISP program. Chapter 3 describes the error handler and explains how you can create your own error handler. 1.1.3 Debugging Facilities VAX LISP provides several functions and macros that return or display information you can use when you are debugging a program. VAX LISP also provides four debugging facilities: the break loop, debugger, stepper, and tracer. The functions that return debugging information and the break loop, stepper, and tracer facilities are defined in COMMON LISP and are extended in VAX LISP. The break loop lets you interrupt the evaluation of a program, the stepper lets you use commands to step through the evaluation of each form in a program, and the tracer lets you examine the evaluation of a program. The debugger is a VAX LISP facility. The facility provides commands that let you examine and modify the information in the LISP system's control stack frames. Q Q Chapter 4 explains how to use the debugging facilities. 1.1.4 0 Pretty Printer VAX LISP provides a pretty printer facility. You can use the facility to control the format in which LISP objects are printed. The pretty printer can be helpful in making objects easier to understand by means of indentation and spacing. You can use the pretty printer with the existing defaults, or you can control it with control variables. Chapter 5 explains how to use the pretty printer in both of these ways. 1.1.5 Call-Out Facility VAX LISP includes a call-out facility, which lets. you call routines written in C and other ULTRIX compiled languages. Chapter 2 of the 1-4 0 INTRODUCTION TO VAX LISP VAX LISP/ULTRIX System Access Programming Guide describes the call-out 0 process and explains how to use the call-out facility. 1.1.6 Alien Structure Facility VAX LISP supplies an alien structure facility. It lets you define, create, and access VAX data structures that are used to communicate between the VAX LISP language and C or other ULTRIX languages. Chapter 3 of the VAX LISP/ULTRIX System Access Programming Guide describes the alien structure facility and explains how to use it. 1.1.7 0 VAX LISP/ULTRIX Function, Macro, and Variable Descriptions VAX LISP/ULTRIX contains many functions, macros, and variables that are either not mentioned or are mentioned but not fully defined in the COMMON LISP language. These functions, macros, and variables are divided into the following categories: Implementation-dependent objects mentioned but not • defined in Common LISP: The Language 0 fully • VAX LISP objects that implement the parts of VAX LISP that are described in this manual • System access-specific objects (pertaining to the alien structure, and interrupt function facilities) call-out, These LISP objects let you use the VAX LISP facilities and some ULTRIX facilities without exiting or calling out from the LISP system. 0 The LISP objects in the first two categories listed above are described in Part II of this manual. System access-specific objects are described in Part II of the VAX LISP/ULTRIX System Access Programming Guide. 1.2 HELP FACILITIES You can get help in using VAX LISP both from the shell and f rem the LISP interpreter. I only) 1.2.1 0 (on ULTRIX-32 ULTRIX HELP Although ULTRIX-32 has the ULTRIX-32 Programmer's Manual on line, ULTRIX-32m does not. So, only if you are on ULTRIX-32, can you get 1-5 INTRODUCTION TO VAX LISP information about ULTRIX commands, their parameters, and qualifiers by using the on-line ULTRIX-32 Programmer's Manual. their You display this manual's information on your terminal by using the shell command man(l) with a second command (the one about which you want to find information) as an argument. The format for d9ing this is: 0 man command-name Example % man vaxlisp In the preceding example, the man(l) command will display one screenful (the first 21 lines of text on a terminal capable of displaying 24 lines) of the manual's explanation on the vaxlisp command. Once you are reading a section of the on-line through it in several ways: manual, you • To se~ one more line of text, press the RETURN key. • To see a second screen of text, press the SPACE bar. • For further viewing commands, see the discussion more(l) command in the ULTRIX-32 Programmer's Manual. can move of the If the screen has displayed all of a section, you are automatically returned to the shell prompt. If more is to be displayed, the last line of your screen contains the phrase "--More--(xx%)". The percent figure gives the fraction of the file (in characters) that has been displayed so far. If you want to leave a section before all of it is displayed, press the q key. 1.2.2 Q Q 0 LISP HELP VAX LISP provides two functions you can use to obtain help during a LISP session: DESCRIBE and APROPOS. The.DESCRIBE- function displays information about a specified LISP object. The type of information the function displays depends on the object you specify as its argument. You can use the APROPOS function to search through a package for symbols whose print names contain a specified string. See COMMON LISP: The Language for information about packages. Descriptions of the DESCRIBE and APROPOS functions are provided in Part II. 0 1-6 INTRODUCTION TO VAX LISP 0 1.3 ULTRIX FILE SPECIFICATIONS An ULTRIX file specification indicates the input file to be processed or the output file to be produced. A discussion of ULTRIX file name syntax follows. For more information, see the ULTRIX-32. Programmer's Manual. 1.3.1 File Name ULTRIX is case sensitive. So, a file name in uppercase letters indicates a file different from the same name in lowercase letters. ULTRIX file names can be from 1 to 255 ASCII characters in length. Any character (printable.or not) can be used except for the'slash (the delimiter) and the null character (the terminator). However, to use only alphanumeric characters is best. Many nonalphanumeric characters have special meaning to the shell and can create confusion if you use them in a file name. 11 / 0 11 You can use a hyphen(-) in a file name, but you should not use a hyphen as the first character in the name. The hyphen preceded by a space indicates an option argument to a command, not a file name. 0 Although an extension to a file name (a file type) is not required, you can create file names with extensions by placing a period between the extension and the base of the name; for example, factorial.lsp. VAX LISP uses extensions (file types) to name files. See Section 1.3.4. ULTRIX does not maintain version numbers for files. ·So, if you make a new version of an old file and do not rename the old version, the old version will be lost. 0 1.3.2 Pathname On ULTRIX, the pathname of a file is the file's name plus the name of the directory-tree structure that contains the file. The directory tree goes from the system root directory to the file's working (default) directory. The directory tree is called a pathname because it is like a path that leads to a file's location. The last component of a pathname is usually a file name, though it can be a directory name if that is what is wanted. For example, if you use the pwd(l) command to show your working dire_ctory, that command displays a pathname whose last component is a directory. 0 1-7 INTRODUCTION TO VAX LISP NOTE A pathname is also a COMMON LISP data type (see Chapter 6). In the other chapters of this manual, the word PATHNAME refers to the COMMON LISP data type. 0 1.3.2.1 Directory Names - In ULTRIX, a directory is named in the same way as any other file with one exception: The first slash(/) in a complete pathname indicates the system root directory. Other than the system root directory, directories are simply file names "that are branches of the root directory. So, the following specification could be either of a file or of a directory: /usr/users/jones/lispl 0 1.3.2.2 Slash(/) Separators - Slashes (/) separate the components of a pathname (directory names from each other, and a file name from its directory) • . However, a single slash(/) by itself stands for the ULTRIX system root directory. 1.3.2.3 Sample Pathname - In the following sample pathname, factorial.lsp is a file in the directory /usr/users/jones/lisp, and lisp is a subdirectory of the directory /usr/users/jones: Q /usr/users/jones/lisp/factorial.lsp 1.3.2.4 Host Names - Normally, a host (computer) name is not included in a pathname. However, when using the rcp(l) command to copy files between computers, the host name followed by a colon(:) is added to the front of a pathname. For example, in the following file specification, miami is the host name: Q miami :/usr/users/jones/lisp/factorial •. lsp 1.3.3 Default Values You do not have to supply a complete pathname each time you compile a file, load an initialization file, or resume a suspended system. Also, the file name ·by itself wi.thout its type is sufficient if the name is contained in your working directory. 1-8 0 INTRODUCTION TO VAX LISP O The way the system fills in default values depends on the operation that is being performed. For example, if you are compiling a file and you specify only a file name, the compiler processes the source program if it finds a file with the specified file name in the default directory. The file (in your directory) does not have to have a type; but if it does, it must have the default type of lsp for the. system to process the file without your specifying the file type· (in your command line). Suppose you pass the following file specification to the compiler: % vaxlisp -c circle Also, suppose the file circle is in the directory /usr/user/jones. Then the previous file specification would be equivalent to: % vaxlisp -c /usr/user/jones/circle.lsp Q ( In either specification, the compiler searches through the directory-tree structure of/, usr, user, and jones, seeking the file circle or, if that does not exist, circle.lsp. Since no output file is specified, the compiler generates the file circle.fas and stores it in directory jones. 0 1.3.4 VAX LISP Default File Types VAX LISP has the default file types listed in Table 1-1. types are explained in Chapter 2. Table 1-1: File Type Qfas These file VAX LISP File Type Specifications Description Fast-loading file (output from compiler) lis Error listing (output from compiler) lsp Source file (input to LISP reader or compiler) SUS Suspended system (a copy of the LISP during an interactive LISP session) 0 1-9 -----------------·--------- memory in use 0 0 0 ·o 0 0 CHAPTER 2 USING VAX LISP This chapter describes the shell command vaxlisp and its oexplains the following: • options and Invoking LISP • Exiting LISP • Entering input • Deleting input • Entering the debugger • Using control key sequences • Creating programs • Loading files • Compiling programs • Using suspended systems 0 0 2.1 INVOKING LISP You invoke an interactive LISP session by typing the shell command vaxlisp. When it· is executed, a message identifying the VAX LISP , system appears, and then the LISP prompt (Lisp>) is displayed. For example: % vaxlisp 0 Welcome to VAX LISP, Version V2.0 Lisp> 2-1 ( USING VAX LISP See Section 2.10 for a description of the options you can use with the vaxlisp command. 2.2 0 EXITING LISP You can exit from LISP by using the LISP EXIT function. For example: Lisp> (EXIT) % When you exit the LISP system, you are returned to the shell. 2.3 ENTERING INPUT You enter input into the VAX LISP system a line at a time. Once you move to a new line, you cannot go back to the previous line. However, you can recover an input expression or an output value by using the following 10 unique variables:· I II Ill * ** *** + ++ +++ These variables are described in COMMON LISP: The Language. The following example illustrates the use of the plus sign(+) variable that is bound to the expression most recently evaluated: Lisp> (CDR '(ABC)) (BC) Lisp>+ (CDR (QUOTE (ABC))) Lisp> COMMON LISP symbols are not case sensitive. 2.4 0 0 0 DELETING INPUT The keys that control how you delete input vary d~pending on whether you use the Bourne or the C Shell and on what options you use in a shell. For more information on deleting input, see the ULTRIX-32 Programmer's Manual. 0 2-2 USING VAX LISP 0 2.5 ENTERING THE DEBUGGER If you make an error in an interactive VAX LISP session, the error automatically invokes the debugger, which replaces the LISP prompt (Lisp>) with the debugger prompt (Debug 1>). If you continue to make errors, each new error puts you into another level in the debugger. The debug prompt indicates the level of interaction. For example, the prompt "Debug 2>" means you are at a second level in the debugger. For information on how to use the VAX LISP debugger, see Chapter 4. Typing <CTRL/C> is a quick way to recover from an error without using the VAX LISP debugger. If you want to recover from an error by discarding the expression you typed and starting over, type <CTRL/C>. <CTRL/C> returns you to the read-eval-print loop, which displays the LISP prompt (Lisp>). 0 0 2.6 USING CONTROL KEY SEQUENCES Table 2-1 lists three helpful QLTRIX signals and the default control key sequences bound to these signals. To display the settings of control keys for various signals, type the stty all command. For further information on characters that generate signals and on how to change control key sequences bound to these signals, see the stty·( 1) command in the ULTRIX-32 Programmer's Manual. The control keys that generate these signals are the only control characters that can be bound to functions with BIND-KEYBOARD-FUNCTION (see Part II for a description of BIND-KEYBOARD-FUNCTION). Table 2-1: Control Key Sequences Default Q Signal SIG INT Control-Key Sequence <CTRL/C> Function In LISP, <CTRL/C> first invokes the CLEAR-INPUT function on the *TERMINAL-IO* stream, then throws to the catcher established for CANCEL-CHARACTER-TAG. If you want to recover from an error by discarding the expression you typed and starting over, type <CTRL/C>. (See the description o( CANCEL-CHARACTER-TAG in Part II for an example of changing the behavior of <CTRL/C>.) 0 2-3 USING VAX LISP Table 2-1 (cont.) 0 Signal Default Control-Key Sequence SIGQUIT <CTRL/\> By default, <CTRL/\> (A\), makes a core dump and exits LISP. <CTRL/\> can be bound with the BIND-KEYBOARD-FUNTION function. SIGTSTP <CTRL/Z> In the C shell, suspends a process and returns you to the shell, letting you execute other commands while the process (such as an interactive LISP session) remains suspended. The shell command jobs shows you the number of any suspended processes. By typing %n in response to the shell prompt, where n is the number of your suspended process, you will be returned to your suspended process. See the ULTRIX-32 Programmer's Manual for further information regarding the SIGTSTP signal. Function 0 0 2.7 CREATING PROGRAMS The most common way to create a LISP program is by using a ·text editor. In this way, the program exists in a source file that can be loaded into the LISP environment by the LISP LOAD function. Although you can compose source programs with any text editor, the ULTRIX vi(l) screen editor provides three options that help you enter and edit LISP source code. • lisp Changes the (and) commands to move backward and forward over LISP expressions. • ai Properly indents LISP expressions. • sm Briefly shows the on-screen position of an open parenthesis that matches a close parenthesis. You can set these options in the editor startup file EXINIT line: set lisp ai sm with Q the 0 2-4 USING VAX LISP For more information on this editor, see the ULTRIX-32 Programmer's oanual and the ULTRIX-32 Supplementary Documentat.ion -- Volume I. Another way to create LISP programs is to define them, using the LISP interpreter in an interactive LISP session. If you define functions with the DEFUN macro or macros with the DEFMACRO macro, the definitions become a part of the interpreted LISP environment. You can then invoke your defined functions and macros. However, since these definitions are not in a permanent text file, your work is stored only temporarily and disappears when you exit VAX LISP. Entering programs by means of the interpreter is really useful only for experimenting with small functions and macros. 2.8 LOADING FILES OBefore you can use a file in interactive LISP, you must load the file into the LISP system. The file can be compiled or interpreted; compiled files load more quickly. You can load a file into the LISP system in two ways: Load the file by specifying the vaxlisp INITIALIZE (-i) option • when in the shell. For example: 0 % vaxlisp -i myinit.lsp Welcome to VAX LISP, Version V2.0 Lisp> 0 The LISP prompt indicates the file has been successfully loaded. If the file is not successfully loaded, an error message indicating the reason appears on your terminal screen. Include the VERBOSE (-v) option to cause the names of functions loaded in an initialization file to be listed at the terminal. For more information on the -i option, see Section 2.10.4. the file by using the LISP LOAD function when in an • Load interactive·LISP session. For example: Lisp> ( LOAD "testprog. lsp") . ; Loading contents of file /usr/users/jones/testprog.lsp ; FACTORIAL FACTORS-OF Finished loading /usr/users/jones/testprog.lsp T Lisp> 0 The file name, testprog.lsp, can be a string, symbol, stream, or pathname. FACTORIAL and FACTORS-OF are t~e functions 2-5 USING VAX LISP contained in the file testprog.lsp. The final T that the file has been successfully loaded. information on the LOAD function, see Part II. indicates For more Q With the -i option, you can load more than one file at a time. With the LOAD function, however, you can specify only one file at a time. 2.9 COMPILING PROGRAMS You compile LISP programs by compiling the LISP expressions that make up the programs. You can do this individually apart from any file or in a file. You can compile LISP expressions individually by using the LISP COMPILE function. You can compile a file of LISP expressions by using the LISP COMPILE-FILE function or the shell vaxlisp command with the COMPILE (-c) option. 2.9.1 Compilrng Individual Func~ions and Macros In LISP, the unit of compilation is normally either a function or a macro. You can compile a function or a macro in a currently running LISP session by using the COMPILE function. This function is described in COMMON LISP: The Language. You normally call a LISP function first in interpreted form to see if the function works. Once it works as interpreted, you can test it in compiled form without having to write the function to a file. Use the COMPILE function for this purpose. Section 2.9.3 has an example of how the compiler can find errors that the interpreter misses. When you compile a function or a macro that is not in a file, the consequent compiled definition exists only in the current LISP session; the definition is not in a file. However, you can use the VAX LISP UNCOMPILE function to restore the interpreted definition. This function, described in Part II, is useful when debugging programs. Because the interpreted code shows you more of your function's evaluation than the compiled code, you can find errors more easily. For more information on finding errors in your code, see the description of the VAX LISP debugger in Chapter 4. 2.9.2 0 0 0 Compiling Files Any collection of LISP expressions can make up a program and can be stored in a file. The compiler processes such a file by compiling the LISP expressions in the file and writing each compiled result ~o an. output file. 2-6 Q USING VAX LISP C) You can compile LISP files either in the shell with the vaxlisp command and the COMPILE (-c) option or in an interactive LISP session with the LISP COMPILE-FILE function. The -c option is described in Section 2.10.2. The COMPILE-FILE function is described in Part II and in COMMON LISP: The. Language. The following example shows how the -c option is used to compile the file myprog.lsp in the shell: % vaxlisp -c myprog.lsp % This example produces an output file named myprog.fas. The next example shows how the COMPILE-FILE function can be used to compile the file myprog.lsp from in t~e LISP system: 0 Lisp> (COMPILE-FILE "myprog.lsp") Starting compilation of file /usr/users/jones/myprog.lsp FACTORIAL compiled. Finished compilation of file /usr/users/jones/myprog.lsp O Errors, 0 Warnings 11 /usr/users/jones/myprog.fas" Lisp> O O Both methods of compiling LISP files ~re equivalent except in their defaults. The COMPILE-FILE function automatically lists the name of each function it compiles at the terminal, but the -c option does not. Both methods produce fast-lo'ading files (type fas) that run more quickly than uncompiled files. The fast-loading files by default are placed in the directory containing your source files~ The first method of compiling files, using the LISP -c option, has the advantage that you can compile several files in one step. For example: % vaxlisp -c filel.lsp file2.lsp file3.lsp When you use the COMPILE-FILE function, it takes several steps to compile several files, since you can compile only one file at a time. Q The second method of compiling files, using the LISP COMPILE-FILE function, has the· advantage of enabling yeti to stay in LISP both I during compilation and afterwards. This method is convenient if you are compiling a single function and want to quickly check for errors and correct them without leaving LISP. This method is necessary if the compilation depends on changes you have made to the LISP environment; that is, you have defined some macros or changed a package. 2-7 USING VAX LISP 2.9.3 Advantages of Compiling LISP Expressions You can use both compiled and uncompiled (interpreted) files and functions during a LISP session. Both compiled and uncompiled LISP expressions have their advantages. The advantages of compiling a file, a macro, or a function are: • 0 Compiling a function or a macro is a good initial debugging tool, since the compilation does static error checking ( checking a program for errors without running it), . such as checking the number of arguments to a function or a macro. For example, consider the following function definiti6n: (DEFUN TEST (X) (IF(> X 0) (+ 1 X) (TEST (TRY X) X))) In the definition of the function TEST, the alternate consequent (the false part) of the IF condition has two arguments ("(TRY X)" aJ;}d "X"),- while the function definition of TEST calls for only one argument. Despite this error, this function might work correctly as an interpreted (uncompiled) function if the argument given is a positive number, since it uses only the first consequent (the true part); so you may not detect the error. But if you compiled the function, the compiler would detect the error in the second consequent and issue a warning. • 2.9.4 0 0 A compiled file not only loads much faster, but the compiled code executes significantly faster than. the corresponding interpreted code. Advantage of Not Compiling LISP Expressions 0 You can debug run-time errors in an interpreted function more easily than you can debug them in a compiled file or function. For example, if the debugger is invoked because an error occurred in an uncompiled function, you can use the debugger to find out what code caused the error. If the debugger is invoked because .an error occurred in a compiled function, the code surrounding the form that caused an error to be signaled may not be accessible. The steppe~ facility is also more informative with interpreted than with compiled functions. See Chapter 4 for information on the debugger and the stepper. 0 2-8 USING VAX LISP 0 2.10 vaxlisp COMMAND OPTIONS The vaxlisp-shell command can be specified with several options according to the standard ULTRIX conventions. The format of the command is: vaxlisp [-option .•. ] [file] ... The conventions are: • Options and their arguments qualify the vaxlisp command . Files specified with the COMPILE option are the only arguments to the command. Files specified with any other option are arguments of that option only. Thus, files to be compiled do not have to be specified immediately after the COMPILE option, but files that are the argument of any other option have to be specified immediately after that option. Also, options specified with the COMPILE option apply to all the file(s) to be compiled. 0 For example, in the following command line, myprogl.lsp and myprog2.lsp are specified with the COMPILE (-c) option. These file are the only arguments of the command vaxlisp, and the VERBOSE (-v) option applies to both of the files. The file myinit.lsp is the argument of the INITIALIZE (-i) option. 0 vaxlisp -c -i myinit.lsp·-v myprogl.lsp myprog2.lsp is case sensitive; the command name is in the lower • ULTRIX case and all the options, with the exception of the LISTING (-L) and the VENDOR (-V) options, are in the-lower case. 0 • Most options can be specified in two ways: As a VENDOR (-V) option with an option-name argument. example: For -V COMPILE As a single-letter option without example: the option name. For -c • Some options accept arguments. These arguments can be either a file name, a number, a symbol, or a string depending on the option. To specify an option argument, type the option specifier followed by a space and the argument. For example: 0 2-9 USING VAX LISP -i myprog.lsp or -m 15000 or -V NOWARNINGS or -V "NOWARNINGS" • To specify a list of option arguments, type a space after the option specifier and either separate the arguments with commas, or include the arguments in string quotes and separate the arguments with spaces. For example: Q -i mrprog1.lsp,myprog2.lsp or -i "myprog1.lsp myprog2.lsp" e When specifying a number of options, you can specify them in any order. However, an option that takes an argument must have that argument follow the option specifier. For example: Q -v -i file or -i file -v • Most options can be negated only in the -v form. You negate an option by adding NO to the -v option name. For example: Q -V NOVERBOSE The two exceptions to this rule are the WARNINGS option and the OUTPUT_FILE option. WARNINGS can be negated by NOWARNINGS in the -v form or by -w; OUTPUT_FILE can be negated by NOOUTPUT_FILE in the -V form or by -n. • If conflicting options specified is used. are specified, the • If you use the -v option specifier, the rules the argument(s) of the -v are: last for option formatting 0 2-10 USING VAX LISP 0 Case can be either upper, lower, or example, the following are equivalent: a mixture. For -v compile -V COMPILE -V Compile Option names can be abbreviated to the fewest ambiguous letters. For example, MEMORY can be abbreviated to ME, and MACHINE_CODE can be abbreviated to MA. 0 Option-name arguments can be combined into one unit by joining them together with commas or in a string surrounded by double quotes and separated by spaces. For example, the following three command lines are equivalent: -v INITIALIZE=file -v MACHINE_CODE -v COMPILE file -V INITIALIZE=~ile,MACHINE_CODE,COMPILE file -v "INITIALIZE=file MACHINE_CODE COMPILE" file 0 Options can be specified either as a string (with quotes) or not (without quotes). For example, the following are equivalent: -V COMPILE -V "COMPILE" 0 Specify an option argument by typing the option name followed by. an equal sign (=) and the argument. For example: -V "INITIALIZE=MYPROG.LSP" or -V INITIALIZE=MYPROG.LSP Options specified with more than one INITIALIZE and OPTIMIZE options) have format with the arguments enclosed in separated by commas. For example: argument (the to be in string parentheses and -V "OPTIMIZE=(SPEED:3,SAFETY:2)" 0 In the format description, option arguments are surrounded by braces ({ }) when you can choose only one value from a list. For example: 2-11 USING VAX LISP -v ERROR_ACTION={EXIT or DEBUG} Table 2-2 summarizes the.options you can use with the vaxlisp shell() command. Sections 2.10.2 through 2.10.13 describe each option in detail. Table 2-2: Options of the vaxlisp Shell Command Option Function -v COMPILE (or) -c Invokes the VAX LISP ~ompiler to compile one or more source files (input arguments that default to the file type lsp). -V ERROR_ACTION={EXIT or DEBUG} EXIT causes your program to,o exit LISP when an error occurs. EXIT is the default in jobs not attached to a terminal and when you use the -c option. DEBUG invokes the VAX LISP debugger when an error occurs. DEBUG is the default in an interactive LISP session. Q -v INITIALIZE=file(sJ (or) -i file(s) -V NOINITIALIZE -V LISTING[=file] (or) -L -V NOLISTING Causes the LrSP system to load an initialization file(s). The default file types for an initialization file are· lsp and fas. -v NOINITIALIZE suppresses the loading of initialization files. Specifies that a listing file() be created during compilation. You can specify a listing file name only with the -v format of the option. A listing consists of the file name, date of compilation, names of the LISP expressions compiled (if the -v option is specified), and warning and error messages. The default file type for a listing file is lis. -v NOLISTING suppresses a listing file and is the default except in jobs . not attached to a terminal.() In such jobs, -v LISTIRG is the default. 2-12 USING VAX LISP (:)ab~e 2-2 (cont.) Option Function -V MACHINE_CODE (or) -a -V NOMACHINE_CODE Includes LISP machine code in the listing file. -v NOMACHINE_CODE suppresses a listing of the machine code and is the default. -v MEMORY=nurnber (or) -m number Specifies the amount of dynamic virtual memory LISP allocates in 512-byte pages. -V "OPTIMIZE=(SPEED:n,SPACE:n, SAFETY:n,COMPILATION_SPEED:n)" NOOPTIMIZE Tells the compiler that each quality has the corresponding value. SPEED is the speed at which the object code runs, SPACE is the space occupied or used by the code, SAFETY is the run-time error checking of the code , and COMPILATION_SPEED is the speed of the compilation process. n is an integer in the range O to 3. The value O is the lowest priority value; the value 3 is the highest. The default value for n is 1. See Chapter 6 for a description of optimization declarations. -V NOOPTIMIZE' suppresses optimization. Q-v 0 0 -v OUTPUT_FILE=file (or) -o file -V NOOUTPUT_FILE (or) -n Causes the name of the compiled file to be the specified name. The default output file type is fas. -v NOOUTPUT_FILE prevents compiled code from being written to a file. -v RESOME=file (or) -r file Resumes a suspended LISP system. The default file type for a suspended LISP system is sus. See Section 2.11 on Using Suspended Systems. -v VERBOSE (or) -v Lists on the output device and the listing file, if any, the names of functions and macros loaded (if -i) or compiled (if 0 -V NOVERBOSE 2-13 USING VAX LISP Table 2-2 (cont.) ) ,..____/ ~\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~---;\ Option Function -c). -v NOVERBOSE suppresses a listing of func~ion and macro names defined ln a file. -V NOVERBOSE is the default. Specifies that the compiler is to produce warning messages. -v WARNINGS is the "default. -V NOWARNINGS prevents the compiler from producing warning messages. -V WARNINGS -V NOWARNINGS (or) -w 2.10.1 0 Three Ways to Use the vaxlisp Command Depending on the option modifying it, you can use the vaxlisp in one of the following three ways called modes: e COMPILE to compile LISP files 9 INTERACTIVE to invoke an (the default) o RESUME to resume a suspended LISP system interactive LISP command session 0 Table 2-3 lists the options of ·the vaxlisp shell command that apply to each mode. The vaxlisp command without an option puts you in an interactive LISP session (the default). Table 2-3: Option Modes for the vaxlisp Command Option Mode COMPILE COMPILE ERROR_ACTION INTERACTIVE or COMPILE or RESUME INITIALIZE INTERACTIVE or.COMPILE LISTING ' COMPILE MACHINE_CODE COMPILE MEMORY INTERACTIVE or COMPILE or RESUME OPTIMIZE COMPILE 2-14 0 0 USING VAX LISP Table 2-3 ( cont. ) 0 Option Mode OUTPUT_FILE COMPILE RESUME RESUME VERBOSE INTERACTIVE or COMPILE WARNINGS COMPILE 2.10.2 COMPILE 0 The COMPILE option, abbreviated as -c, invokes the VAX LISP compiler to compile one or more source files. These source files are specified as arguments to the vaxlisp shell command (rather than as arguments of the -c option). The compiler creates a fast-loading (fas) file from each source file, which defaults to type lsp. Unlike other compilers, such as those for C and FORTRAN, the LISP compiler does not generate ULTRIX object a.out files. So, the LISP compiler does not have an "o" file type. If the ~c option is used with the NOOUTPUT_FILE (-n) option, the compiler compiles the source file but does not put the compiled code in a file. That method is helpful if your purpose in compiling the file is to check for errors. See Section 2.10.9 for more information on the NOOUTPUT_FILE ·option. 0 By default, the compiler gives your newly compiled file the same name as your source file with a fas file type, puts the new file in your source file's di rectory, and returns you to the . shell when the compiler is finished. If you want function names to be listed on your output device as they are compiled, you must specify the VERBOSE (-v) option (see Section 2.10.11). If you want to compile files with the aid of initialization files, use the INITIALIZE (-i) option (see Section 2.10.4). 0 If you use the LISTING, MACHINE_CODE, OPTIMIZE, OUTPUT_FILE, VERBOSE, and WARNINGS options with the COMPILE option, the options apply to all the files to be compiled. If you compile more than-one file at a time, separate file names a space. l Format vaxlisp -c file1 ••. 0 or vaxlisp -V COMPILE file1 2-15 with USING VAX LISP Example 0 % vaxlisp -c factorial.lsp Mode Compile 2.10.3 ERROR_ACTION The ERROR_ACTION option can be specified only with the -v option. The ERROR_ACTION option has two mutually exclusive values: EXIT and DEBUG. • EXIT causes the evaluation of your program to stop and exits LISP if a fatal or a continuable error occurs (for a description of errors and warnings, see Chapter 3). EXIT is the default in jobs not attached to a terminal and in compile mode;'that is, with the -c option. • DEBUG calls the VAX LISP debugger if an error occurs. Once you are in the VAX LISP debugger, you can look at your error, inspect the control stack, and continue your program from the point at which it stopped. DEBUG is the default in an interactive session. See Chapter 4 for more information on the debugger. 0 0 You can use the ERROR_ACTION option when invoking an interactive LISP session or when compiling f'iles with the COMPILE (-c) option.· The ERROR_ACTION option is mainly useful for jobs not attached to a terminal and is equivalent to the VAX LISP *ERROR-ACTION* variable (see Part II). 0 Format vaxlisp -v ERROR_ACTION=value Example % vaxlisp -c -v ERROR_ACTION=DEBUG myp~og.lsp Mode Inte'racti ve, Compile, or Resume 0 2-16 USING VAX LISP 2.10.4 [NO]INITIALIZE QThe INITIALIZE option, abbreviated as -i, causes the LISP system to load one or more initialization files containing LISP source code or compiled code. An initialization file's purpose is to predefine functions you might want to use in a LISP session. The def~ult is to have no initialization file. · If the initialization files contain calls to exiting functions or if these files contain errors and the ERROR_ACTION option is set to exit (-V ERROR_ACTION=EXIT), the LISP system returns to the shell without going into an interactive LISP session. If the initialization files contain errors and the ERROR_ACTION option is set to debug (-V ERROR_ACTION=DEBUG), the LISP system puts you into the LISP debugger. See Section 2.10.3 for more information on the ERROR_ACTION option. O The the -i option uses the LISP LOAD function to determine defaults for proper file type, directory, and other parts of a file specification. For example, you do not have to specify the file type with the name of your initialization file, if that file has a fas or a lsp file type. If your directory contains a file name with both a fas and a lsp file type, the LISP system selects the most recently created file as the initialization file. If only a lsp type file or only a fas type file of a given name and directory exists, the LISP system selects the type file that exists. Quse ~he VERBOSE (-v) option (see Section 2.10.11) to display terminal screen the names of the functions or macros initialization file. on in the the You can use the -i option when invoking an interactive LISP session or when compiling files with the COMPILE (-c) option. You cannot use the -i option with the RESUME {-r) option; if you do, the -i option is disregarded. Q If you load more than one file by using the -v option format, you must use parentheses inside quotes (see the following format). The NOINITIALIZE form of this option (-V ROIRITIALIZE) suppresses the loading of initialization files. Format for Interactive Mode vaxlisp -i file![, ••• ] or vaxlisp -v INITIALIZE=file o or vaxlisp -v "INITIALIZE={filel[, ••• J)" 2-17 USING VAX LISP Format for Compile Mode vaxlisp -i filel[, .... ] -c file 0 or vaxlisp -V "INITIALIZE=(filel[, ... ]) COMPILE" file Example % vaxlisp -i myinit -v Welcome to VAX LISP, Version V2.0 Loading contents of file FACTORIAL FACTORS-OF ; Finished loading /usr/users/jones/myinit.lsp * In the· preceding example, the file type defaults to lsp. FACTORIAL and FACTORS-OF are functions that are loaded into the LISP system from Jones's initialization file. The form (SETF *TOP-LEVEL-PROMPT* "*" ) in the initialization file changes the Lisp> prompt to an asterisk(*). The *TOP-LEVEL-PROMPT* variable is described in Part II. 0 Q The SETF form and the prompt variable are not listed on an output device when the file is loaded, because the VERBOSE option (-v) lists only functions and macros defined in the file. Mode Interactive or Compile 0 2.10.5 [NO]LISTING The LISTING option,abbreviated as -L, is meaningful only if it is specified with the COMPILE (-c) option. The -L option specifies that the compiler generate a listing file during compilation. You must specify this option if you want a listing file. A listing includes the name of the file compiled, the date it was compiled, warning or error messages produced during compilation, and a summary of warning and error messages. If you specify the VERBOSE (-v) option and the -L option, the listing also includes the names of the functions compiled. You can specify a file name for the listing only in the -v format. Do so only when you want the listing file name to be-different from the. name of the source file. If you specify the LISTING option without a file name, the LISP system produces a listing file with a lis file type and the same name as the source file. Q USING VAX LISP 0 The NOLISTING form of this option prevents the compiler from generating a listing file and is the default except in jobs not attached to the terminal. In such jobs, LISTING is the default. Format vaxlisp -c -L file or vaxlisp -V COMPILE,LISTING[=file] file Example % vaxlisp -c myprog.lsp -v -V listing=factorial.lis 0 Sample Listing File Listing output for file /usr/users/jones.lis/myprog.lsp Compiled at 10:33:30 on Friday, 20 April 1984 by JONES Lisp Version V2.0 0 Starting compilation of file FACTORIAL compiled. "/usr/users/jones.lis/myprog.lsp". Finished compilation of _file O Errors, 0 warnings "/usr/users/jones.lis/myprog.lsp". Mode Compile 0 2.10.6 [NO]MACHINE CODE The MACHINE_CODE option,abbreviated as -a, is meaningful only if it is ·· specified with the COMPILE (-c) option. The -a option requests the compiler to put a listing of the VAX LISP machine code in a file separate from the fas file the compiler generates. The compiler also puts anything usually included in a listing file in this file (see Section 2.10.5 for a description of a listing file). ,VAX LISP machine code is similar to a standard assembly language code. However, compiling LISP code does not generate object modules that can be linked. 0 The -a option has no effect on the machine code; this option produces only a machine-code listing file. The machine-code -listing file generated when you use the -a option has the same name as your source file and has a lis file type (unless you also used the LISTING option to specify a different name). 2-19 USING VAX LISP The NOMACHINE_CODE form of this option, the default, prevents compiler from generating a listing of the LISP machine code. the Format 0 vaxlisp -a -c file or vaxlisp -V COMPILE,MACHINE_CODE file Example % vaxlisp -a -c myprog.lsp Mode 0 Compile 2.10.7 MEMORY The MEMORY option, abbreviated as -m, lets you specify the amount of dynamic virtual memory the LISP system allocates in 512-byte pages. The LISP system requires a minimum of 6000 pages of dynamic virtual memory in addition to the read-only and static memory. So, the default page size for the dynamic virtual memory is 6000 pages. If you specify fewer than 6000 pages with the -m option, the system disregards the requested page size and uses the default page size. You do not need the -m option if you intend to use no more than·6000 pages of dynamic memory. Q To see how many pages of memory are available at any point while you are in LISP, use the LISP ROOM function. If you discover that you need more memory, save your work by creating a suspended system and : exit LISP. Then reenter LISP with the RESUME (-r) and the -m options. Use the -m option to specify a larger number of pages than you had previously specified. For information on creating a suspended system, see Section 2.11.1; for descriptions of the -r option and the ROOM function, see Section 2.10.10 and Part II, respectively. Q Format vaxlisp -m value or vaxlisp -v MEMORY=value 0 2-20 USING VAX LISP Example 0 % vaxlisp -m 15000 Welcome to VAX LISP, Version V2.0 Lisp> Mode Interactive or Compile or Resume 2.10.8 [NO]OPTIMIZE OPTIMIZE option can be specified only as a string argument of the OThe -v option. This option lets you optimize your program according to the following qualities: Q • SPEED (execution speed.of the code} • SPACE (space occupied by the code} • SAFETY (run-time error checking of the code} • COMPILATION_SPEED (speed of the compilation process) You can optimize your program by setting a priority value for each quality. That value must be an integer in the range of Oto 3. The value O means the quality has the lowest priority in relationship to the other qualities; the value 3 means the quality has the highest priority in relationship to the other qualities. When you do not specify the OPTIMIZE option, the qualities each take the default value of 1. To suppress optimization, use the NOOPTIMIZE form of this !>ption. C The OPTIMIZE option is meaningful only if it is specified with the COMPILE (-c) option. The optimize qualifier affects only the compiler and does nothing to the interpreter, the debugger, or any other VAX LISP facility. See Chapter 6, Appendix A, and COMMON LISP: The Language for information on specifying optimization declarations. Format vaxlisp -c -v "OPTIMIZE=(guality:value[, ••. ])" file 0 2-21 USING VAX LISP Example % vaxlisp -c -v "OPTIMIZE=(SPEED:3,SAFETY:2)" mypro~.lsp 0 or . % vaxlisp -c -V "OPTIMIZE=SPEED:3" myprog.lsp Mode Compile 2.10.9 [NO]OUTPUT_FILE The OUTPUT_FILE option, abbreviated as -o, is meaningful only when it is specified with the COMPILE (-c) option. The -o option tells the compiler to write the compiled code to a specific file. If you specify the -o option with a file name, the LISP system puts the compiled code· in a file with that specified name. Use the option only when you want to change the name of the compiled file so that the source file and the compiled file have different names. By default, an output file is produced. The -o option does not specify a listing file, only a compiled file. See the LISTING (-L) option (Section 2.10.5) for an explanation of a listing file. Q Q If this option is not specified, the compiler produces a file with the same name as the source file artd a type of fas~ The NOOUTPUT_FILE option, abbreviated as -n, prevents compiled code from being written to a file. If you want only to check a file for errors, use this option with the COMPILE (-c) option. Format 0 vaxlisp -c -o file file or vaxlisp -V COMPILE,OUTPUT_FILE=file file Example % vaxlisp -c -o test.fas factorial.lsp Mode 0 Compile 2-22 USING VAX LISP 2.10.10 RESUME 0 where The RESUME option, abbreviated as -r, resumes a suspended LISP system the suspension occurred. See Section for an explanation of 2.11 suspended systems. used together. The-rand the INITIALIZE (-i) options cannot be Format vaxlisp -r file or vaxlisp -V RESUME=file Example Q % vaxlisp -r myprog.sus T Lisp> Mode Resume 0 2.10.11 [NO)VERBOSE The VERBOSE option, abbreviated as -v, lists on an output device and in the listing file the names of the functions loaded from an initialization file, and the names of functions in a-file as they are compiled. The -v option applies only to files loaded with the INITIALIZE ( -i) option o.r compiled with the COMPILE ( -c) option. Q The NOVERBOSE form of this option (the default) prevents the names of functions compiled with the COMPILE option or loaded with the INITIALIZE option from being listed in a file or at the terminal. Format vaxlisp -v -i file or vaxlisp -v VERBOSE,INITIALIZE=file or 0 2-23 USING VAX LISP vaxlisp -v -c file 0 or vaxlisp -V VERBOSE,COMPILE file Examples 1. % vaxlisp -v -i myinit.lsp Welcome to VAX LISP, Version V2.0 ; Loading contents of file /usr/users/jones/myinit.lsp ; FACTORIAL ; FACTORS-OF ; Finished loading /usr/users/jones/myinit.lsp Lisp> FACTORIAL and FACTORS-OF are functions that are loaded the LISP system from Jones's initialization file. 2. into 0 % vaxlisp -v -c myprog.lsp Starting compilation of file /usr/users/jones/myprog.lsp MULT compiled. SUB compiled. DIV compiled. 0 Finished compilation of file /usr/users/jones/myprog.l.sp O Errors, 0 Warnings % MULT, SUB, and DIV are functions compiled in the file, myprog.lsp. The compiled definitions of these functions are written to the file, myprog.fas. Q Mode Interactive or Compile 2.10.12 [NO]WARNINGS The WARNINGS option specifies that the LISP system is to produce warning messages. Warning messages are the default when you use the COMPILE (-c) option. warnings can be specified only in the -v format. A warning message indicates that the LISP system has detected a. possible error. If warnings are signaled while a file is being compiled and the value of the *BREAK-ON-WARNINGS* variable is NIL, the 2-24 Q USING VAX LISP default, the compilation continues. But, if errors are signaled, compilation of the expression causing the error is not continued though the rest of the file is compiled. See Chapter 3 for more information on the differences between warnings and errors. O The NOWARNINGS form of this option suppresses warning messag~s ano abbreviated as -w. is The following example of a warning message is the message the compiler displays for the TEST function defined in Section 2.9.3. % vaxlisp -c test.lsp Warning in TEST TEST earlier called with 2 args, wants at most 1. % oFormat vaxlisp -w -c file or vaxlisp -V NOWARNINGS,COMPILE file Example Q % vaxlisp -w -c myprog.lsp Mode Compile 0 2.11 USING SUSPENDED SYSTEMS A suspended system is a binary file that is a copy of the LISP memory in use during an interactive LISP session up to the point at which you create the suspended system. The purpose of a suspended system is to save the state of an interactive LISP session. You might want to do this if your work is incomplete. By resuming LISP from a suspended system, you can continue your work from the point at which you stopped. 2.11.1 O Creating a Suspended System The VAX LISP SUSPEND function puts in a file the LISP memory in use during an interactive LISP session, enabling you to resume the same LISP session at a later time. The SUSPEND function does not stop the current LISP session; you can continue to use the LISP session after 2-25 USING VAX LISP the SUSPEND function has put a copy of memory into a file. The SUSPEND function also automatically invokes a garbage collection o f o dynamic memory space. See Chapter 6 for information on garbage collections. In the following example, the file filex.sus is created and a copy of the memory in a LISP session is put into that file. The fil~ name can be a string, symbol, or pathname. See Chapter 6 and COMMON LISP: The Language for a description of pathnames. Lisp> (SUSPEND "filex.sus") Starting garbage collection due Finished garbage collection due Starting garbage collection due Finished garbage collection due NIL Lisp> to GC function. to GC function. to SUSPEND function. to SUSPEND function. After your file is created, the system returns to your interactive LISP session. You can exit LISP when you see the LISP prompt. Your suspended system file is place~ either in your default directory or in the directory you specified in the file specification. The file is usable only in an interactive LISP session. For a description of the SUSPEND function, see Part II. 2.11 .2 Resuming a Suspended System 0 0 To resume a suspended system, invoke the LISP system with the RESUME (-r) option and the name of the file containing the suspended system. Program execution continues from the point at which you called the SUSPEND function. See Section 2.10.10 for an explanation of the -r option. 0 0 2-26 () CHAPTER 3 ERROR HANDLING 0 The LISP system invokes the VAX LISP error handler when errors are signaled during program evaluation. This chapter explains what the error handler does when an error is signaled. Because the system's error handler might not meet your programming needs, VAX LISP allows you to create your own error handler. The procedure for creating an error handler is also explaine9 in this chapter. 3.1 0 ERROR HANDLER The VAX LISP error handler function, UNIVERSAL-ERROR-HANDLER, performs four sequential steps. Q ' 3.2 1. Checks the number of nested errors that have occurred. If three nested errors have occurred, the error handler aborts your program, displays a message, and returns you to the top-level read-eval-print loop; otherwise, the handler continues to the next step. 2. Checks the type of error. 3. Displays an error message that provides you with about the error. 4. Performs the appropriate operation for the type of error that was signaled. VAX LISP ERROR TYPES Three types of errors can program: 0 information - o occur during Fatal error 3-1 the evaluation of a LISP ERROR HANDLING • Continuable error • warning 0 When an error is signaled, the VAX LISP system displays message that provides you with the following information: signaled an error fatal • The type of error that was continuable error, or warning error, • The name of the function that caused the error • The name of the function that was used to signal the error ERROR, CERROR, or WARN • A description of the error If a continuable error, an explanation of what will happen if' 0 • you continue the program's evaluation from the point at which the error occurred The format of an error message and the information a message provides depend on the type of the error. The next three sections describe the types of errors; each description includes the error type's message format and the operation the error handler performs. -0 3.2.1 Fatal Errors When a fatal error is signaled; the error handler displays in the following format: a message Fatal error in function function-name (signaled with ERROR). Error description. In the preceding format description, function-name is the name of the function that caused the error, and ERROR is the name of the function that was used to signal the error (see Table 3-1). The error description is a message telling why the error occurred. The message is generated from the format string and the arguments in the call to the ERROR function; the message can be.displayed on more than one line. 0 An example of a fatal error message follows: Fatal error in function MAKE-ARRAY (signaled with ERROR). · Only vectors can have fill pointers. After the message is displayed, the error handler checks the va~ue of the VAX LISP *ERROR-ACTION* variable. Its value can be either the :EXIT or the :DEBUG keyword. The ERROR_ACTION (-V 3-2 Q ERROR HANDLING __ "ERROR_ACTION=valuen) option you use with the vaxlisp command sets the ralue of the *ERROR-ACTION* variable when you invoke the LISP system (see Chapter 2). When the value is :EXIT (you used the ERROR_ACTION=EXIT form of the option), the error handler causes the LISP system to exit on an error; when the value is :DEBUG (you used the ERROR_ACTION=DEBUG ·form of the option, the defaul~ in an interactive session), the handler invokes the VAX LISP debugger. C If the debugger is invoked, you can use it to locate the error in your program. After you locate the error, you can correct it and restart your program's evaluation. NOTE You cannot continue your program's evaluation from the P?int at which a fatal error occurred. 0 The *ERROR-ACTION* variable is described in Part II and is described in Chapter 4. 3.2.2 the debugger Continuable Errors c=)ihen a continuable error is signaled, ~he message in the following format: error handler displays a Continuable error in function function-name (signaled with CERROR). Error description. If continued: Continue explanation. In the preceding format d.escription, function-name is the name of the function that caused the error, and CERROR is the name of the function lhat was used to signal the error (see Table 3-1). The error description is a message telling why the error occurred. The message is generated from the format string and the arguments in the call to the CERROR function; the message can be displayed on more than one line. A line of text that explains what will happen if you continue your program's evaluation follows the error description. C An example of a continuable error message is: Continuable error in function ENTER-NAME (signaled with CERROR). The value you specified is not a string. If continued: You will be prompted for a new value. After the message is displayed, the error handler checks the value of the VAX LISP *ERROR-ACTION* variable in the same way ir.checks the c=)alue after a fatal error (see Section 3.2.1). 3-3 \ ERROR HANDLING If the debugger is invoked,,you can do one of the following: the • Continue from the error; the CERROR function performs corrective action that is specified in the error message. • Locate the error in your program. After you locate the error, you can correct it and restart your program's evaluation. The *ERROR-ACTION* variable is described in Part II and is described in Chapter 4. 3.2.3 the Q debugger Warnings A warning is an error condition .that exists in your program, which may or may not affect your program's evaluation. When this type of error occurs, the system displays a message for the following reasons: • You might want to correct the error later. • Your program might correct the error, but you should know that the error occurred. When a warning is signaled, the error handler displays the following format: a message Q in Warning in function function-name (signaled with WARN). Error description. In the preceding format description, function-name is the name of· the function that caused the error, and WARN is the name of the function that was used to signal the error (see Table 3-1). The error description is a message telling why the error occurred. The message is generated from the format string and the arguments in the call to the WARN function; the message can be displayed on more than one line. 0 Q An example of a warning error message is: Warning in function TE (signaled with WARN). 3 is not a symbol. After the message is displayed, the error handler checks the value of the *BREAK-ON-WARNINGS* variable in the same'way it checks the value *ERROR-ACTION* variable after a fatal error (see Section 3.2.1). NOTE If the value of the *BREAK-ON-WARNINGS* variable is T, the'debugger is invoked when a warning is .signaled. 3-4 0 ERROR HANDLING O If the debugger is invoked, you can use it to locate the error in your program. After you locate the error, you can correct it, exit the debugger, and then continue your program's evaluation from the point where the error occurred. The *BREAK-ON-WARNINGS* variable is described in COMMON LISP: The Language. The *ERROR-ACTION* variable is described in Part II, and the debugger is described in Chapter 4. 3.3 CREATING AN ERROR HANDLER The VAX LISP *UNIVERSAL-ERROR-HANDLER* variable is bound to the system's error handler. This binding provides you with a way to create your own error handler if the system's handler does not meet oyour programming needs. To create an error handler you must: 1. Define the error handler. 2. Bind the *UNIVERSAL-ERROR-HANDLER* variable to handler. your defined The *UNIVERSAL-ERROR-HANDLER* variable is described in Part II. Q 3.3. 1 Defining an Error Handler To define an error handler, you must define an error handler function. This function must be able to accept two or more arguments since the LISP system passes at least two arguments to the error handler each time an error occurs in a program. Therefore, specify the arguments in an error-handler definition in the following format: Q function-name error-signaling-function &REST args The arguments information: provide the error handler with the following - • The name of function • The name of the error-signaling function • The arguments that were passed to the error-signaling function the function 0 3-5 that called the error-signaling ERROR HANDLING An example of an error handler definition is: 0 Lisp> (DEFUN CRITICAL-ERROR-HANDLER (FUNCTION-NAME ERROR-SIGNALING-FUNCTION &REST ARGS) (WHEN (OR (EQ ERROR-SIGNALING-FUNCTION 'ERROR) (EQ ERROR-SIGNALING-FUNCTION 'CERROR)} (FLASH-ALARM-LIGHT)) (APPLY #'UNIVERSAL-ERROR-HANDLER FUNCTION-NAME ERROR-SIGNALING-FUNCTION ARGS)) CRITICAL-ERROR-HANDLER The preceding error handler checks whether a fatal or continuable error is signaled. If either type of error is signaled, the handler calls the function FLASH-ALARM-LIGHT and then passes the error signal information to the VAX LISP error handler. 0 When you define an error handler, the definition can include a call to the UNIVERSAL-ERROR-HANDLER function. If the definition does not include a call to this function and you want the handler to check the value of the *ERROR-ACTION* or *BREAK-ON-WARNINGS* variable, you must include a check of the variable in the handler's definition. If you want an error handler to display error messages in the formats described in Sections 3.2.1 to 3.2.3, include a call to either the PRINT-SIGNALED-ERROR function. UNIVERSAL-ERROR-HANDLER or Descriptions of these functions are provided in Part II. The next three sections describe the arguments an error be able to accept. 0 handler ·must 3.3.1.1 Function Name - The function-name argument is the name of the function that calls an error-signaling function. This argument enables the error handler to include the function's name in the error message the handler displays. Q 3.3.1.2 Error-Signaling Function - The error-signaling-function argument is the name of the error-signaling funct~on that is called to generate the error signal. Depending on which function is called, a fatal error, continuable error, or warning is signaled. The error handler uses the error-signaling-function determine the contents of the args argument. argument to Table 3-1 lists the functions that can be passed as . the error-signaling-function argument and briefly describes each function. 3-6 Q ERROR HANDLING Table 3-1: Error-Signaling Functions OFunction Description CERROR Function Signals a continuable error ERROR Function Signals a fatal error WARN Function Signals a warning See COMMON LISP: The Language for detailed descriptions of the CERROR and ERROR functions. See Part II for a description of the WARN function. Arguments - The args argument is the list of arguments passed to the error-signaling function when the error-signaling function is invoked. The contents of the list depends on which function is invoked. The list can include one or two format strings and their corresponding arguments. The format strings and arguments are passed to the FORMAT function, which produces the correct error message. 03.3.1.3 03.3.2 Binding the *UNIVERSAL-ERROR-HANDLER* Variable Once you define an error-handling function, you must bind the *UNIVERSAL-ERROR-HANDLER* variable to it. The following example shows how to bind the variable to a function: Lisp> (LET ((*UNIVERSAL-ERROR-HANDLER* #'CRITICAL-ERROR-HANDLER)) (PERFORM-CRITICAL-OPERATION)) OThe LET special form binds the *UNIVERSAL-ERROR-HANDLER* variable to the CRITICAL-ERROR-HANDLER function that was defined in Section 3.3.1 and calls a function named PERFORM-CRITICAL-OPERATION. When the form is exited because the evaluation finished or the THROW function is called, the *UNIVERSAL-ERROR-HANDLER* variable is restored to its previous value. 0 3-7 0 0 0 0 0 0 CHAPTER 4 DEBUGGING FACILITIES O O Debugging is the process ' of locating and correcting programming errors. When an error is signaled, the VAX. LISP error handler displays a message, which provides you with your initial debugging information: the error type, the name of the function that caused the error, the name of the function the LISP system used to signal the error, and a description of the error. Once you know the name of the function that caused an error, you can use the VAX. LISP debugging functions and macros to locate and correct the programming error. Table 4-1 lists the debugging functions and macros with a brief description of each. See Part II for more detailed descriptions. Table 4-1: Debugging Functions and Macros Name Function or Macro OAPROPOS Function Locates symbols whose print names contain a specified string argument as a substring and displays information about each symbol it locates. APROPOS-LIST Function Locates symbols whose print names contain a specified string argument as a substring and returns a list of the symbols it locat~s. l:!REAK Function Invokes the break loop. DEBUG Function Invokes the VAX. LISP debugger. DESCRIBE Function Displays detailed specified object. 0 Description 4-1 information about a DEBUGGING FACILITIES Table 4-1 (cont.) ~~~~~~~~~~-o Name Function or Macro DRIBBLE Function Sends the input and the output of an interactive LISP session to a~specified file. ROOM Function Displays information about the state internal storage and its management. Description of < STEP Macro Invokes the stepper. TIME Macro Displays timing information about evaluation of a specified form. the TRACE Macro Enables the macros. tracer for functions and UNTRACE Macro Disables the tracer macros. for functions and 0 This chapter provides the following: o A list of the functions and the macro that debugging information provide @ Descriptions of two variables that control the output debugger, the stepper, ·and the tracer facilities • A description of the VAX LISP control stack you with of the O • Explanations of how to use the following debugging facili"ties: 0 Break loop A read-eval-print loop you can invoke while the LISP system is evaluating a program. Debugger A control stack interactively to inspect and control stack frames. debugger you can use modify the LISP system's Stepper A facility you can use interactively through a form's evaluation. to Tracer A facility you can use to inspect evaluation. program's a step 0 4-2 DEBUGGING FACILITIES 4., CONTROL VARIABLES OvAX LISP provides two variables that control the output of the debugger, the stepper, and the tracer facilities: *DEBUG-PRINT-LENGTH* and *DEBUG-PRINT-LEVEL*. These variables analogous to the COMMON LISP variables *PRINT-LENGTH* *PRINT-LEVEL* but are used only in the debugger. are and *DEBUG-PRINT-LENGTH* Controls the number of displayed elements at each level of a nested data object. The variable's value must either be an integer or NIL. The default value is NIL (no limit). *DEBUG-PRINT-LEVEL* Controls the number of displayed levels of a nested data object. The variable's value must either be an integer or NIL. The default value is NIL (no limit). 0 4.2 CONTROL STACK The control stack is the part of LISP memory that stores calls to functions, macros, and special forms. The stack consists of stack frames. Each time you call a function, macro, or special form, the {:JVAX LISP system does the following: 0 1. Opens a stack frame. 2. Pushes the name of the function associated with the function, macro, or special form that was called onto the stack frame. 3. Pushes the function's arguments onto the stack frame. 4. Closes the stack frame when all the function's arguments on the stack frame. 5. Evaluates the function. are The LISP system can have several open stack frames at a time because the arguments used by LISP functions are frequently LISP expressions. Each control stack frame has a frame number; which is displayed as part of the stack frame's output. Stack frame numbers are displayed ~n the output of the debugger, the stepper, and the tracer. 0 There is always one active stack frame, and it can either be significant or insignificant. Significant stack frames are those that invoke documented and user-created functions. Insignificant stack frames are those that invoke undocumented functions. 4-3 DEBUGGING FACILITIES Debugger commands show only significant stack frames unless you spec 1 fy the ALL modifier with a debugger command ( see Section 4.~.3.1). Significant stack frames store one of the following calls: @ A call to a function named by a symbol that is in the c ) current package • A call to a function that is accessible in the current package and is explicitly or implicitly called by another function that is in the current package See COMMON LISP: The Language for information on packages. Many stack frames in the control stack store internal, undocumented functions. These stack frames are insignificant to most users; therefore, by default, the debugger does not display their representation. However, if you are using the debugger and you want to examine these stack frames, you can specify the ALL modifier with debugger commands. 4.3 ACTIVE STACK FRAME The active stack frame is a stack frame that stores a call to a function the LISP system is evaluating. The system can evaluate a function call in the active stack frame because the frame contains all the function's argument values. Only one stack frame is active at a time and an active stack frame can exist anywhere on the control stack. The active stack frame can have a previous active stack frame and/or it can have a next active stack frame. The previous active stack frame represents the caller of the function in the current active stack frame. 4.4 Q O 0 BREAK LOOP The break loop is a read-eval-print loop that you can invoke to debug a program. You can invoke the break loop while a program is being evaluated. If you do, the evaluation is interrupted and you are placed in the loop. 4.4.1 Invoking the Break Loop You can invoke the break loop by calling the BREAK function. ways of using the BREAK function to debug a program are: 4-4 The two Q DEBUGGING FACILITIES () • Use a keyboard function to invoke the BREAK function while your program is being evaluated. directly • Put the BREAK function in specific places in your program. In either case, the BREAK function displays a message~ (if you specified one in your form calling the BREAK function) and enters a read-eval-print loop. If you specified a message, the BREAK function displays the message in the following format: Break in function function-name (signaled with BREAK). description. 0 In the preceding format description, function-name represents the name of the function the LISP system was evaluating when you entered the. break loop. BREAK is the riame of the function that caused the LISP system to invoke the break loop. The description is optional and can be printed on more than one line. A description usually provides the reason the break loop was invoked. An example of a break loop message follows: Break in function CHECK-INPUT (signaled with BREAK). Values are too high. the message is displayed, a prompt is displayed at the left O After margin of your terminal: Break> 4.4.2 Exiting the Break Loop you are ready to exit the break loop and continue your program's O when evaluation, invoke the VAX LISP CONTINUE function. Break> (CONTINUE) The CONTINUE function causes the evaluation of your program to continue from the point where the LISP system encountered the BREAK function. If you are in a nested break loop and you invoke the CONTINUE function, you are placed in the previous break-loop level. A description of the CONTINUE function is provided in Part II. 0 4-5 DEBUGGING FACILITIES 4.4.3 Using the Break Loop Once you are in the break loop, you can check what your program is doing by interacting with the LISP system as though you were in the top-level-loop. For example, suppose you define a variable named *FIRST* and a function named COUNTER, which uses the variable *FIRST*. 0 Lisp> (DEFVAR *FIRST* 0) *FIRST* Lisp> (DEFUN COUNTER NIL (IF(< *FIRST* 100) (PROGN (INCF *FIRST*) (COUNTER)) *FIRST*)) COUNTER You can bind <CTRL/\> (A\) to the BREAK function in the following way: BIND-KEYBOARD-FUNCTION #FS #'BREAK 0 Then, you interrupt a function's evaluation by typing <CTRL/\>. Lisp> (COUNTER)<RET> <CTRL/\> Break> Once you are in the break variable *FIRST*. you loop, can check the value of the of the function 0 Break> *FIRST* 16 Break> If you call the CONTINUE function, r.uUNTER continues. the evaluation 0 Break> (CONTINUE) After you call the CONTINUE function, you can see that the evaluation was continued by invoking the break loop again and rechecking the value of the variable *FIRST*. <CTRL/\> Break> *FIRST* 93 Break> Use the CONTINUE function again to complete the_function's evaluation. Break> (CONTINUE) 100 0 4-6 DEBUGGING FACILITIES Changes that you make to global variables and global definitions while C;ou are in the break loop remain in effect after you exit the loop and your program continues. For example, if you are in the break loop and you find that the value of the variable named *FIRST* has an incorrect value, you can change the variable's value. The change remains in effect after you exit the break loop and continue your~program's evah1ation. NOTE The forms you type while you are in the break loop are evaluated in a null lexical environment, as though they are evaluated at top level. Therefore, you cannot examine the lexical variables of a program that you interrupt with'the break loop. To examine those lexical variables, invoke the debugger (see Section 4.5). For information on lexical environments, see 0 COMMON LISP: The Language. 4.4.4 Break Loop Variables The break loop uses a copy of the top-level-loop variables (plus (+), ?yphen (-), asterisk (*), slash (/), and so on) the same way the cop-level loop uses them (see COMMON LISP: The Language). These variables preserve the input expressions you specify and the output values the VAX LISP system returns while you are in the break loop. C 4.5 DEBUGGER C ~he VAX LISP debugger is a control stack debugger. You can use it lnteractively to inspect and modify the LISP system's control stack frames. The debugger has a pointer that points to the current stack frame. The current stack frame is the last frame for which the debugger displayed information. The debugger provides several commands that: Q e Display help ~ Evaluate a form or reevaluate a function call stores ® Handle errors e Move the pointer from one stack frame to another e Inspect or modify the function call in a stack frame 4-7 a stack frame DEBUGGING FACILITIES ~ Display a summary of the control stack The debugger reads its input from and prints its output to the bound to the *DEBUG-IO* and the *TRACE-OUTPUT* variables. streamo NOTE The stack frames the debugger displays are active. no longer Before you use the debugger, you should be familiar with the VAX control stack. The control stack is described in Section 4.2. 4.5.1 LISP 0 Invoking the Debugger The VAX LISP system invokes the debugger when errors occur. You invoke the debugger by calling the VAX LISP DEBUG function. example: can For Lisp> (DEBUG) When the debugger is invoked, a message that identifies the debugger, a message that identifies the current stack frame, and the command prompt are displayed at the left margin of your terminal in the following format: Q ' Control Stack Debugger Frame #5: (DEBUG) Debug n> Q The letter n in the prompt represents an integer, which indicates the number of the nested command level you are in. The value of n increases by one each time the command level increases. For example, the top-level read-eval-print loop is level 0. If an error is invoked from the top-level loop, the debugger displays the prompt Debug 1>. If you make a mistake again causing an error while within the debugger, that error causes the debugger to display the prompt Debug 2>. After the debugger is invoked, you can use the debugger commands inspect and modify the contents of the system's control stack. to A description of the DEBUG function is provided in Part II. 0 4-8 DEBUGGING FACILITIES 4.5.2 Exiting the Debugger 0 Todebugger exit the debugger, use the QUIT debugger command. It causes the to return control to the previous command level. Debug 2> QUIT Debug 1> If you specify the QUIT command when the debugger command level is 1 (indicated by the prompt Debug 1>), the command causes the debugger to exit and returns you to the system's top level. For example: Debug 1> QUIT Lisp> 0 By default, the QUIT command displays a confirmation message before the debugger exits if a continuable error causes the debugger to be invoked. For example: Debug 1> QUIT Do you really want to ret~rn to the previous command level? If you type YES, the debugger returns control to the previous level. command Do you really want to return to the previous command level? YES Lisp> 0 If .you type NO, the debugger prompts you for another command. Do you really want to return to the previous command level? NO Debug 1> You can prevent the debug_ger from displaying the confirmation message by specifying the QUIT command with a value other than NIL. For example: O Debug 1> QUIT T Lisp> A description of the QUIT command is provided in Section 4.5.3.2. '1,5.3 0 Using Debugger Commands The debugger commands let you inspect and modify the current control stack frame and move to other stack frames. You must specify many of the debugger commands with one or more arguments that qualify command operations. These arguments are listed in Section 4.5.3.1. 4-9 DEBUGGING FACILITIES You can abbreviate debugger commands to as few characters as you like, as long as no ambiguity is in the abbreviation. Enter a debugger command by typing the command name and then pressing the RETURN key. For example: or ,Q abbreviation Debug 1> BACKTRACE<RET> If you pres,s only the RETURN key, the debugger prompts you for another command. Table 4-2 provides a summa·ry of the debugger commands. "Detailed descriptions of the commands are provided in Section 4.5.3.2. Table 4-2: Debugger Commands 0 Command Description BACK TRACE Displays a backtrace of the control stack. BOTTOM Moves the pointer to the first stack frame on control stack. CONTINUE Enables you to correct a continuable error. DOWN Moves the pointer down the control stack. ERROR Redisplays the error message that when the debugger was invoked. EVALUATE Evaluates a specified form. GOTO Moves the pointer to a specified stack frame. HELP (or) ? Displays help text about the debugger commands. QUIT Exits to the previous command level. REDO Invokes the function in the current stack frame. RETURN Evaluates its arguments. and causes the current stack frame to return the same values the evaluation returns. SEARCH Searches the function. SET Sets the values of the components in stack frame. control 4-10 stack was for the 0 displayed Q specified a the current 0 DEBUGGING FACILITIES ~ble 4-2 (cont.) \___G'Jmmand Description SHOW Displays information stored in the frame. STEP Invokes the stepper current stack frame. function in the TOP . Moves the pointer to the last stack frame control stack. in the UP Moves the pointer up the control stack. WHERE Redisplays the argument list and the function name in the current stack frame. for the current stack O- - - - - - - - - - 4.5.3.1 Arguments - Some debugger commands require an argument; other debugger commands accept optional arguments. An argument whose value is an integer is usually optional; an argument whose value is a symbol or form is required. If you do not specify an argument that is required, the debugger prompts you for the argument. For example: 0 Debug 1> RETURN<RET> First Value: The debugger does not prompt for arguments if you specify them in command line. the Enter an argument after the command it qualifies and RETURN key. For example:. the O then press Debug 1> DOWN ALL<RET> The types of arguments you can specify with debugger commands are: • Debugger command • Symbol • Form • Integer • Function name 0 • Modifier 4-11 DEBUGGING FACILITIES NOTE Only parenthesized expressions evaluate (that is, arguments EVALUATE command) are evaluated. and arguments specified with 0 to the The preceding arguments are self-explanatory with the exception of the integer and modifier arguments. Integer arguments represent control stack frame numbers. Each stack frame on the control stack has a frame number, which the debugger displays as part of the stack frame's output. The debugger reassigns these numbers each time it is invoked. You can specify a frame number in a debugger command to refer to a specific stack frame. If you refer to a t'rame number that is outside the current debugging session, an error is signaled. If you refer to the stack frame number of a frame that was established in another debugging session in a current nested session, the command in which you specify the frame number results in an erroneous or unpredictable result. 0 Q Table 4-3 provides a summary of the modifier arguments you can specify with debugger commands. Table 4-3: Debugger Command Modifiers ~~~~~~~~~~-0 Modifier Command Modification ALL Operates on both stack frames. ARGUMENTS Operates on the arguments specified function in the current stack frame. CALL Operates on the call to the current stack frame. DOWN Moves the pointer down the control stack. FUNCTION Operates on the function stack frame. HERE Operates on the current stack frame. NORMAL Displays the function name and the in the control stack frames. argument list QUICK Displays the function name in frames. control stack TOP Starts a backtrace stack. the control significant and object in the insignificant with the the current ~ 4-12 at the top of 0 . Q -~...... DEBUGGING FACILITIES Table 4-3 (cont.) 0 Modifier Command Modification UP Moves the pointer up the control stack. VERBOSE Displays the function name, argument list, local variable bindings, and special variable bindings in the control stack frames. 4.5.3.2 Debugger Commands - The VAX LISP debugger provides commands that you can use to move through and modify the system's control stack. 0 Help Command HELP ? 0 The HELP command displays help text about the debugger commands. You_ can specify this command with one argument, which is the name of the debugger command about which you want help text. If you specify the HELP command without an argument, the debugger displays a list of the debugger commands. You can abbreviate this command mark (?). by using a question Evaluation Command You can evaluate LISP expressions while you are in the debugger . . If you want the LISP system to evalute a parenthesized form, you can specify the form and then press the RETURN key. If you want the system to evaluate a symbol, you must use the EVALUATE command. You can also evaluate expressions by entering the break loop. For information on the break loop, see Section 4.4. 0 EVALUATE The EVALUATE command explicitly evaluates a specified form. You must specify the command with an argument that is the form you want the LISP system to evaluate. The system evaluates the form in the lexical environment of the current stack frame. 0 4-13 ..,.-. --. . . ...J ·. .' ~. ,' :" , :;' .. ' DEBUGGING FACILITIES Error-Handling Commands The debugger deals with errors that invoke the debugger. Each of the following debugger commands deals with errors in a different way. CONTINUE The CONTINUE command causes the debugger to r~turn NI~, letting you return from a continuable error or from a warning if the value of the *BREAK-ON-WARNINGS* variable is T. This command is not the same as the CONTINUE function. See Chapter 3 for a descrf~tion of error types. QUIT The QUIT command lets you exit to the previous command level. If the current level of the debugger is 1, the· command causes the debugger to exit to the LISP prompt (Lisp>). You can specify this command with an optional argument. If a continuable error invokes the debugger and the argument is NIL, the debugger displays a confirmation message. If you respond to the message by typing YES, the.command returns control to the previous command level. If the argument is not NIL, the debugger does not display a message. The default value for the optional argument is NIL. REDO The REDO command invokes the function in the current stack frame, causing the LISP system to reevaluate the function in that frame. This commard is useful for correcting errors that are not continuable, such as unbound variables and undefined functions. To do so, first bind th• variables or defin£ the function·with the SET command, then use the REDO co r, Htand. RETURN The RETURN command evaluates its arg·,.rnents and causes the debugger to force the current st:,ck frame to return the same values the evaluation r~turns. You must specify the command with an arguru!nt that is a form. When the command is executed, the fo;sm is evaluated. When the evaluation is complete the current stack frame returns the same· values that .:.lie evaluated form returns. S'l'EP 0 0 0 0 The STEP command invokes 'the step;·er for the function that is in the current stack f r,1me. When the stepper is invoked, the LISP system reev~~uates the function. This command is useful if you w,·1t to repeat an error to get information about the caust of the error.· 0 4-14 DEBUGGING FACILITIES Movement Commands 0 The movement commands move the debugger's pointer to another stack frame. The debugger displays the new stack frame's information. BOTTOM The BOTTOM command moves the pointer to 'the first significant stack frame on the control stack. If you specify the ALL modifier with the BOTTOM command, the command moves the pointer to the first (oldest) stack frame on the control stack whether the frame is significant or insignificant. DOWN The DOWN command moves the pointer toward the bottom of the control stack, one frame at a time. You can specify this command with optional arguments. One of the optional arguments is the ALL modifier. If you specify ALL, the command moves the pointer down the significant and insignificant stack frames on the control stack. 0 You can also specify an optional integer argument, which indicates the number of stack frames down which the command is to move the pointer. OGOTO SEARCH 0 The GOTO command moves the pointer to a specified stack frame. You must specify this command with an integer that specifies the numbe·r of the stack frame. The SEARCH command searches the control stack for a specified function name. You must specify this command with two arguments. The first argument must be either the UP or the DOWN modifier to specify the direction of the command's search. The second argument must be the name of the function for which the command is to search. You can also specify an optional integer argument. This argument must follow the function name argument in the command specification. The integer you specify indicates the number of occurrences of the specified function name that you want the command to skip. TOP The TOP command moves the pointer to the last (newest) significant stack frame on the control stack. If you specify the ALL modifier with the TOP command, the command moves the pointer to the last stack frame on the control stack whether the frame is significant or insignificant. 0 4-15 DEBUGGING FACILITIES UP The UP command moves the pointer toward the top of the control stack. You can specify this command witn~ optional arguments. One of the optional arguments is'-._./ the ALL modifier. If you specify it, the command moves the pointer up the significant and insignificant stack frames on the control stack. You can also specify an optional integer argument. It indicates the number of stack frames up which the command is to move the pointer. WHERE The WHERE command redisplays the function argument list in the current stack frame. name and I Inspection and Modification Commands You can inspect and change. the information in a function call before the LISP system evaluates the call. To do this, use the inspection and modification commands. O ERROR The ERROR command redisplays the error message that was displayed for the error that invoked the debugger. SET The SET command sets the values of the components i n o the current stack frame. You must specify this command with three arguments. The first argument must be either the ARGUMENTS or the FUNCTION modifier. The modifier determines what the command sets. The following list 'describes what is set when you specify each modifier: -- The value of an argument in the current • ARGUMENTS stack frame. FUNCTION -- The function object in the current stack Q • frame. If you specify the ARGUMENTS modifier, the second argument must be the symbol that names the .argument to be set, and the third argument must be a form that evaluates to the new value •. If you specify the FUNCTION modifier, the second argum~nt must be a form that evaluates to a function or the name of a function. The new function must take the same number of arguments the old function takes. SHOW The SHOW command displays information stored in the current stack frame. You must specify this command with the ARGUMENTS, CALL, FUNCTION,.or HERE modifier. o · The modifier determines what the command is to display. 4-16 DEBUGGING FACILITIES 0 0 The following list describes what the command when you specify each modifier: displays • ARGUMENTS -- A list of the arguments in the stack frame. current • CALL -- The function call that.created the current stack frame. The command displays the function call so that its output is easy to read. The arguments in the call are represented by their values. • FUNCTION·-- The function in the current stack frame. The function can be either interpreted or compiled with the COMPILE function. The function cannot be displayed if it is a system function or if it is loaded in a compiled file. • HERE -- A description of the current stack frame. Backtrace Command BACK TRACE o. The BACKTRACE command displays the argument list of each stack frame in the control stack, starting from the top of the stack. You earl specify the command with modifiers to specify the style and extent of the backtrace. The modifiers you can specify are ALL, NORMAL, QUICK, HERE, TOP, or VERBOSE. By default, the command uses the NORMAL and the TOP modifiers. The following list describes the style or extent the BACKTRACE command uses when you specify each modifier: 0 • ALL -- Displays significant and insignificant frames. • NORMAL -- Displays the function list in each stack frame. • QUICK -- Displays the function name frame. in each stack • HERE. -- Starts the backtrace'at frame. current stack • TOP -- Starts the control stack. backtrace name and the at the top argument - of the Displays the function name argument • VERBOSE list, and local variable bindings in each stack 7 0 stack frame. 4-17' DEBUGGING FACILITIES 4.5.4 Using the DEBUG-CALL Function The DEBUG-CALL function returns a list representing the call at the current debug stack frame. This function is a debugging tool and takes no arguments. The list returned by DEBUG-CALL can be used to access the values passed to the function in the current st~ck frame. If used outside the debugger, DEBUG-CALL returns NIL. The following example shows how to use the function: Lisp> (SETF THIS-STRING "abed") "abed" Lisp> (FUNCTION-Y THIS-STRING 4) ...• Error in function FUNCTION-Y Frame #4 (FUNCTION-Y "abed" 4) Debug 1> (SETF STRING (SECOND (DEBUG-CALL))) "abed" Debug 1> (EQ "abed" STRING) NIL Debug 1> (EQ THIS-STRING STRING) 0 0 T In this case, the function in the current stack frame is FUNCTION-Y. The call to (DEBUG-CALL) returns the list (FUNCTION-Y "abed" 4). The form (SECOND (DEBUG-CALL)) evaluates "abed", the first argument to FUNCTION-Y in the current stack frame. Note that the string returned by the call (SECOND (DEBUG-CALL)) is the same string passed to the function FUNCTION-Y. See the description of the TRACE macro for another example of the use of the DEBUG-CALL function. 4.5.5 0 Sample Debugging Sessions 1. Lisp> (DEFUN FIRST-ELEMENT (X) (CAR X)) FIRST-ELEMENT Lisp> (FIRST-ELEMENT 3) 0 Fatal error in function CAR (signaled with ERROR). Argument must be a list: 3 Control Stack Debugger Frame #11: (CAR 3) Debug 1> DOWN Frame #8: (BLOCK FIRST-ELEMENT (CAR X)) Debug 1> DOWN Frame #5: (FIRST-ELEMENT 3) Debug 1> SHOW HERE It is a cons Format: FIRST-ELEMENT x -- Arguments X : 3 4-18 0 DEBUGGING FACILITIES Debug 1> SET Type of SET operation: ARGUMENT Argument Name: X New Value: '(1 2 3) Debug 1> WHERE Frame #5: (FIRST-ELEMENT (1 2 3)) Debug 1> REDO 0 1 Lisp> The argument in a stack frame is changed from an integer to a list, and the function is reevaluated with the correct argument. 2. O Lisp> (DEFUN PLUS-Y (X) - (+ X Y)) PLUS-Y Lisp> (PLUS-Y 4) Fatal error in function SYSTEM::%EVAL (signaled with ERROR). Symbol has no value: Y Control Stack Debugger Frame #8: (BLOCK PLUS-Y (+ X Y)) Debug 1> DOWN Frame #5: (PLUS-Y 4) Debug 1> UP Frame #8: (BLOCK PLUS-Y (+ X Y)) Debug 1> (SETF Y 1) 0 1 Debug 1> WHERE Frame #8: (BLOCK PLUS-Y Debug 1> EVALUATE Evaluate: Y (+ X Y)) 1 Debug 1> DOWN Frame #5: (PLUS-Y 4) Debug 1> REDO 5 Lisp> 0 The value of the variable Y is set with the SETF the body of the function PLUS-Y is reevaluated. 3. Lisp> (DEFUN·ONE-PLUS (X) (1+ X)) ONE-PLUS Lisp> (ONE-PLUS '(1 2 3 4)) Fatal error in function 1+ (signaled with ERROR). Argument must be a number: (1 2 3 4) 0 Control Stack Debugger Frame #11 : ( 1 + ( 1 2 3 4 ) ) 4-19 macro, and DEBUGGING FACILITIES Debug 1> SET FUNCTION Function: 'CAR Debug 1> WHERE Frame #11: (CAR (l 2 3 4)) Debug 1> DOWN Frame #8: (BLOCK ONE-PLUS (1+ X)) Debug 1> UP Frame #11: .(CAR (1 2 3 4)) Debug 1> REDO 0 1 Lisp> (PPRINT-DEFINITION 'ONE-PLUS) (DEFUN ONE-PLUS (X) (1+ X)) Lisp> This example shows that changing the contents of a stack frame does not change the contents of other stack frames or the function that was originally evaluated. 0 4.6 STEPPER The stepper is a facility you can use to step interactively through the evaluation of a form. You can control the stepper with stepper commands as it displays and evaluates each subform of a specified form. The stepper has a pointer that points to the current stack frame ono the system's control stack. The current stack frame is the last frame for which the stepper displayed information. The stepper prints its command interaction to the stream bound to the *DEBUG-IO* variable; it prints its output to the stream bound to the *TRACE-OUTPUT* variable. 0 4.6. 1 Invoking the Stepper You can invoke the stepper by calling the STEP macro with a form as an argument. The following example invokes the stepper with a call to a function named FACTORIAL: Lisp> (STEP (FACTORIAL 3)) When the stepper is invoked, it displays a line of text that includes the first subform of the specified form and the stepper prompt. The output is displayed at the left margin of your terminal in the following format: 0 : #9: (FACTORIAL 3) Step> 4-20 DEBUGGING FACILITIES O After the stepper is invoked, you can use the stepper commands to control the operations the stepper performs and the way the stepper displays output. 4.6.2 Exiting the Stepper Usually, when you use the stepper, you press the RETURN key until the stepper steps through the entire specified form. If you want to exit from the stepper before it steps through a form, use the QUIT stepper command. This command c·auses the stepper to return control to the previous command level that was active when the stepper was invoked. Step> QUIT Lisp> O Bycauses default, the QUIT command displays a confirmation message before it the stepper to exit. For example: Step> QUIT . Do you really want to exit the stepper? If you type YES, the stepper exits and returns control to the level that was active when the stepper was invoked. 0 command Do you really want to exit the stepper? YES Lisp> If you type NO, the stepper prompts you for another command. Do you really want to exit the stepper? NO Step> can prevent the stepper from displaying the confirmation message O You by specifying the QUIT command with a value other than NIL. For example: Step> QUIT T Lisp> A description of the QUIT command is provided in Section 4.6.4.2. I 4.6.3 Q Stepper Output Once you invoke the displays two types form: stepper with a specified form, the stepper of information as the LISP system evaluates the 4-21 DEBUGGING FACILITIES • A description of each subform of the specified form • A description 0£ the return value from eich subform 0 If the subform being evaluated is a symbol, the stepper displays the descriptions in a line of text that includes the following :;. information: • The nested level of the symbol • The control stack frame number that indicates where the symbol and its return value are stored o The symbol • The return value 0 The stepper indicates the nested level of a symbol with indentation. When the number of nested levels increases, the indentation increases. After making the appropriate indentation, the stepper displays the control stac·k frame number, the symbol, and the return value in the following format: · #n: symbol=> return-value If the subform being evaluated is not a symbol, the stepper displays the descriptions in a line· of text that includes the following information: e The nested level of the subform • The control stack subform is stored frame number that indicates where Q the • The subform 0 The stepper indicates the nested level of a subform with indentation. When the number of nested levels increases, the indentation increases. After making the appropriate indentation, the stepper displays the control stack frame number and the subform in the following format: #n: (subforrn) The description of a return value includes the'following information: e The nested level of the return value e The control stack frame number that indicates where the return value is stored • The return value 0 4-22 DEBUGGING FACILITIES C The stepper also indicates the nested level of each return value with indentation. The indentation matches the· indentation of the corresponding call. After making the appropriate indentation, the stepper displays the control stack frame number and the return value in the following format: #n => return-value Suppose you define a function named FACTORIAL. Lisp> (DEFUN FACTORIAL (N) (IF(<= N 1) 1 (* N (FACTORIAL (- N 1))))) FACTORIAL The following example illustrates the format of the output the stepper displays when you invoke it with the form (FACTORIAL 3): 0 0 0 Lisp> (STEP (FACTORIAL 3)) #4: (FACTORIAL 3) Step> STEP : #10: (BLOCK FACTORIAL (IF(<= N 1) 1 (• N (FACTORIAL (- N 1))))) Step> STEP : : #14: (IF (<= N 1) 1 (* N (FACTORIAL (- N 1)))) Step> STEP : : : #18: ( <= N 1) Step> STEP : : : : #22: N => 3 : : : #18 => NIL : : : #17: (* N (FACTORIAL (- N 1))) Step> STEP : : : : #21 : N => 3 : : : : #21: (FACTORIAL (- N 1)) Step> STEP : : : : : #25: (- N 1) Step> STEP : : : : : : #29: N => 3 : : : : : #25 => 2 : : : : : #27: (BLOCK FACTORIAL (IF(<= N 1) 1 (* N (FACTORIAL (- N 1))))) Step> OVER : : : #27 => 2 : : : #21 => 2 : : : #17 => 6 : : #14 => 6 : #10 => 6 #4 => 6 6 O Note that the FACTORIAL function is a recursive function and, in the preceding example, has three levels of recursion. The stepper indicates the nested level of each subform with an indentation, indicated with a colon followed by a space (: ). The stepper indicates the number of the stack frame in which a call is.stored with an integer. The integer is preceded with a number sign and followed by a colon (#n:). . 4-23 DEBUGGING FACILITIES The nested level of each return value matches the indentation of the corresponding subform. The stepper indicates the number of the control stack frame onto.which the LISP system pushes the value with an integer that matches the stack frame number of the corresponding sutform. The integer is preceded by a number sign and followed by an arrow (#n =>) that points to the return value. 4.6.4 Ci Using Stepper Commands Stepper commands let you use the stepper to step through the evaluation of a LISP expression, form by form. You must specify some commands with arguments. They provide the stepper with additional information on how to execute the command. You can abbreviate stepper commands to as few characters as you as long as no ambiguity is in the abbreviation. like, Q Each time a command is executed, the stepper displays a return value if the subform returns a value, displays the next subform, and prompts you for another command. Enter a stepper command by typing the command name or abbreviation and then pressing the RETURN key. For example: Step> STEP<RET> : : : #22: (IF(<= N 1) 1 Step> (* 0 N (FACTORIAL (- N 1)))) If you press only the RETURN key, the LISP system evaluates the subform the stepper displays. · If the evaluation returns a value, the stepper displays the value and the next subform and then prompts you for another command. Step><RET> 0 #22: (IF(<= N 1) 1 (* N (FACTORIAL(~ N 1)))) Step> Table 4-4 provides a summary of the stepper commands. the stepper commands are provided in Section 4.6.4.2. Table 4-4: Descriptions of Stepper Commands Command Description BACKTRACE Displays a back trace of a form's evaluation .. DEBUG Invokes the debugger. EVALUATE Evaluates disabled. a specified 4-24 form. with the stepper Q DEBUGGING FACILITIES Table 4-4 (cont.) ~~~~~~~~~~- O Command 0 Description FINISH Finishes the evaluation of the form that was specified in the call to the STEP macro with the stepper di sabled. • HELP (or) ? Displays help text about the stepper commands. OVER Evaluates the subform in the current with the stepper disabled. SHOW Displays the subform in the current stack frame. QUIT Exits the stepper. RETURN Forces the current stack frame to return a value. STEP Evaluates the subform in the current with the stepper enabled. UP Evaluates subforms with the stepper disabled until the stepper gets back to a subform that contains the subform in the current stack frame. stack stack frame frame 0 4.6.4.1 Arguments - Stepper command arguments modify the operations the stepper commands perform. Some stepper commands require an argument, and some commands accept optional arguments. The arguments you can specify with the stepper commands are: • Q Integer • Form • Stepper command NOTE and arguments specified with to the Enter an argument after the command it modifies and press key. For example: the Only parenthesized expressions evaluate (that is, arguments EVALUATE command) are evaluated. O Step> EVALUATE(<= N l)<RET> 4-25 RETURN DEBUGGING FACILITIES If an argument is required and you omit it, the for the argument. For example: stepper prompts you Step> EVALUATE<RET> Evaluate: (<= N 1) The stepper does not prompt for arguments if you specify the& command line. in 0 the 4.6.4.2 Stepper Commands - The stepper provides c9mmands that let you control how it steps through a form's evaluation. Help Command HELP ? 0 The HELP command displays help text about the stepper commands. You can specify this command with one argument, the name of the stepper command about which you want help text. If you specify the HELP command without an argument, the stepper displays a list of the stepper commands. You can abbreviate this command mark (?). by using a question 0 Evaluation Command You can evaluate· expressions while. you are in· the stepper. If you want the LISP system to evaluate a parenthesized form, you can specify the form and then press the RETURN key. If you want the system to evaluate a symbol, you must use the EVALUATE command. I EVALUATE Q The EVALUATE command causes the LISP system to explicitly evaluate a specified form. You must specify the command with an argument, which must be the form you want the system to evaluate. The system evaluates the form in the lexical environment of the form currently being stepped. Debugger Command DEBUG The DEBUG command invokes the debugger at the control stack frame that stores the call to the current form. When the debugger returns control to the stepper, the stepper prompts you for a command. 4-26 0 DEBUGGING FACILITIES Display Command The SHOW command displays the subform stack frame. in the current Exiting Command QUIT 0 The QUIT command causes the stepper to exit and return control to the command level that was active when the stepper was invoked. You can specify this command with an optional argument. If you specify NIL, the stepper displays a confirmation message before it causes the stepper to exit. If you respond to the message by typing YES, the stepper exits. If you specify a value other than NIL, the stepper does not display a message. The default value for the optional argument is NIL. Backtrace Command BACK TRACE 0 The BACKTRACE command lists the subforms of the form being stepped through. You can specify the command with an optional integer, which determines the number of subforms that are to be listed. The stepper works its way back the specified number of subforms and then lists the subforms in the order in which they were invoked. If you do not specify the argument, the stepper lists all the subforms the LISP system is evaluating. Commands That Continue Evaluation of the Form Being Stepped Through Several,stepper commands continue the evaluation of the form being stepped through, each command continuing the evaluation in a different way. 0 FINISH The FINISH command evaluates the form you specified in the call to the STEP macro. You can specify the command with an optional argument that is a form. When the stepper executes the command, the LISP system evaluates the form. If the evaluation returns a value other than NIL, the stepper steps through the evaluation of the form until it reaches the end of the evaluation. If the evaluation returns NIL, the LISP system disables the stepper and then evaluates the form you specified in the call to the STEP macro. The default value for the optional argument is NIL. 0 4-27 DEBUGGING FACILITIES OVER The OVER command causes the LISP system to evaluate the subform in the current stack frame with the steppero disabled.- RETURN The RETURN command causes the LISP system to evaluate the RETURN command's argument and causes the stepper to force the current stack frame to return tie values returned by the evaluation. This command must be specified with an argument that must be a form. When you execute the command, the LISP system evaluates the form. When the evaluation is complete, the current stack frame returns the values returned by the evaluated form. STEP The STEP command causes the LISP system to evaluate the subform in the current stack frame with the stepper enabled. This command is equivalent to pressing theo RETURN key. UP The UP command causes the LISP system to evaluate subforms with the stepper disabled until control returns to the subform that contains the subform in the current stack frame. You can specify the command with an optional integer argument (n). If you specify the argument, the system evaluates subforms with the stepper disabled until control returns to the subformo that contains the subform in the current stack frame n levels deep. The default value of the argument is 1. 4.6.5 Using Stepper Variables The stepper facility has debugging tools when *STEP-ENVIRONMENT*. two special variables in the stepper: that are useful *STEP-FORM* and 0 4.6.5.1 *STEP-FORM* - The *STEP-FORM* variable· is bound to the form being evaluated while stepping. For example, while executing the form (STEP (FUNCTION-Z ARG1 ARG2)) the value of *STEP-FORM* is the list (FUNCTION-Z ARG1 ARG2). stepping, the value is undefined. When not 4.6.5.2 *STEP-ENVIRONMENT* - The *STEP-ENVIRONMENT* variable is boun~ to the lexical environment in which *STEP-FORM* is being evaluated.o By default in the stepper, the lexical environment is used if you use 4-28 DEBUGGING FACILITIES 0 the EVALUATE command. See COMMON LISP: The Language for a description of dynamic and lexical environment variables. Some COMMON LISP functions (for example, EVALHOOK, APPLYHOOK, and MACROEXPAND) take an optional environment argument. The value bound to the *STEP-ENVIRONMENT* variable can be passed as an envi~onment to these functions to allow evaluaton of forms in the context of the stepped form. 4.6.5.3 Example Use of Stepper Variables - The following example illustrates the use of the *STEP-FORM* and *STEP-ENVIRONMENT* special variables. 0 0 Lisp> (SETF X "Top level value of X") "Top level value of X" Lisp> (DEFUN FUNCTION-X (X) (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) FUNCTION-X Lisp> (STEP (FUNCTION-X 5)) #4: (FUNCTION-X 5) Step> STEP : #10: (BLOCK FUNCTION-X (IF(< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Step> STEP : : #14: (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2)))) Step> STEP : #18: (< X 3) Step> STEP : #22: X => 5 #18 => NIL #17: (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X. 2))) Step> STEP : #21: (FUNCTION-X (- X 1)) Step> STEP : : : #2 5: ( - X 1) Step> STEP : #29: X => 5 #25 => 4 #27: (BLOCK FUNCTION-X (IF(< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Step> STEP #31: (IF (< X 3) 1 (+ (FUNCTION-X (- x 1)) (FUNCTION-X ( x 2)))) Step> STEP #35: (< x 3) . 0 . . .. . . .. . .. .. . .. . .. .. . . 0 - . . .. . . . . 4-29 DEBUGGING FACILITIES Step> STEP : #39: X => 4 #35 => NIL #34: (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))) Step> STEP · • • : # 3 8 : ( FUN CT I ON - X ( - X 1 ) ) Step> EVAL *STEP-FORM* (FUNCTION-X (- X 1)) Step> STEP #42: (- X 1) Step> STEP : #46: X => 4 #42 => 3 #44: (BLOCK FUNCTION-X (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Step> EVAL *STEP-FORM* (BLOCK FUNCTION-X (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Step> STEP : : : : : : : : : : #48: (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2)))) Step> STEP . . #52: (< X 3) Step> STEP : #56: X => 3 #52 => NIL #51: (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))) Step> STEP . . #55: (FUNCTION-X (- X 1)) Step> EVAL X . 0 0 .. 3 Step> (EVAL 'X) "Top level value of X" Step> EVAL *STEP-FORM* (FUNCTION-X (- X 1)) Step> (EVALHOOK 'X NIL NIL NIL) "Top level value of X" Step> (EVALHOOK 'X NIL NIL *STEP-ENVIRONMENT*) 3 Step> ( EVALHOOK ( CADR *STEP-FORM*) NIL NIL *STEP-.ENVIRONMENT*) 2 Step> STEP . . .. .. #59: (- X 1) Step> STEP : #63: X => 3 #59 => 2 #61: (BLOCK FUNCTION-X ( IF ( < X 3) 1 4-30 0 DEBUGGING FACILITIES 0 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Step> FINISH 5 This example shows that the *STEP-FORM* special variable is bound to the form being evaluated while stepping. The example also !hows that the *STEP-ENVIRONMENT* special variable is bound to the lexical environment in which the currently stepped form is being evaluated. The call to EVALHOOK evaluates the form (- X 1) in the lexical environment of the stepper, that is, with the local binding of x.. A call to EVALHOOK with a null environment specified shows that X's value in the null lexical environment differs from that in the stepper. The EVAL command uses the *STEP-ENVIRONMENT* environment; the EVAL function uses the null lexical environment. 0 4.6.6 Sample Stepper Sessions 1. Lisp> (DEFUN FIRST-ELEMENT (X) (CAR X)) FIRST-ELEMENT Lisp> (SETF MY-LIST '(FIRST SECOND THIRD)) (FIRST SECOND THIRD) Lisp> (STEP (FIRST-ELEMENT MY-LIST)) : #9: (FIRST-ELEMENT MY-LIST) Step> STEP : : #14: MY-LIST=> (FIRST SECOND THIRD) : : #15: (BLOCK FIRST-ELEMENT (CAR X)) Step> STEP : : : #22: (CAR X) Step> EVALUATE (CAR X) FIRST Step> FINISH FIRST Lisp> 2. Lisp> (DEFUN PLUS-Y (X) (+ X Y)) PLUS-Y Lisp> (SETF Y 5) 5 Lisp> (STEP (PLUS-Y 10)) : #9: ( PLUS-Y· 10) Step> STEP : : #15: (BLOCK PLUS-Y (+ X Y)) Step> EVALUATE Evaluate: (+ X Y) 15 Step> STEP : : : #22: (+ X Y) 0 0 0 4-31 ____________________________ /_ DEBUGGING FACILITIES Step> BACKTRACE (PLUS-Y 10) : (BLOCK PLUS-Y (+ X Y)) : : 0 (+ X Y) Step> SHOW (+ X Y) Step> OVER : : #22 => 15 : : #15 => 15 : #9 => 15 15 Lisp> 3. Lisp> (DEFUN ADDITION (X) (+ X Y)) ADDITION Lisp> (SETF Y 5) 5 Lisp> (STEP (ADDITION 4)) : #9: (ADDITION 4) Step> STEP : : #15: (BLOCK ADDITION(+ X Y)) Step> STEP : : : #22: (+ X Y) Step> BACKTRACE (ADDITION 4) : (BLOCK ADDITION(+ X Y)) : : (+ X Y) Step> EVALUATE Evaluate: (+ X Y) 0 0 9 Step> STEP : #27: X => 4 : #26: Y => 5 #22 => 9 #15 => 9 #9 => 9 0 9 Lisp> 4.7 TRACER The VAX LISP tracer is a macro you can use to ~nspect a program's evaluation. The tracer informs you when a function or macro is called during a program's evaluation by printing information about each call and return value to the stream bound to the *TRACE-OUTPUT* variable. To use the tracer, you must enable it for each function and macro you want traced. 0 4-32 DEBUGGING FACILITIES NOTE 0 You cannot trace special forms. 4.7.1 Enabling the Tracer You can enable the tracer for one or more functions and/or macros by specifying the function and macro names as arguments in a call to the TRACE macro. For example: Lisp> (TRACE FACTORIAL ADDITION COUNTER) (FACTORIAL ADDITION COUNTER) o The TRACE macro returns a list of the functions and macros that are to be traced. If you try to trace a function or macro that is already being traced, a warning message is displayed. To avoid this error, call the TRACE macro without an argument to produce a list of the functions and macros for which tracing is enabled. For example: Lisp> (TRACE) (FACTORIAL ADDITION COUNTER) QA description of the TRACE macro is provided in Chapter 8. 4.7.2 O Disabling the Tracer To disable the tracer for a function or macro, specify the name of the function or macro in a call to the UNTRACE macro. It returns a list of the functions and macros for which tracing has just been disabled. For example: Lisp> (UNTRACE FACTORIAL ADDITION COUNTER) (FACTORIAL ADDITION COUNTER) You can disable tracing for all the functions for which tracing is enabled by calling the UNTRACE macro without an argument. If you try to disable tracing for a function that is not being traced, a warning message is displayed. I The UNTRACE macro is described in COMMON LISP: The Language. 0 4-33 DEBUGGING FACILITIES Tracer Output 4. 7 .3 Once you enable the tracer for a function or macro, the tracer displays two types of information each time that function or macro is called during a program's evaluation: • A description of each call to the specified function'or macro • A description of each return value from the specified function or macro 0 The description of a call to a function or macro consists of a line of text that includes the following information: • The nested level of the call • The control stack frame number that indicates where is stored the call • The name and arguments of the function function or macro that is called with the associated The tracer indicates the nested level of a call with indentation. When the number of nested levels increases, the indentation increases. After making the appropriate indentation, the tracer displays the control stack frame number, the function name, and the arguments in the following format: 0 0 #n: (function-name arguments) The tracer also displays a line of text for the return value of ·each evaluation. The line of text the tracer displays for each value includes the following information: • The nested level of the return value • The control stack frame number that indicates where the return value is stored • The return value 0 The tracer indicates the nested level of. each return value with indentation. The indentation matches the indentation of the corresponding call. After making the indentation, the tracer displays the control stack frame number and the return value in the following format: #n => return-value 04-34 DEBUGGING FACILITIES c=Juppose you define a function named FACTORIAL. Lisp> (DEFUN FACTORIAL (N) (IF(<= N 1) 1 (* N (FACTORIAL (- N 1))))) FACTORIAL The following example illustrates the format of the output t~e tracer displays when the function FACTORIAL is called with the argument 3: Lisp> (FACTORIAL 3) #11: (FACTORIAL 3) . #27: (FACTORIAL 2) . . #43: (FACTORIAL 1) . . #43 => 1 • #27 => 2 #11 => 6 0 6 The FACTORIAL function is a recursive one and, in the case of the preceding example, has three levels of recursion. The tracer indicates the nested level of each call with indentation. Each level of indentation is indicated with a period followed by a space (. ). The tracer indicates the number of the stack frame in which a call is stored with an integer. The integer is preceded with a number sign and followed by a colon (#n:). Ohe nested level of each return value m~tches the indentation of the corresponding call. The tracer indicates the number of the control stack frame onto which the LISP system pushes the value with an integer. This integer matches the stack frame number of the corresponding call and is preceded with a number sign and followed by an arrow (#n =>) that points to the return value. Q. 7 .4 Tracer Options You can modify the output of the tracer by specifying options in the call to the TRACE macro. Each option consists of a keyword-value pair. The format in which to specify keyword-value pairs for the TRACE macro is: (TRACE (function-name keyword-1 value-1 keyword-2 value-2 ... )) You can also specify options for a list of functions and/or macros. The TRACE macro format in which to specify the same options for a list of functions and macros is: 0 (TRACE ((name-1 name-2 ••• ) keyword-1 value-1 keyword-2 value-2 ... ) ) 4-35 DEBUGGING FACILITIES NOTE Forms the system evaluates just before or just after a call to a function or macro for which tracing is enabled are evaluated in a null lexical environment. For information on lexical environments, see COMMPN LISP: The Language. 0 The keywords you can use to specify options are: e s :DEBUG-IF :PRE-DEBUG-IF :POST-DEBUG-IF :PRINT :PRE-PRINT :POST-PRINT !-- Invoke the debugger 1-- Add information to tracer output • :STEP-IF -- Invokes the stepper • :SUPPRESS-IF -- Removes information from tracer output • :DURING -- Determines when a function or macro is traced 4.7.4.1 Invoking the Debugger - You can cause the tracer to invoke the debuggei by specifying the :DEBUG-IF, :PRE-DEBUG-IF, or :POST-DEBUG-IF keyword. These keywords must be specified with a form. The LISP system evaluates the 'form before, after, or before and after each call to the function or macro being traced. If the form returns a value other than NIL, the tracer invokes the debugger after each evaluation. 0 0 0 4.7.4.2 Adding Information to Tracer Output - You can add information to tracer output by specifying the :PRINT, :PRE-PRINT, or :POST-PRINT keyword. You must specify these keywords with a list of forms. The LISP system evaluates the list of forms and the tracer displays the return values before, after, or before and .after each call to the function or macro being traced. The tracer displays the values one per line and indents them to match other tracer output. If the forms to be evaluated cause an error, the debugger is invoked. 4.7.4.3 Invoking the Stepper - You can cause the tracer to invoke the stepper by specifying the :STEP-IF keyword. You must specify this keyword with a form. The LISP system evaluates the form before ,each call to the function or macro being traced. If the form returns a value other than NIL, the tracer invokes t~e stepper. 4-36 ·o DEBUGGING FACILITIES 0 0 4.7.4.4 Removing Information from Tracer Output - You can remove information from tracer output by specifying the :SUPPRESS-IF keyword. You must specify this keyword with a form. The LISP system evaluates the form before each call to the function or macro being traced. If the form returns a value other than NIL, the tracer does not display the arguments and the return value of the function or macro being 0 traced. 4.7.4.5 Defining When a Function or Macro Is Traced - You can define when a function or macro, for which tracing is enabled, is to be traced by specifying the :DURING keyword. You must specify this keyword with a function or macro name or a list of function and/or macro names. The functions and macros for which the tracer is enabled are traced only when they are called (directly or indirectly) from within one of the functions or macros whose names are specified with the keyword. 4. 7.5 0 Tracer Variables You can use two special variables with the TRACE macro. These are helpful debugging tools: *TRACE-CALL* and *TRACE-VALUES*. With these variables and the preceding tracer options, you can control when to debug or step depending on the arguments to a function or the return values from a function. 4.7.5.1 *TRACE-CALL* - The *TRACE-CALL* variable is bound to the function or macro call being traced. The following example shows how to use the variable: 0 0 Lisp> (DEFUN FUNCTION-X (X) (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) FUNCTION-X Lisp> (TRACE (FUNCTION-X :PRE-DEBUG-IF(< (SECOND *TRACE-CALL*) 2) :SUPPRESS-IF T)) (FUNCTION-X) Lisp> (FUNCTION-X 5) Control Stack Debugger Frame #26: (DEBUG) Debug 1> DOWN Frame #21: (BLOCK FUNCTION-X (IF {< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) 4-37 DEBUGGING FACILITIES Debug 1> DOWN Frame #19: (FUNCTION-X 3) Debug 1> (CADR (DEBUG-CALL)) 3 Debug 1> CONTINUE Control Stack Debugger Frame #19: (DEBUG) Debug 1> CONTINUE 5 0 e In this example, FUNCTION-Xis first defined. e Then the TRACE macro is called for FUNCTION-X. TRACE is specified to invoke the debugger if the first argument to FUNCTION-X (the function call being traced) is less than 2. Since the PRE-DEBUG-IF option is specified, the debugger is invoked before the call to FUNCTION-X. As the :SUPPRESS-IF option has a value of T, calls to FUNCTION-X do not cause any trace output. @ 0 The DOWN command moves the pointer down the control stack. The DEBUG-CALL function returns a list representing the In this case, the CADR of current debug frame function call. the list is 3. This accesses the first argument to the function in the current stack frame. Finally the FUNCTION-X. CONTINUE command continues the evaluation of 4.7.5.2 *TRACE-VALUES* - The *TRACE-VALUES* variable is bound to the list of values returned by a traced function. Consequently, the variable can be used only with the :POST- options to the TRACE macro. Before being bound to the return values, the variable returns NIL. The following example shows how to use the variable: Lisp> (TRACE (FUNCTION-X :POST-DEBUG-IF (> (FIRST *TRACE-VALUES*) 2))) (FUNCTION-X) Lisp> (FUNCTION-X 5) #4: (FUNCTION-X 5) . #11: (FUNCTION-X 4) #18: (FUNCTION-X 3) . #25: (FUNCTION-X 2) #25=> 1 . • . #25: (FUNCTION-X 1) . #25=> 1 . • #18=> 2 • • #18: (FUNCTION-X 2) . . #18=> 1 4-38 0 Q 0 DEBUGGING FACILITIES 0 0 0 Control Stack Debugger Frame #12: (DEBUG) Debug 1> BACKTRACE -- Backtrace start -Frame #12: (DEBUG) Frame #7: (BLOCK FUNCTION-X (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Frame #5: (FUNCTION-X 5) Frame #1: (EVAL (FUNCTION-X 5)) -- Backtrace ends -Frame #12: (DEBUG) Debug 1> CONTINUE . #11=> 3 #11: (FUNCTION-X 3) . #18: (FUNCTION-X 2) . . #18=> 1 #18: (FUNCTION-X 1) . . #18=> 1 . #11=> 2 Control Stack Debugger Frame #5: (DEBUG) Debug 1> CONTINUE #4=> 5 TRACE is called for FUNCTION-X (the same function as in the previous example) to start th~ debugger if the value returned exceeds 2. The value returned exceeds 2 twice once when it returns 3 and at the end when it returns 5. 0 0 4-39 0 0 0 0 0 0 CHAPTER 5 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 0 0 0 Pretty printing clarifies the meanings of LISP objects- by modifying their printed representations. It inserts indentation and line breaks at appropriate places, making pretty-printed output easier to read than output produced with standard print functions. Pretty printing is an alternative to standard printing for all LISP objects, but is particularly useful for printing LISP code, complex data lists, and arrays.* When pretty printing is enabled, any output function that prints output can potentially perform pretty printing. The following example contrasts the standard and pretty-printed treatments of a COND structure: Lisp> (SETF T-QUESTION '(COND ((EQUAL TERMINAL 'VT240) START) (T (PRIN1 '(WHAT TERMINAL TYPE ARE YOU USING?))))) ( COND ( ( EQUAL TERMINAL ( QUOTE VT2 4 0) ) START) ( T (.PRIN1 (QUOTE (WHAT TERMINAL TYPE ARE YOU USING?))))) Lisp> (PPRINT T-QUESTION) (COND ((EQUAL TERMINAL 'VT240) START) (T (PRIN1 '(WHAT TERMINAL TYPE ARE YOU USING?)))) The first version (produced by the standard read-eval-print loop) breaks the line at an awkward place and provides no indentation. Only one line is being printed. The line is either wrapped or truncated, depending on the operating system (VMS or ULTRIX-32) and the setting of the terminal. The pretty-printed (PPRINT) version is more readable because it starts a new line at the beginning of a nested list, indenting the list to· line up with the structure nested to the equivalent level in the first line. * VAX LISP pretty printing and the extensions to FORMAT are based on a O program described in the paper PP: A Lisp Pretty Printing System, A.I. Memo No. 816, December, 1984. The paper and the program were written by Richard C. Waters, Ph.D., of the MIT Artificial Intelligence Laboratory. 5-1 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT This chapter describes four ways to print LISP objects: 5.1 0 • Section 5.1 tells how to pretty-print·objects. • Section 5.2 tells how to control the format of objects using print control variables. • Section 5.3 tells how to use the VAX that support pretty-printing. e Sections 5.4 through 5.9 tell how you can extend the VAX LISP print functions to handle specific structures and types of structures by defining new print functions. LISP pretty-printed • FORMAT directives PRETTY PRINTING WITH DEFAULTS Three print functions let you pretty-print print control variables: without .explicitly e PPRINT formats an object and prints it to a stream. • PPRINT-DEFINITION formats the function object of a symbol prints it to a stream. using 0 and formats the property list of a symbol and prints Q • PPRINT-PLIST it to a stream. Use PPRINT when you want to let the system decide how best to format an object. PPRINT prints whatever object is given as its argument. The COND structure at the beginning of this chapter is an example of the output format specified for lists starting with a particular symbol. You can use PPRINT-DEFINITION to print the definition of a function. Supply the function name as the argument, as follows: LISP O Lisp> (DEFUN BELONGS (THIS PILE) (COND ((NULL PILE) NIL) ((EQUAL THIS (CAR PILE)) PILE) (T (BELONGS THIS (CDR PILE))))) BELONGS Lisp> (PPRINT-DEFINITION 'BELONGS) (DEFUN BELONGS (THIS PILE) (COND ((NULL PILE) NIL) ((EQUAL THIS (CAR PILE)) PILE) (T (BELONGS THIS (CDR PILE))))) If the object to be printed is the property list PPRINT-PLIST, as shown in the following example: of a symbol, Lisp> (SETF (GET 'PLACES 'CITIES) '(AUGUSTA SACRAMENTO))· (AUGUSTA SACRAMENTO) 5-2 use 0 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (SETF (GET 'PLACES 'STATES) '(MAINE CALIFORNIA)) (MAINE CALIFORNIA) Lisp> (PPRINT-PLIST 'PLACES) (STATES (MAINE CALIFORNIA) CITIES (AUGUSTA SACRAMENTO)) 0 PPRINT-PLIST prints only indicator-value pairs for which the 1 indicator is accessible in the current package. PPRINT-PLIST emphasizes the relationships between the indicator-value pairs. 5.2 HOW TO PRETTY-PRINT USING CONTROL VARIABLES VAX LISP supports the global print control variables included in COMMON LISP. In addition, VAX LISP provides three variables that oaffect only pretty-printed output: ~ *PRINT-RIGHT-MARGIN* e *PRINT-MISER-WIDTH* e *PRINT-LINES* By changing the values of these variables, you pretty-printed output to suit a variety of situations. can adjust QYou can also specify values for these three variables in calls to the WRITE and WRITE-TO-STRING functions. These functions have been extended to accept the following keyword arguments: :RIGHT-MARGIN :MISER-WIDTH :LINES O rf you specify any of these arguments, the corresponding special variable is bound to the value you supply with the argument before any output is produced. 5.2.1 Explicitly Enabling Pretty Printing When the COMMON LISP variable *PRINT-PRETTY* is non-NIL, it enables Piretty printing. If you set *PRINT-PRETTY* to T, you can pretty print by calling any print function. The LISP read-eval-print loop will also pretty-print when *PRINT-PRETTY* is non-NIL. The following example shows the effect of a PRIN1 function pretty printing is enabled: 0 5-3 call when PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (SETF *PRINT-PRETTY* T) T Lisp> (PRINl '( (TIGER TIGER BURNING BRIGHT) (IN THE FORESTS OF THE NIGHT) (WHAT IMMORTAL HAND OR EYE) (COULD FRAME THY FEARFUL SYMMETRY) ) ) ((TIGER TIGER BURNING BRIGHT) (IN THE FORESTS OF THE NIGHT) (WHAT IMMORTAL HAND OR EYE) (COULD FRAME THY FEARFUL SYMMETRY)) 0 You can also enable pretty printing by specifying a non-NIL value for the :PRETTY keyword in functions such as WRITE and WRITE-TO-STRING. Limiting Output by Lines 5.2.2 Pretty printing lets you abbreviate output by controlling the numberO of lines printed. With the variable *PRINT-LINES* set to any integer value, the print function you use stops after printing the specified number of lines~ The output stream replaces omitted output with the characters" " Abbreviation by number of lines occurs only when pretty printing is enabled. See Section 5.7 for more details on abbreviating output. The following example shows pretty-printed output set to 2. with *PRINT-LINES*Q Lisp> (SETF *PRINT-LINES* 2) 2 Lisp> (SETF *PRINT-PRETTY* T) T Lisp> (PRINT '((IN WHAT DISTANT DEEPS OR SKIES) (BURNT THE FIRE OF THINE EYES) (ON WHAT WINGS DARE HE ASPIRE) (WHAT THE HAND DARE SEIZE THE FIRE))) ((IN WHAT DISTANT DEEPS OR SKIES) (BURNT THE FIRE OF THINE E ... 5.2.3 0 Controlling Margins The *PRINT-RIGHT-MARGIN* variable lets you adjust the width of pretty-printed output. The value should be an integer; it specifies the exclusive upper limit on column numbers. With the left margin at 0, *PRINT-RIGHT-MARGIN* specifies the number of columns in which you can print. The default value, NIL, causes the print functions to query the output stream for the right margin value. The default varies, but is always appropriate to the output device. Output may exceed the right margin if the printer. encounters a long Q symbol name or string. The left margin is normally 0, but you can 5-4 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 0 change it by using logical blocks with the FORMAT function (see Section 5.3). 5.2.4 to indent Conserving Space with Miser Mode Miser mode can help you avoid running out of horizontal space when you print complicated structures. Pretty printing adds line breaks and indentation to output to indicate levels of nesting, so that deeply nested structures often use up much of the line width. Miser mode conserves line width by minimizing indentation and inserting new lines where possible. You can use this feature by setting the variable *PRINT-MISER-WIDTH* to an integer value two or three times the length of the longest symbol in the output (usually a value between 20 and 40 is appropriate). 0 O The system subtracts the value of *PRINT-MISER-WIDTH* from the right margin of the output stream to determine the column at which miser mode takes effect. In other words, miser mode becomes effective when the total line width available for printing after indentation is less than the value of *PRINT-MISER-WIDTH*. You can set *PRINT-MISER-WIDTH* to NIL to disable miser mode. See Section 5.8 for more details. The default value of *PRINT-MISER-WIDTH* is 40. 5.3 EXTENSIONS TO THE FORMAT FUNCTION VAX LISP provides eight specified in COMMON LISP. 0 FORMAT directives in addition to those The added directives allow you to specify: • Logical blocks, which are groupings of related output tokens • Multiline mode new lines, which result in new lines cannot fit on one line • Indentation, which aids in indenting portions of a form if output Table 5-1 lists and briefly describes the FORMAT directives that VAX LISP provides. This section provides a guide to their use. The section presupposes a ·thorough knowledge of the LISP 'FORMAT function. ~ee COMMON LISP: The Language for a full description of FORMAT. Use the FORMAT function as follows: FORMAT destination control-string &REST arguments O This function formats the arguments according to the format you specify with directives in the control string. destination .specifies 5-5 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT the output stream. The arguments identify the objects to be operated on by the control string. The sections that follow describe the application of these directives and the effects of the col0n and at-sign modifiers on them. Table 5-1: Q Format Directives Provided by VAX LISP Directive Effect Prints the corresponding argument under the current print variable values. direction of Begins a logical block. Depending on modifiers, this directive causes FORMAT to print one or more of the arguments following the control string. 0 Ends a logical block. Specifies a multiline mode new line. effective only in a logical block. This directive is Sets indentation ton columns after the logical block or after the prefix. This directive is effective only in a logical block. -n/FILL/ Prints the elements of a list with as many elements as possible on each line. If n is 1, FORMAT encloses the printed list in parentheses. This directive is effective only in a logical block. -n/LINEAR/ If the elements of the list, to be printed cannot be printed on a single line, this directive prints each element on a separate line. If n is 1, FORMAT encloses the printed list in parentheses. This directive is effective only in a logical block. -n,m/TABULAR/ Q Q Prints the list in tabular form. If n is 1, FORMAT encloses the list in parentheses; m specifies the column spacing. This directive is effective only in a logical block. These FORMAT directives provide the sole means of. performing pretty printing in VAX LISP. All functions that explicitly perform pretty printing (for example, PPRINT and PPRINT-DEFINITION) do so by using these directives. Objects printed with FORMAT are printed normally unless pretty printing is enabled. Pretty printing is enabled when both the following conditions exist: 0 5-6 PRETTY .PRINTING AND USING EXTENSIONS TO FORMAT CJ 1. A logical block is started. 2. *PRINT-PRETTY* is non-NIL, or the colon modifier is specified in the logical block directive (-:!). Nothing prevents you from starting a logical block when *PRINT-PRETTY* is NIL. However, any conditional new lines or indentation'specified within the logical block will be ignored. This feature results in normal-looking output, ·as opposed to pretty-printed output. By allowing this flexibility, FORMAT lets you use one control string to format data, and the data is either printed normally or pretty-printed, according to the value of *PRINT-PRETTY*. 5.3.1 Using the WRITE FORMAT Directive Q u·se the -w FORMAT di rec ti ve to print an element when you want to use the current values of the print control variables. The argument for 0 -w can.be any LISP object. In contrast, -A and -s specify the of print control variables. values You can use up to four prefix parameters with -w to object: printed pad the -mincol,colinc,minpad,padcharw For an explanation of these parameters, see the description under "FORMAT Directives Provided with VAX LISP" in Part II of this manual. The colon modifier (-:W) binds the following print control variables for the duration of the WRITE: *PRINT-ESCAPE* to T, *PRINT-PRETTY* to T, *PRINT-LENGTH* to NIL, *PRINT-LEVEL* to NIL, and *PRINT-LINES* to NIL. The following example contrasts the effects of using-wand -:w. 0 Lisp> (SETF *PRINT-PRETTY* NIL) NIL Lisp> (SETF *PRINT-ESCAPE* NIL) NIL Lisp> (SETF *PRINT-LENGTH* 2) 2 Lisp> (SETF COLORS ' ( ( "Yellow" "Purple" "Orange" "Green") ("Aqua" "Pink" "Beige" "Buff") ("Peach" "Violet" "Chartreuse"))) 0 Lisp> (FORMAT T "-W" COLORS) ((Yellow Purple ... ) (Aqua Pink ... ) •.. ) NIL Lisp> (FORMAT T .. -:w" COLORS) (("Yellow" "Purple" "Orange" "Green") ("Aqua" "Pink" "Beige" "Buff") ("Peach" "Violet" "Chartreuse")) 5-7 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT The first FORMAT call truncates the first two sublists to two colors and truncates the outer list to two sublists. This truncation occursQ because *PRINT-LENGTH* is 2. The first FORMAT call omits quotation ~ marks because *PRINT-ESCAPE* is NIL. The second FORMAT call produces the full list of colors and includes quotation marks, because it implicitly sets *PRINT-LENGTH* to NIL and *PRINT-ESCAPE* to T. The second FORMAT call also indents the lists because it implic\tly sets *PRINT-PRETTY* to T. 5.3.2 Controlling the Arrangement of Output Two concepts support the dynamic arrangement of output for pretty printing: logical blocks and conditional new lines. Logical block directives divide the total output into hierarchical groupings, which are referred to as logical blocks or subblocks. The goal of FORMAT is to print an entire logical block (including all its subblocks) on one line. If pretty printing is enabled, the logical block is printed on one line only if the logical block fits between the current left and right margins. Printing all the output on one line is referred to as single-line mode printing. o The output for a logical block may not fit on one line when pretty printing. In this case, the block must be subdivided into sections at points where it may be split into multiple - lines. Conditional new Q line directives specify these points. Multiline mode printing is the name given to the condition where a logical block must occupy multiple lines. When pretty printing is enabled, FORMAT buffers the contents of a logical block until it can decide whether to use single-line mode or multiline mode printing. A third mode, miser mode, is described briefly in Section 5.2.4 and in Q detail in Section 5.8. Use the-! and - directives to specify a logical block in the form: - - !block-. where block can include any FORMAT directives. A logical block takes one argument from the FORMAT argument list. If that argument is a list, any directives within the logical block that take arguments take them from that list, as shown in the following example: Lisp> (SETF *PRINT-RIGHT-MARGIN* 40) 40 Lisp> (SETF *PRINT-PRETTY* T) T 0 5-8 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (FORMAT T n-1-w- ." '((STARS (BETELGEUSE DENEB SIRIUS)) (PLANETS (MERCURY VENUS EARTH MARS JUPITER SATURN NEPTUNE PLUTO)))) (STARS (BETELGEUSE DENEB SIRIUS)) (PLANETS (MERCURY VENUS EARTH MARS JUPITER SATURN URANUS NEPTUNE PLUTO)) 0 The logical block takes the entire list as its argument. The -w directive within the logical block causes FORMAT to pretty-print the list because *PRINT-PRETTY* is set to T. If the argument is not a list, replaced by the -w directive. O the logical block is effectively You can alter the directive to start a logical block (-!) by adding two modifiers. When the directive includes a colon (-:!), the directive sets *PRINT-PRETTY* and *PRINT-ESCAPE* to T and *PRINT-LENGTH*, *PRINT-LEVEL*, and *PRINT-LINES* to NIL for all the printing controlled by the logical block. When the-! directive includes an at-sign (-@!), the directives within the logical block take successive arguments from the FORMAT argument list. The logical block uses up all the arguments, not just a single list argument. Therefore, no directives that take arguments from the argument list can appear after a logical block modified by an at-sign in the logical block directive (see the last example in this section). You can use the -- directive· inside a logical block to check whether the logical block arguments have been reduced to a non-NIL atom. See Section 5.9 for information on handling improperly formed argument lists. O The output associated with any FORMAT directive is subject printing when the directive occurs within a logical Q*PRINT-PRETTY* is non-NIL. to pretty block and A logical block defines an indentation level and can define a prefix and a suffix. By default, when pretty printing is enabled, the indentation level is the position of the first character in the logical block. Each line following the first line in the logical block is printed preserving indentation and per-line prefixes, so that the first character in the line normally lines up with the first character in the block following the prefix. However, no default prefix or suffix is associated with a logical block. You can create nested logical blocks within a logical block, using the -!block-. directive. For example: 0 5-9 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (SETF *PRINT-RIGHT-MARGIN* 70) 70 Lisp> (SETF *PRINT-PRETTY* T) T Lisp> (FORMAT T "-!Stars: -!-s -s-. Planets: -!-s -s-.-." '((BETELGEUSE DENEB) (MARS JUPITER))) Stars: BETELGEUSE DENEB Planets: MARS JUPITER • In this example, two logical blocks are created within the principal logical block. Each logical block uses the next argument for printing: • The enclosing logical block uses the elements of the principal list ((BETELGEUSE DENEB) (MARS JUPITER)) as its arguments. • The first inner logical block uses the elements (BETELGEUSE DENEB) as its arguments. of the list • The second inner logical block uses the elements of (MARS JUPITER) as its arguments. the list 0 Lisp> (FORMAT T .. - : !Stars: - !-s -s-. Planets: - !-s -s- .- . " '((BETELGEUSE DENEB) (MARS JUPITER))) Stars: BETELGEUSE DENEB Planets: MARS JUPITER In this example, the colon in the - : ! directive enables pretty printing implicitly, producing the same output as the previous example. 0 Lisp> (SETF *PRINT-PRETTY* T) T Lisp> (FORMAT T .. -@!-S -%-s -%-s -%-s-." '(BETELGEUSE DENEB SIRIUS) 'POLARIS 'VEGA 'ALGOL 'ALDEBERAN) (BETELGEUSE DENEB SIRIUS) POLARIS VEGA ALGOL 0 In this example, the at-sign causes the logical block to use all following arguments. Unneeded arguments are used up by the logical block but not printed. The first -s applies to the first argument (the list (BETELGEUSE DENEB SIRIUS)). The rema1n1ng three -s directives apply to POLARIS, VEGA, and ALGOL. ALDEBERAN goes unprinted, because there is no corresponding directive. Lisp> (FORMAT T "-@!Stars: - !-s -s-. Planets: - !-s -s- .- • ". '(BETELGEUSE DENEB) '(MARS JUPiTER)) Stars: BETELGEUSE DENEB Planets: MARS JUPITER In this example the at-sign in the outermost logical block (-@!) directs the logical block to use all the arguments. 5-10 directive. The first Q PRETTY PRINTING AND USING EXTENSIONS TO FORMAT inner logical block uses the elements of the list (BETELGEUSE DENEB); :he second inner logical block uses the elements of the list (MARS JUPITER) . O 5.3.3 Controlling Where New Lines Begin Five FORMAT directives let you specify start according to the demands of delimits a section in a logical block. s places where new lines can the situation. Each directive The-% directive produces an unconditional new line. When used within a logical block, the directive preserves indentation and per-line prefixes. -& directive produces a fresh line. When used within a • The logical block, the directive preserves indentation and 0 per-line.prefixes. @ - The directive produces a multiline mode new line when within a logical block. used The - : - directive produces an if-needed new line when used • within a logical block. 0 .....: . The -@_ directive produces a miser-mode new line when used • within a logical block. You can specify unconditional new lines (-%) and fresh lines (-&) if you know in advance how the text should be laid out. If a new line is produced by one of these directives when the FORMAT function is printing a logical block, FORMAT prints the logical block in the multiline mode, preserving indentation and per-line prefixes. ~rhe -& directive specifies a fresh line, whether or not pretty printing is enabled. If the -& directive occurs inside a logical block when pretty printing is enabled and any output is on the line other than prefixes and indentation, the FORMAT call starts a fresh line, preserving indentation and per-line prefixes. The following examples show the use of the-% and -& directives: 0 5-11 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (FORMAT T "Stars-:!;-@;_%_S -%-s _%_S_ ." '(BETELGEUSE DENEB SIRIUS)) Stars; BETELGEUSE DENEB SIRIUS NIL Lisp> (FORMAT T "Stars-:!;-@;_&_S -&-s -&-s-." '(BETELGEUSE DENEB SIRIUS)) Stars; BETELGEUSE DENEB SIRIUS 0 The first FORMAT call starts a new line after the prefix";", because the -% directive starts a new line wherever.the directive occurs. Replacing the-% directive with the -& directive changes the output, because the fresh line is not needed after the prefix. The remaining three new line directives offer flexibility because they However, they have no effect on output (except are conditional. length abbreviation -- see Section 5.7.1) when pretty printing is not enabled. 1- The - directive (multiline mode new line) starts a new line if the output for the enclosing logical block is too long to fit on one line or if any other directive in the logical block causes a new line. When the output is too long, FORMAT uses multiline mode, and every -directive in a logical block starts a new line. The directive (if-needed new line) produces a new line if it is needed: if the following section of output is too long to fit on the current line. The -@_ directive (miser-mode ·new line) produces a new line if pretty printing is enab°Ied with miser mode in effect (see Section 5.8 for details). The FORMAT function ignores the three conditional new line directives when they occur outside a logical block. The following example shows how you can specify a multiline line and an if-needed new line: mode new 0 Q Q Lisp> (SETF *PRINT-RIGHT-MARGIN* 16) 16 Lisp> ( FORMAT T n- : !- s - _- s - : _- s - - - s- . '(BETELGEUSE .ALDEBERAN MERCURY JUPITER)) BETELGEUSE ALDEBERAN MERCURY JUPITER II This FORMAT function produces output in the multiline mode, because the output will not fit on one line. The multiline mode new line directives(-_) produce a new line for each element. The directive directs FORMAT to start a new line befo.re MERCURY if needed (and a new line is needed). 5-12 Q PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 0 You can produce printed output that fills up the space available in each line by using the at-sign (@) modifier with the directive that ends the logical block (- !block-@.). This modifier causes FORMAT to start a new line if needed following every blank space or tab and is equivalent to inserting directive after each element to be printed, as shown in the following example: a-=- Lisp> (SETF *PRINT-RIGHT-MARGIN* 25) 25 Lisp> (FORMAT T "-@:!ANTARES ALPHECCA ALBIREO CANOPUS CASTOR POLLUX MIRZAM ALGOL BELLATRIX CAPELLA MIRA MIRFAK DUBHE POLARIS-@." ) ANTARES ALPHECCA ALBIREO CANOPUS CASTOR POLLUX MIRZAM ALGOL BELLATRIX CAPELLA MIRA MIRFAK DUBHE POLARIS 0 5.3.4 O O Controlling Indentation With pretty printing enabled, a call to FORMAT indents the output for a logical block so that the first character in each succeeding line falls under the first character following the prefix in the first line. When pretty printing is not enabled, the FORMAT call does not produce indentation, and the indentation directive has no effect. Use the -nI directive or the -n:I directive if you want to change the standard pretty-printed indentation. The -nI directive causes FORMAT to indent subsequent lines n spaces from the position of the first character in the logical block. The -n:I directive, on the other hand, causes FORMAT to indent subsequent lines n spaces from the output column corresponding to the position of the directive. If you omit the parameter n, the default is 0. Although this parameter can be less than O when used with the colon, the indentation cannot move to the left of the first character in the logical block. An indentation directive affects only indentation produced on subsequent new lines. · The following example shows directive: 0 several variations of the Lisp> (SETF *PRINT-RIGHT-MARGIN* 15) 15 Lisp> (FORMAT T .. - : 1-s -2r :_-s - :rs - _-s -1r_-s-." '(BETELGEUSE DENEB SIRIUS VEGA ALDEBERAN)) BETELGEUSE DENEB SIRIUS VEGA ALDEBERAN 5-13 indentation PRETTY PRINTING AND USING EXTENSIONS TO FORMAT DENEB lines up under the Tin BETELGEUSE, because the directive produces a new line and -21 causes an indentation of 2 spaces past the beginning of the block . . The -:I directive for the third argument. sets the indentation to the column of the firsts in SIRIUS, so that the v of VEGA lines up with the S. ALDEBERAN lines up with the first. E in BETELGEUSE, because the -11 directive resets the indentation to one column past the first character in the logical block. • Q The -1 directives only set the indentation. They do not· start new lines and they do not take effect until new lines begin. Therefore, in the directives for DENEB and·ALDEBERAN, the indentation directives precede the new line directives. 5.3.5 Producing Prefixes and Suffixes You can specify FORMAT control strings that add prefixes and suffixes to the printed output produced for a logical block. Several options are available. If you divide the format control string intd three sections by inserting the-; directive twice, the-string will specify a prefix and a suffix, as follows: -!prefix-;body-;suffix- .. The first ; directive marks the end of the prefix; the second marks the beginning of the suffix. If you omit the second -; directive, no suffix is specified. Although the body can be any FORMAT control string, the prefix and suffix cannot include FORMAT directives. When a FORMAT call prints output for a logical block that includes a prefix and pretty printing is' enabled, the second line of the output is indented so that the second line lines up with the firs~ character in the block following the prefix. When the logical block includes a suffix, the FORMAT call always prints the suffix at the end, even if abbreviation directives.eliminate some of the body of the block. In the following examples, "Stars<" forms the prefix, and the suffix. Lisp> (FORMAT T "-!Stars C;-s -%-S -_-s-;>-." '(SIRIUS VEGA DENEB)) Stars <SIRIUS VEGA DENEB> NIL Lisp> (SETF *PRINT-LENGTH* 2) 2 Lisp> (FORMAT T .. - !Stars <- ;-s -%-s -_-s- ;>-." '(SIRIUS VEGA DENEB)) Stars <SIRIUS VEGA ••• > 5-14 ">" forms 0 0 0 0 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT In the second example, FORMAT truncates the list to two elements, ecause *PRINT-LENGTH* is set to 2 (see Section 5.7), but it still dds the suffix after the last list element. VEGA lines up under SIRIUS in the first column for the body of the logical block. Cl You can specify the prefix parameter 1 in the logical block t directive (-l!block- .), causing the FORMAT call to use parentheses for the prefix and suffix, as shown: Lisp> (FORMAT T .. -1:!-S -%-s-." '(CASTOR POLLUX)) (CASTOR POLLUX) You can create per-line prefixes in a logical block by specifying the at-sign modifier in the-; directive used to indicate the end of the refix (-@;). This modifier causes FORMAT to repeat the prefix at the eginning of each line, as shown in the following example: O Lisp> (FORMAT T .. -:!<<-@;-$ -%-s -_-s - _-s-;>>- ." '(ALGOL ANTARES ALBIREO ALPHECCA)) <<ALGOL <<ANTARES <<ALBIREO <<ALPHECCA>> Q'he prefixes and the list elements line up. If you nest logical blocks, you can specify a prefix with each block, as shown: Lisp> (FORMAT T n-: !Bright stars-; -@!<<-@;-$ -s .-%-s - - s-; >>-. - ; still twinkle.-." '(SIRIUS VEGA DENEB ALGOL)) Bright stars <<SIRIUS VEGA <<DENEB ALGOL>> still twinkle. 0 The prefix and suffix for the outer logical block are "Bright stars" 'and "still twinkle". The prefix for the inner logical block, "<<", is printed on each line after the indentation required by the prefix for the first logical block. The suffix for the inner logical block, ">>", is printed once at the end of the block. 5.3.6 Using Tabs You can use the tab directive to arrange output in columns. When pretty printing is enabled, the -n,rnT tab directive counts spaces, ~eginning with the indentation of the immediately enclosing logical block. The integer n specifies a number of columns. The .integer rn C 5-15 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT specifies an increment: the number of columns to be added at one time~ until the column width is at least n columns. The at-sign modifiei: ) makes the tab directive relative, so that -n,m@T counts space~ beginning with the current output column. When pretty printing is not en~bled, on the other hand, the -n,mT directive counts spaces from the beginning of the line, as specified in COMMON LISP. The defaults for n and mare 1 (see COMMON LISP: The Language for details). t In the iterative example that follows, the tab directive precedes if-needed new line directive: Lisp> (SETF *PRINT-RIGHT-MARGIN* 29) 29 Lisp> (FORMAT T "Stars: -:@!_{_s_A -11T-s -A-=--}-." '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES)) ' Stars: POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES the 0 Since the tabs are counted from the indentatioh of the logical block,o the tab directives do net have to account for the fact that the whole block is shifted seven columns to the right. 5.3.7 Directives for Handling Lists VAX LISP provides three FORMAT directives that simplify the printing of lists. Each implicitly uses the -w directive repeatedly to printo elements. • If pretty printing is enabled, the -n/FILL/ directive causes FORMAT to fill the available line width by inserting a space and an if-needed new line after each list element except the last. FORMAT encloses the list in parentheses if n is 1. If pretty printing is not enabled, -n/FILL/ causes FORMAT to print the output in .single-line mode. • If pretty printing is enabled, the -n/LINEAR/ directive causes FORMAT to print the list on a single line if the list fits. Otherwise, FORMAT prints each element on a separate line. FORMAT encloses the list in parentheses if n is 1. If pretty printing is not enabled, -n/LINEAR/ causes FORMAT to print the . output in single-line mode. . 0 5-16 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 0 If pretty printing is enabled, the -n,m/TABULAR/ directive • causes FORMAT to print the list as a table, using columns of m spaces for list elements. The default value for m is 16. FORMAT encloses the list in parentheses if n is 1. If pretty printing is not enabled, -n,m/TABULAR causes FORMAT to print the output in single-line mode. The following examples show the kinds of formats you can produce the list-handling directives: 0 0 0 0 Lisp> (SETF *PRINT-RIGHT-MARGIN* 36) 36 Lisp> (FORMAT T "Stars: -@:!-/FILL,1." '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES)) Stars: POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES NIL Lisp> (SETF *PRINT-RIGHT-MARGIN* NIL) NIL Lisp> ( FORMAT T "Stars: - @: !- /LINEAR.1." '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES}) Stars: POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES NIL Lisp> (FORMAT T "Stars: -@: !-0,20/TABULAR.1 ." '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES)) Stars: POLARIS DUBHE MIRA BELLATRIX MIRFAK CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES 5-17 with PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 5.4 OEFINING YOUR OWN FORMAT DIRECTIVES VAX LISP lets you define· your own FORMAT directives to supplement the directives supplied with the system. Any FORMAT directive that you define you can use in the control string argument to a FORMAT call. 0 DEFINE-FORMAT-DIRECTIVE name (arg stream colon at-sign &OPTIONAL (parameter! default) (parameter2 default) &BODY forms ... ) This macro defines a directive named name. After you define a FORMAT directive, you can use it (whether or not pretty printing is enabled) by including -;name/ in a FORMAT control string. 0 NOTE If you do not specify a package with name when you define the directive, name is placed in the current package. If you do not specify a package when you refer to the directive, the FORMAT directive looks in the USER package for the directive definition. For the body of the macro call, the symbols you stream, colon, and at-sign are bound as follows: supply arg, for • arg is bound to the argument list for the FORMAT directive you define. e stream is bound to the stream on which the printing is done. to be • The colon and at-sign arguments are bound to NIL unless colon and at-sign modifiers are used with the directive. the 0 0 There must be one optional argument for each prefix parameter that is allowed in the directive. A parameter argument will receive the corresponding prefix parameter if it was spe-cified in the directive. Otherwise, the default value will be used, as with all optional arguments. The body is evaluated to print the argument argon the output stream. A user-defined FORMAT directive can be useful because it provides a In addition, you can call .the directive level of indirection. repeatedly, which may save you some time coding and debugging. The following example shows a format directive used to produce error messages: 5-18 0 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (DEFINE-FORMAT-DIRECTIVE EVALUATION-ERROR (SYMBOL STREAM COLON-P ATSIGN-P &OPTIONAL (SEVERITY 0)) (DECLARE (IGNORE ATSIGN-P)) (FRESH-LINE STREAM) (PRINC (CASE SEVERITY (0 "Warning: ") (1 "Error: ") (2 "Severe Error: ")) STREAM) (FORMAT STREAM "-:!The symbol -s -:_does not have an integer value.-%Its value is: -=_-s-." SYMBOL (SYMBOL-VALUE SYMBOL')) (WHEN COLON-P (WRITE-CHAR #\BELL STREAM))) EVALUATION-ERROR Lisp> (SETF PROCESS NIL) NIL Lisp> (FORMAT T "-1:/EVALUATION-ERROR/" 'PROCESS) Error: The symbol PROCESS does not have an integer value. Its value is: NIL <BEEP> 0 0 O This example shows the definition of a FORMAT directive, an application of the directive, and the printed output. It assumes that the current package is USER. The prefix parameter 1 in "~:/EVALUATION-ERROR/" indicates th~ severity of the error being signaled. The colon in the FORMAT call produces a beep on the terminal. 5.5 DEFINING PRINT FUNCTIONS FOR LISTS O You can use DEFINE-LIST-~RINT-FUNCTION to define functions to print specific kinds of lists in formats of your choice. Functions that you define are effective only if pretty printing is enabled. The printer checks the first element of each list that it prints. If the first· element of a list matches the name of a list-print function, the list is printed according to the format you have specified. Create a list-print function according to the following format: DEFINE-LIST-PRINT-FUNCTION symbol (list stream) &BODY forms I This macro defines or redefines a print function for lists for which the first element is symbol. list is bound to the list to be printed and stream is bound to the stream on which the printing is to be done. The forms are evaluated to output list. QFor example, if you MY-SETQ, any list define a beginning list-print function for the symbol with MY-SETQ will be printed in your 5-19 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT format when pretty-printing is enabled: 0 Lisp> ( DEFINE-LIST-.PRINT-FUNCTION MY-SETQ ( LIST STREAM) (FORMAT STREAM LIST)) MY-SETQ Lisp> (SETF BASE '(MY-SETQ HI 3 BYE 4)) (MY-SETQ HI 3 BYE 4) Lisp> (PRINT BASE) (MY-SETQ HI 3 BYE 4) (MY-SETQ HI 3 BYE 4) Lisp> (PRRINT BASE) (MY-SETQ HI 3 BYE 4) When pretty printing is not enabled, the value of BASE is printedo without regard to the list-print function defined for MY-SETQ. PPRINT enables pretty printing, producing a representation of the value of BASE using the specified list-print function. VAX LISP pretty printing incorporates predefined list-print functions for many standard LISP functions. However, if you define a list-print function for a LISP keyword, your function will override the one built into the system. 0 NOTE. When you use DEFINE-LIST-PRINT-FUNCTION, you may encounter two kinds of ·output that you do not expect: • • In most cases, a list whose first element is the symbol for a defined list-print function will be printed in the format specified, even if the context and meaning of the list are irregular and the format is inappropriate. For example, if your data says (LET IT BE) and LET is the symbol of a defined list-print function, the resulting output may be inappropriate. 0 List-print functions are not used when you print a list under control of a user-defined FORMAT directive. You can disable any defined list-print function UNDEFINE-LIST-PRINT-FUNCTION macro. Its format is: by using the UNDEFINE-LIST-PRINT-FUNCTION symbol 0 5-20 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 0 This macro disables the list-print function defined for symbol. The following example disables the LET list-print function defined in the example at the beginning of this section: Lisp> (UNDEFINE-LIST-PRINT-FUNCTION MY-SETQ) MY-SETQ 5.6 0 DEFINING GENERALIZED PRINT FUNCTIONS Using generalized print functions, you can specify how any object is pretty-printed, regardless of its form. Functions that you define and enable are effective only if pretty ·printing is enabled. First you define a function with DEFINE-GENERALIZED-PRINT-FUNCTION. Then you enable the function. You can enable it globally, using GENERALIZED-PRINT-FUNCTION-ENABLED-P. Or you can enable it locally, using WITH-GENERALIZED-PRINT-FUNCTION. Use the following format when you define a generalized print function: DEFINE-GENERALIZED-PRINT-FUNCTION name (object stream) predicate &BODY forms 0 0 This macro defines or redefines a print function with the name name. object is bound to the object to be printed. stream is bound to the stream to which output is to be· sent. predicate governs the application of the generalized print function. The predicate is operative on any LISP object. A generalized print function will be used if it is enabled and the predicate evaluates to true on the object to be printed. (NULL OBJECT) is the predicate in the sample generalized print function shown at the end of this section. The output stream can use your generalized print function to print any object for which the predicate does not evaluate to NIL. forms identifies arguments to be evaluated in the call to FORMAT. If a generalized print function and a list-print function for the same symbol are both enabled, the generalized print function will be used. A related function lets you test whether a specific generalized function is enabled: print GENERALIZED-PRINT-FUNCTION-ENABLED-P name You can also use this function to globally change the function, using SETF as shown: 0 5-21 status of the PRETTY PRINTING AND USING EXTENSIONS TO FORMAT ( SETF ( GENERALIZED-PRINT-FUNCTION--ENABLED-P name) T) 0 or (SETF (GENERALIZED-PRINT-FUNCTION-ENABLED-P name) NIL) Use the WITH-GENERALIZED-PRINT-FUNCTION macro to locally 'enable generalized print function in the following format: a WITH-GENERALIZED-PRINT-FUNCTION name &BODY forms This macro locally enables the generalized print function when it evaluates the specified forms. named name The printer checks generalized print functions that have been enabled in reverse order from the order of their enabling. This means that in cases where two or more generalized print functions apply, the most recently enabled function is used. Enabling a generalized print function globally is less efficient than enabling it · locally, because the printer must check the predicate of globally enabled print functions against every object to be printed. If you enable the generalized print function locally, the printer checks the function's predicate against the object being printed only during execution of the code within the macro, instead of on every call to a print function. Since the read-eval-print loop is used often, the difference in efficiency can be significant. Q Q Consider the following examples: Lisp> (SETF *PRINT-RIGHT-MARGIN* 25) 25 Lisp> (GENERALIZED-PRINT-FUNCTION-ENABLED-P 'PRINT-NIL-AS-LIST) NIL Lisp> (DEFINE-GENERALIZED-PRINT-FUNCTION PRINT-NIL-AS-LIST (OBJECT STREAM) (NULL OBJECT) (PRINC II ( ) II STREAM)) PRINT-NIL-AS-LIST Lisp> (PRINT NIL) . NIL NIL Lisp>(PPRINT NIL) NIL Lisp> (WITH-GENERALIZED-PRINT-FUNCTION 'PRINT-NIL-AS-LIST (PRINT NIL) (PPRINT NIL)) NIL ( 0 ) 0 5-22 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT Lisp> (SETF (GENERALIZED-PRINT-FUNCTION-ENABLED-P 'PRINT-NIL-AS-LIST) T) 0 T LISP> (PPRINT NIL) ( ) The first PRINT call prints NIL, because pretty printing is not enabled. The first PPRINT call prints NIL, because the generalized print function PRINT-NIL-AS-LIST is not enabled. The second PRINT call prints NIL, because pretty printing is again not enabled. The second PPRINT call prints ( ), because the generalized print function is enabled locally and pretty printing is enabled. The third PPRINT call prints ( ), because the generalized print function is enabled globally and pretty printing is enabled. NOTE 0 A generalized print function controls the printing an object only if the following conditions exist: 0 of 1. The generalized print function is enabled globally or locally. 2. The predicate specified PRINT-FUNCTION is true. 3. The object to be printed does not come control of a user-defined FORMAT directive. with DEFINE-GENERALIZEDunder In cases where two or more generalized print functions are applicable, only one is chosen. The one.chosen is the most recently enabled (globally or locally) generalized print function for which the predicate specified with DEFINE-GENERALIZED-PRINT-FUNCTION is true. 0 Generalized print functions are not used when you print an object under control of a user-defined FORMAT directive. 5.7 ABBREVIATING PRINTED OUTPUT You can abbreviate printed output according to: 0 • The length of the object to be printed • The depth of nested logical blocks e The number of lines in the output 5-23 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT ,n Length and depth abbreviatio~ are S~?ported in COMMON LISP and are effective whether er not pretty p1inting ls enabled. In addition abbreviation based un the numb1::r of lines of output is supported in"-....../ VAX LISP; this is effective only when pretty printing is enabled. 5.7.1 Abbreviating Output Length You can control the number of sections of printed output by setting the *PRINT-LENGTH* variable. The value you supply specifies the number of sections to be printed for any affected logical block. The directives _, -%, and -& mark the sections of a logical block (see Section 5.3.3 for details). After the output stream prints *PRINT-LENGTH* sections of a logical block, it prints an ellipsis ( ... ) and stops processing the logical block. If the logical block is nested with other logical blocks, the output stream terminates onlyo the processing of the immediately enclosing logical block. Output is not truncated if the value of *PRINT-LENGTH* is NIL. The following example shows output abbreviation based on length: Lisp> (SETF *PRINT-RIGHT-MARGIN* 47) 47 Lisp> (SETF *PRINT-LENGTH* 11) 11 Lisp> (SETF *PRINT-PRETTY* T) T 0 Lisp> (FORMAT T "Stars: -@!_{_W_" -:_-}-." '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX 'CANOPUS ALBIREO CASTOR ALPHECCA ANTARES)) Stars: POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO Each star name in the list constitutes a separate logical section. FORMAT prints " " after the eleventh star name to indicate that the list has been abbreviated at that point. 5.7.2 Abbreviating Output Depth Use the variable *PRINT-LEVEL* to control the depth of printed output. *PRINT-LEVEL* specifies the lowest level of dynamically nested logical blocks to be printed. When your program calls FORMAT recursively, the output stream keeps track of the actual nesting level and abbreviates output when the level reaches *PRINT-LEVEL*. The printed character # indicates where the stream has truncated the output. You can prevent depth abbreviation by setting *PRINT-LEVEL* to NIL. o 5-24 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 0 Dynamic nesting of logical blocks occurs frequently when you print complicated structures. This nesting may not be obvious as you read the program. For example, if you have defined list-print functions for the primitives IF and PROGN, printing a program that uses a combination of these primitives would involve dynamic nesting of logical blocks, since each list print function uses the -w,directive implicitly. The following example shows how the output stream abbreviates the printing of a structure in accord with the value of *PRINT-LEVEL*: Lisp> (SETF *PRINT-LEVEL* 3) 3 Lisp> (PPRINT '(LEVEL1 (LEVEL2 (LEVEL3 (LEVEL4 (LEVELS)))))) (LEVEL1 (LEVEL2 (LEVEL3 #))) Lisp> (SETF *PRINT-LEVEL* 2) 2 0 O 0 Lisp> (PPRINT '(LEVEL1 (LEVEL2 (LEVEL3 (LEVEL4 (LEVELS)))))) (LEVELl (LEVEL2 #)) Lisp> (PPRINT '(LEVELl 4 5 6 (LEVEL2 (LEVEL3 (LEVEL4 (LEVELS)))))) (LEVELl 4 5 6 (LEVEL2 #)) 5.7.3 Abbreviating Output by Lines You can control the number of lines printed in the output by setting the *PRINT-LINES* variable. The value you supply specifies the number of lines to be printed for the outermost logical block. The output stream prints" ... " at the end of the last line to indicate where it has truncated the output. If *PRINT-LINES* is NIL, the output stream will not abbreviate the number of lines p·rinted. This abbreviation mechanism is effective only when pretty printing is enabled. In the following example, printing stops at line: the end of the fourth Lisp> (SETF *PRINT-LINES* 4) 4 Lisp> ( FORMAT T "Stars: - : !- /LINEAR/'. ti '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES)) Stars: POLARIS DUBHE MIRA MIRFAK 0 5-25 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT 5.8 USING MISER MODE If you print large structures with deeply nested logical blocks, you may find the miser mode useful. Indentation produced in the output by the nesting of logical blocks, prefixes, and the -nI directive reduces the line length available for printing. Miser mode ~elp~you avoid running out of space and printing beyond the right margin. Miser mode does not, however, guarantee the elimination of these problems. 0 Pretty printing uses single-line mode if the output fits on one line. If the FORMAT control string permits new lines and the output requires two or more lines, pretty printing normally uses multiline mode. The printer determines whether to print a logical block in miser mode according to the current column of the output at the beginning of the logical block and the values of two variables: e *PRINT-RIGHT-MARGIN* • *PRINT-MISER-WIDTH* 0 *PRINT-RIGHT-MARGIN* specifies the location of the right margin. *PRINT-MISER-WIDTH* specifies a number of columns before the right margin. When the current output column at the beginning of a logical block is equal to or greater than the difference between *PRINT-RIGHT-MARGIN* and *PRINT-MISER-WIDTH*, then the logical block is printed in miser mode. This condition occurs when the total available line width is less than the value of *PRINT-MISER-WIDTH*, as shown in Figure 5-1. COLUMN AT WHICH PRINTER ENTERS MISER MODE *PRINT-RIGHT-MARGIN* '----•PRINT-MISER-WIDTH*___.! Figure 5-1: Q 0 Variables Governing Miser Mode You can disable miser mode by setting *PRINT-MISER-WIDTH* to NIL. Miser mode.saves space by: • Ignoring indentation FORMAT directives 0 5-26 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT o 0 Starting a new line at every conditional new line directive: Multiline mode new line (- _) If-needed new line (-:_) Miser mode new line (-@_) The two examples that follow contrast mode and miser mode: pretty printing in multiline Lisp> (SETF *PRINT-RIGHT-MARGIN* 60) 60 Lisp> (SETF.*PRINT-MISER-WIDTH* 35) 35 Lisp> (FORMAT T .. - : !Stars with Arabic names: -s -s -271- :_-s - : r@_- s - ..: s - ii-_- s- • II '(BETELGEUSE (DENEB SIRIUS VEGA) ALDEBERAN ALGOL (CASTOR POLLUX) BELLATRIX) Stars with Arabic names: BETELGEUSE (DENEB SIRIUS VEGA) ALDEBERAN ALGOL (CASTOR POLLUX) BELLATRIX NIL Lisp> (FORMAT T "- !Stars with Arabic names: - :@!-s - :_-s -21r:_-s -:i-@_-s -_-s -11-_-s-.-." '(BETELGEUSE (DENEB SIRIUS VEGA) ALDEBERAN ALGOL (CASTOR POLLUX) BELLATRIX) Stars with Arabic names: BETELGEUSE (DENEB SIRIUS VEGA) ALDEBERAN ALGOL (CASTOR POLLUX) BELLATRIX 0 0 Qrn the first output sample, FORMAT uses multiline mode. Miser mode is never enabled, because the logical block begins at column O and miser mode takes effect only if the column begins at column 25 (60 35). ALDEBERAN lines up with the T in BETELGEUSE, because the -271 directive sets the indentation for following lines at column 27 and the :_ directive produces a new line. The -=I-@_-s directive sets the column for the next line at the level of the A in ALGOL. The -11 directive controls the last argument, BELLATRIX, setting the indentation to column 1. I O The second output example shows the effects of miser mode, because the text in the outer logical block, "Stars with Arabic names:", causes the inner logical block to begin at column 26. With *PRINT-MISER-WIDTH* set to 35, FORMAT enables miser mode when the logical block begins past column 25. FORMAT conserves space by starting a new line at every multiline mode new line directive(-_) and every if-needed new line directive (-:_). FORMAT also .inserts a 5-27 PRETTY PRINTING AND USING EXTENSIONS TO FORMAT new line at the miser mode new line directive (-@_) and ignores theo indentation directives (-nl). _ 5.9 HANDLING IMPROPERLY FORMED ARGUMENT LISTS VAX LISP provides a method for gracefully handling argument lists that are improperly formed. The function of the- ... directive, when used in a logical block, differs slightly from the corresponding function in COMMON LISP. In COMMON LISP the- ... directive is used with the iteration directives -{ and-} to check whether the argument list has been reduced to NIL. If the list is NIL, iteration stops. You can also use the- ... directive to check whether the argument l i s t Q for a logical block has been reduced to a non-NIL atom. If the check shows that the argument list is a non-NIL atom, the printer prints space-dot-space ( . ) and uses the -w directive to print the value of the atom. FORMAT then stops processing the immediately enclosing logical block, after printing the suffix (if one is there). No error condition results. The following example shows the use of FORMAT to print a dotted pair: Lisp> (FORMAT T "-1:!-@Cs- ... -}- ." '(CASTOR POLLUX DENEB. ALDEBERAN)) (CASTOR POLLUX DENEB. ALDEBERAN) 0 This feature serves as a useful debugging tool, because it lets the FORMAT function work even when'the argument list is improperly formed. NOTE When the- ... directive is included in a logical block, the FORMAT function checks whether the argument list is a non-NIL atom, even when pretty printing is not enabled. 5-28 0 (_] CHAPTER 6 VAX LISP/ULTRIX IMPLEMENTATION NOTES 0 0 VAX LISP is an implementation of LISP that is based on COMMON LISP as described in COMMON LISP: The Language. This chapter describes how implementaton-dependent aspects of COMMON LISP are implemented on the ULTRIX-32/32m operating systems. This chapter does not describe implementation differences between VAX LISP/VMS (VAX LISP as implemented on VMS) and VAX LISP/ULTRIX (VAX LISP as implemented on ULTRIX). For such differences, see the VAX LISP/ULTRIX Release Notes. These are on-line in the file /usr/lib/vaxlisp/lispnnn.mem, with nnn standing for the VAX LISP/ULTR.IX version number. For example, lisp020.mem is the file containing the release notes for Version 2.0. Most of the information in this chapter refers to subjects that COMMON LISP: The Language refers to as implem·entation dependent. The purpose of this chapter is to clarify the implementation specifics for the following topics: • Data representation 0 • Pathnames • The garbage collector / • Input and output • Keyboard functions that execute asynchronously when you type a control character e The compiler • Functions and macros NOTE 0 Complex numbers are documented in COMMON LISP: The Language, but they are not implemented in VAX LISP. 6-1 VAX LISP/ULTRIX IMPLEMENTATION NOTES T, NIL, and keywords are not legal function VAX LISP. names in 0 VAX LISP supports only symbols that are in the package named LISP. 6.1 DATA REPRESENTATION COMMON LISP defines the data types implemented in VAX LISP but COMMON LISP does not define implementation-dependent information related to the data types. This section provides data type information specific to VAX LISP. Complete descriptions of data types are provided in COMMON LISP: The Language. The following data types require VAX LISP implementation information: Q • Numbers • Characters • Arrays • Strings 0 Numbers 6.1.1 Sections 6.1.1.1 and 6.1.1.2 provide implementation i~formation the integer and floating-point number data types. about 6.1.1.1 Integers - COMMON LISP defines two subtypes of integers: fixnums and bignums. The ranges of these two integer types depend on the implementation. In VAX LISP, the integers in the range -2**29 to 2**29-1 are represented as fixnums; integ~rs not in the fixnum range are represented as bignums. VAX LISP stores bignums as two's complement bit sequences. In VAX LISP, the EQ function returns T when fixnums having the same value. it is called with Q two The values of the COMMON LISP integer constants are implementation -dependent. The names of the constants and the corresponding VAX LISP values follow: e MOST-POSITIVE-FIXNUM 536870911 e MOST-NEGATIVE-FIXNUM -536870912 6-2 0 VAX LISP/ULTRIX IMPLEMENTATION NOTES NOTE 0 The range of integers represented as fixnums will likely be cut in half in VAX LISP Version 3.0. That is, integers in the range -268,435,456 to +268,435,456 (-2**28 to 2**28-1) will be represented as fixnum~. The current range for fixnums is -2**29 to 2**29-1. Remember this note when placing FIXNUM declarations in your programs. Descriptions of these Language. 0 constants are provided 6.1.1.2 Floating-Point Numbers - COMMON LISP types of floating-point numbers: e Short floating-point numbers e Single floating-point numbers e Double floating-point numbers in COMMON defines the LISP: The following Long floating-point numbers VAX LISP, these four types are implemented with VAX floating data types. Both the short and single floating-point numbers are implemented as VAX F_floating data. Double floating-point numbers are implemented as VAX G_floating data. Long floating-point numbers are implemented as VAX H_floating data. For information on the VAX floating data types, see the VAX Architecture Handbook. O Table 6-1 lists the types of COMMON LISP floating-point numbers, the corresponding VAX data types, and the number of bits allocated for the exponent and significand of each flo~ting-point type. Table 6-1: 0 VAX LISP Floating-Point Numbers Exponent Significand COMMON LISP Type VAX Type SHORT-FLOAT F_floating 8 24 SINGLE-FLOAT F_floating 8 24 DOUBLE-FLOAT G_floating 11 53 LONG-FLOAT H_floating 15 113 6-3 VAX LISP/ULTRIX IMPLEMENTATION NOTES NOTE If your system does not have G and H floating-point instructions, see the ULTRIX-32 Programmer's Manual Binder IIIA "System Managers" for information on how to configure your system to use the g/h floating-poiot emulator. 0 The values of the COMMON LISP floating-point constants are implementation dependent. You can use the values of these constants to compare the range of values and the degrees of precision of the VAX LISP floating-point types. Table 6-2 lists the names of the constants and provides the actual hexadecimal values and the decimal approximations for VAX LISP. Table 6-2: 0- Floating-Point Constants Approximate Decimal Value Hexadecimal Representation Constant l.lld-16 DOUBLE-FLOAT-EPSILON d8MdMH88 IM883CCd DOUBLE-FLOAT-NEGATIVE-EPSILON 8M8Hl8111 8Ml83CC8 l.lld-16 LEAST-NEGATIVE-DOUBLE-FLOAT M8MH818Y 11118118 -S.56d-319 LEAST-NEGATIVE-LONG-FLOAT NIHYHHHM IHBYHMYM M8HIM888 88Y88RM1 -8.41L-4933 LEAST-NEGATIVE-SHORT-FLOAT 181118M8H -2.94e-39 LEAST-NEGATIVE-SINGLE-FLOAT MIMIBMBH -2.9Ce-39 LEAST-POSITIVE-DOUBLE-FLOAT •••••a•e MMBIMlll S.56d-389 LEAST-POSITIVE-LONG-FLOAT 88MMIMH8 MHHHIMBM HBIMMMld 88118881 B.41L-4933 LEAST-POSITIVE-SHORT-FLOAT 1111111111811 2.He-39 LEAST-POSITIVE-SINGLE-FLOAT 11111181188 2.94e-39 LONG-FLOAT-EPSILON 888H88AN 88888181 888811888 A88A3F91 9.63L-35 LONG-FLOAT-NEGATIVE-EPSILON 818HM8H8 8888M8HA 8R88M8MM IHIH3F91 9.63L-35 NOST-NEGATIVE-DOUBLE-FLOAT FFFFFFFF rrrFFFFF -B.99d387 NOST-NEGATIVE-LONG-FLOAT FFFFrrrF FFFFFFFF FFFFFFFF FFPFPFPF -s.9SL4931 NOST-NEGATIVE-SHORT-FLOAT PPPPPFFF -1.71•38 NOST-NEGATIVE-SINGLE-FLOAT PFPFPPFF -l.71e38 NOST-POSITIVE-DOUBLE-FLOAT FFFFFFPF FPPF7PFF B.99d317 MOST-POSITIVE-LONG-FLOAT FFFFFFFF FFFFFFFF FFFFFFFF FFFF7FFF S.9SL4931 MOST-POSITIVE-SHORT-FLOAT FFPF7FFF 1.7He38 MOST-POSITIVE-SINGLE-FLOAT FPFF7PPF l.71e38 SHORT-FLOAT-EPSILON 1111113481 5.96e-8 SHORT-FLOAT-IIEGATIVE-EPSILON 11113481 S.He-8 SINGLE-FLOAT-EPSILON HH348M S.He-8 SINGLE-FLOAT-NEGATIVE-EPSILON 11113481 S.He-8 Descriptions of these Language. constants are 6-4 provided in COMMON 0 0 LISP: The ·o VAX LISP/ULTRIX IMPLEMENTATION NOTES 0 COMMON LISP allows an implementation to define a floating-point zero. In VAX LISP, floating-point minus zero does not exist. 6.1.2 minus Characters COMMON LISP defines characters as objects that have three attributes: code, bits, and font. The code attribute specifies the way a character is printed or formatted. The bits and font attributes specify extra flags to be associated with a character. In VAX LISP, the character attributes are defined as follows: 0 • The code attribute consists of eight bits and is encoded using the extended ASCII character set. However, the ULTRIX operating system masks the eighth bit, which produces the same effect as having specified 7-bit characters. NOTE 0 You can prevent the masking of the eighth bit by setting the terminal in RAW mode, but this is not recommended (see tty(4) in the ULTRIX-32 Programmer's Manual). bits attribute consists of the four COMMON LISP bits: • The CONTROL, HYPER, META, and SUPER. • The font attribute consists of four bits. 0 NOTE The CONTROL attribute bit has no association control characters in the ASCII character set. with The VAX LISP implementation of COMMON LISP functions that perform character comparisons bases its comparisons on the numeric values that correspond to the extended 8-bit ASCII character set. The character functions and the rules that the functions use to compare I predicate characters are described in COMMON LISP: The Language. 0 The ordering of two characters that have different bits and attributes and the same character code is undefined in VAX LISP. font The COMMON LISP character constants that are the exclusive limits on the code, bits, and font attributes upper have 6-5 VAX LISP/ULTRIX IMPLEMENTATION NOTES implementation-dependent values. The names of the constants corresponding VAX LISP values are: D CHAR-CODE-LIMIT 256 e CHAR-BITS-LIMIT 16 e CHAR-FONT-LIMIT 16 and the 0 NOTE The value$ of these constants might change releases of VAX LISP. Descriptions of these constants are provided in in future COMMON LISP: The Language. You can obtain a table of valid VAX LISP character names by the VAX LISP CHAR-NAME-TABLE function described in Part II. 6.1.3 0 calling Arrays COMMON LISP defines· an array as an object whose components are arranged according to a Cartesian coordinate system and whose number of dimensions is called its rank. The limits on an array's rank, dimensions, and total size are implementation dependent. O The names of the array constants and the corresponding VAX LISP values are: e ARRAY-DIMENSION-LIMIT 536870911 e ARRAY-RANK-LIMIT 536870911 • ARRAY-TOTAL-SIZE-LIMIT 536870911 0 These constants are described in COMMON LISP: The Language. COMMON LISP defines a specialized array as an array that can. contain only elements of a specific type. VAX LISP creates a more efficient specialized array when an array's element type is STRING-CHAR,. (SIGNED-BYTE 32), or a subtype of FLOAT or (UNSIGNED-BYTE 1-29). If an array does not have one of these element types, VAX LISP creates a general array (element type is T). 0 6-6 VAX LISP/ULTRIX IMPLEMENTATION NOTES d.1.4 Strings COMMON LISP defines a string to be a vector of string characters. In VAX LISP, a string can be composed of as many as 65,535 characters. A string character is a character that can be stored in a string object. In VAX LISP, the characters that compose the 8-bit 1scII (see the first note in Section 6.1.2) character set are string characters. String characters cannot have a bits or font attribute. 6.2 PATHNAMES Pathnames exist both in ULTRIX and in COMMON LISP. However, pathnames are used with different meanings in the ULTRIX operating system and in OCOMMON LISP. O 0 o In ULTRIX, a pathname is an ULTRIX file specification. Chapter 1 for a description of ULTRIX pathnames. See e In COMMON LISP, a pathname is a LISP data object that represents a file specification. See COMMON LISP: The Language for a description of COMMON LISP pathnames. This section describes how VAX LISP implements COMMON LISP pathnames on the ULTRIX operating system; this section is not about ULTRIX pathnames. Unless otherwise noted, references to pathnames in this section are references to the word as used by COMMON LISP and as implemented by VAX LISP. The section is divided as follows: 0 Name strings 9 When to use pathnames· Cl Fields in a COMMON LISP pathname @ Field values of a VAX LISP pathname • Three ways to create pathnames • Comparing similar pathnames e Converting pathnames into namestrings • Functions that use pathnames e Using the *DEFAULT-PATHNAME-DEFAULTS* variable 0 6-7 VAX LISP/ULTRIX IMPLEMENTATION NOTES 6.2.1 Q Namestrings In VAX LISP, file names can be represented by pathnames, namestrings, symbols, or streams. Besides the term PATHNAME, COMMON LISP has introduced the term NAMESTRING. Since computer systems (for example, VMS and ULTRIX) have different ways of formatting file names, COMMON LISP uses namestrings to translate between 'pathnames (implementation-independent names) and file names (implementation-dependent names). A namestring is a string naming a file in an implementation-dependent form customary for the file system. A VAX LISP namestring is a string containing a valid ULTRIX file specification. For example, if a file in the ULTRIX file system is called /usr/users/doe/.profile, the equivalent namestring would be displayed as 11 /usr/users/doe/.profile". File system functions, such as LOAD, accept pathnames but internallyo convert them to namestrings. For more information on namestrings, see Section 6.2.7. 6.2.2 When to Use Pathnames Pathnames do not replace the traditional ways of representing a file in LISP. Instead, the pathnames add a new way of representing a f i l e o to make LISP programs portable between systems with different file-naming conventions. Pathnames, however, do not have to refer to an existing file or give complete file specifications·; pathnames can exist as data objects in themselves and are used as arguments to pathname functions (see Section 6.2.8 and COMMON LISP: The Language). Several pathname functions and most functions that deal with the f i l e o system can take either pathnames, namest~ings, symbols, or streams as their arguments. However, the values of the following variable and arguments must be pathnames: • The *DEFAULT-PATHNAME-DEFAULTS* variable • The defaults function argument in a call to the See Section 6.2.9 and COMMON LISP: The Language for a the preceding variable and function. PARSE-NAMESTRING description of ·o 6-8 VAX LISP/ULTRIX IMPLEMENTATION NOTES 0 6.2.3 A COMMON LISP pathname is a LISP data object composed of six Each field represents one of the following aspects of specification: 0 6.2.4 0 0 Fields in a COMMON LISP Pathname e Host - file system • Device - file structure or a (physical or logical) device on which files are stored • Directory - group of related files • Name - file name • Type - file extension • Version fields. a file number incremented every time the file is modified Field Values of a VAX LISP Pathname Although all VAX LISP pathnames contain the six fields of a COMMON LISP pathname to make its files portable, VAX LISP/ULTRIX uses only four of the fields. Since the ULTRIX operating system does not use version numbers or specifically ·indicate devices in its file specifications, VAX LISP/ULTRIX pathnames do not use the device and version fields of a COMMON LISP pathname. For a description of ULTRIX file specifications, see Chapter 1. The following examples show how the components of an ULTRIX file specification are mapped into the fields of a VAX LISP pathname. The first example shows an ULTRIX file specification: miami:/usr/~sers/doe/test.lsp The second example shows the pathname that file specification: represents the preceding #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY 11 /usr/users/doe" :NAME "test" :TYPE "lsp" :VERSION NIL) Table 6-3 names the fields of a VAX LISP pathname, the ULTRIX file components that correspond to those fields, and the data type each field accepts. 0 6-9 VAX LISP/UL TRIX IMPLEMENTATION NOTES Table 6-3: VAX LISP Pathname Fields 0 Field Name ULTRIX Component :HOST node :DEVICE not used :DIRECTORY directory String or NIL. This field does not include the slash(/) that separates a directory from a file name. Examples of directory field values are "usr/users/doe", "doe", and" .. ". :NAME filename String, NIL, or the :WILD keyword. The :WILD keyword is translated into the ULTRIX wildcard symbol, the asterisk Examples of name field values are (* ) . "lisp" and "l*sp". :TYPE filetype String, NIL, or the :WILD keyword. The :WILD keyword is translated into the ULTRIX wildcard symbol, the asterisk This field does not include the (* ) . period ( . ) that precedes the type. Examples of type field values used with the MAKE-PATHNAME function are "lsp" and "fas". :VERSION 6.2.5 Field Value String or NIL. An example field value is "miami:". of • a host 0 not used 0 Three Ways to Create Pathnames You can create a pathname in any one of three ways depending on of the following functions you use: • 0 which - The MAKE-PATHNAME function Lisp> (MAKE-PATHNAME :HOST "miami:" :DIRECTORY "/usr/usez:,s/doe" :NAME "test" :TYPE "lsp") #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe" :NAME "test" :TYPE "lsp" :VERSION NIL) 0 6-10 VAX LISP/ULTRIX IMPLEMENTATION NOTES The PATHNAME function 0 Lisp> (PATHNAME "miami:/usr/users/doe/test.lsp") #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe" :NAME "test" :TYPE "lsp" :VERSION NIL) e The PARSE-NAMESTRING function Lisp> (PARSE-NAMESTRING "miami:/usr/users/doe/test.l~p") #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe" :NAME "test" :TYPE "lsp" :VERSION NIL) O The MAKE-PATHNAME function directly creates a pathname from the user-input keywords :HOST, :DIRECTORY, and so on. On the other hand, the PATHNAME function and the PARSE-NAMESTRING function create a pathname by: • Using a pathname, argument. namestring, symbol, or stream as • Parsing the argument. e Returning a pathname, if the parse operation is a success. an Qsee COMMON LISP: The Language for descriptions of these functions. You can create a pathname that represents a directory name. To do so, place a slash (/) after the directory. For example, the string "/usr/users/doe" names the file doe in the directory /usr/users. However, the string "/usr/users/doe/" names only a directory, /usr/users/doe, and no file name. 0 NOTE The LISP system does not check that you enter an existing or a complete file specification when you create a pathname. So, you can create a pathname that is not usable in ULTRIX. If that situation occurs, and you perform a file operation, the operation will not succeed. To correct the problem, you must change the pathname to conform with an ULTRIX file specification. See Chapter 1 for a description of ULTRIX file specifications and see Section 6.2.4 for a description of the field values in a VAX LISP pathname. 0 6-11 VAX LISP/UL TRIX IMPLEMENTATION NOTES 6.2.6 Comparing Similar Pathnames 0 You should use the EQUAL function to compare pathnames with the same field entries. This function is sensitive to keywords and their equivalent symbols (that is, :WILD is equivalent to "*"). For example I if the MAKE-PATHNAME and PARSE-NAMESTRING functHms create different pathnames for the file test.*, you can use the EQUAL function to compare the pathname that is returned by each function (see COMMON LISP: The Language). The following calls to the SETF macro set the pathnames created by the MAKE-PATHNAME and PARSE-NAMESTRING functions to the variables X and Y: Lisp> (SETF x (MAKE-PATHNAME :NAME "test" :TYPE"*")) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY NIL :NAME "test" :TYPE "*" :VERSION NIL) Lisp> (SETF Y (PARSE-NAMESTRING "test.*")) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY NIL :NAME "test" :TYPE ":WILD" :VERSION NIL) 0 The EQUAL function can be used to compare the variables X and Y, even though the keyword :WILD and its string equivalent ("*") are used. Lisp> (EQUAL X Y) T The function returns T, indicating that the pathname values of X and Y are equal. 6.2.7 O Converting Pathnames into Namestrings You can convert a pathname into a namestring by specifying the pathname in a call to the NAMESTRING function. The VAX LISP implementation of the NAMESTRING function removes the host value if the value is the current host. The following call to the SETF macro sets THIS-PATHNAME to the pathname that is created with the PATHNAME function: Lisp> (SETF THIS-PATHNAME (PATHNAME "/usr/user/doe/test.lsp")) :itS(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe" :NAM~ "test" :TYPE "lsp" :VERSION NIL) When the NAMESTRING function is argument, the ~amestring that pathname's host: called with is returned Lisp> (NAMESTRING THIS-PATHNAME) "/usr/user/doe/test.lsp" 6-12 THIS-PATHNAME as its does not include the 0 VAX LISP/ULTRIX IMPLEMENTATION NOTES 6.2.8 0 Functions That Use Pathnames Most of the functions you can use to create and manipulate VAX LISP pathnames are described in COMMON LISP: The Language. However, the following two functions need further explanation: • The DIRECTORY function The DIRECTORY function (described in Section 6.7) converts its argument to a pathname and merges that pathname with the following ULTRIX file specification: host:directory/* 0 • The values for the host and directory fields are supplied by the *DEFAULT-PATHNAME-DEFAULTS* variable (see next section). The DEFAULT-DIRECTORY function The DEFAULT-DIRECTORY function (described in Part II) is supplied by VAX LISP in addition to the pathname functions described in COMMON LISP: The Language. This function returns a pathname that refers to the current directory. 0 6.2.9 Using the *DEFAULT-PATHNAME-DEFAULTS* Variable The value of the *DEFAULT-PATHNAME-DEFAULTS* variable is used by some pathname functions to fill pathname fields not specified in their arguments. The default value of this variable is a pathname whose host and directory fields indicate the current directory and whose device, name, type, and version fields contain NIL. 0 In VAX LISP, you can change the *DEFAULT-PATHNAME-DEFAULTS* variable in two ways: • value of the With the SETF macro The following example illustrates using change a pathname's directory from "/usr/users/doe/test": the SETF macro "/usr/users/doe" to to Lisp> (SETF *DEFAULT-PATHNAME-DEFAULTS* . (MAKE-PATHNAME :DIRECTORY 11 /usr/users/doe/test")) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe/test" :NAME NIL :TYPE NIL :VERSION NIL) With the DEFAULT-DIRECTORY function 0 The value of the *DEFAULT-PATHNAME-DEFAULTS* variable is set to the value of your default directory when LISP. starts and -6-13 VAX LISP/ULTRIX IMPLEMENTATION NOTES when you change your directory with -the form (SETF (DEFAULT-DIRECTORY) ... ). To check the value of your default directory, call the DEFAULT-DIRECTORY function. For example: O Lisp> (DEFAULT-DIRECTORY) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe" :NAME N!:L :TYPE NIL :VERSION NIL) The pathname returned in this example indicates that the default directory is /usr/users/doe on host miami. In this case, each time a pathname function fills a pathname field with a default value, the corresponding value in the directory "/usr/users/doe" is used. To change the value of your default directory, set it with the SETF macro. For example, the following illustrates how to change a default directory from /usr/users/doe to /usr/users/doe/test: 0 Lisp> (SETF (DEFAULT-DIRECTORY) "./test/") "./test/" The next example illustrates that when the directory is changed, the DEFAULT-DIRECTORY function returns a new pathname referring to the new default directory: Lisp> (DEFAULT-DIRECTORY) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY "/usr/users/doe/test" :NAME NIL :TYPE'NIL :VERSION NIL) 0 NOTE The value of the *DEFAULT-PATHNAME-DEFAULTS* variable must be a pathname. Do not set this variable to a namestring, symbol, or stream. 6.3 0 GARBAGE COLLECTOR When VAX LISP is executing, LISP objects are created dynamically. Some of the objects that are created are always used and referred to, while others are referred to for only a short time. When a LISP object can no longer be referred to, the space that the ·Object occupies can be reclaimed by the VAX LISP system. This process of reclaiming space is called garbage collection. The VAX LISP garbage collector is a stop-and-copy. garbage collector. The LISP system includes a dynamic memory pool, which is divided into 6-14 Q VAX LISP/ULTRIX IMPLEMENTATION NOTES C -~wo equal-sized spaces: dynamic-0 space and dynamic-1 space. At a ;iven time, LISP objects are allocated in either dynamic-0 or dynamic-1 space. When the memory in the current space is exhausted, LISP processing is temporarily suspended, and the LISP data objects that can still be referred to are copied to the other space. The objects that cannot be referred to are not copied. • You can ignore garbage collections of dynamic memory space when you are writing LISP programs. Garbage collections occur automatically when the current dynamic space is exhausted. Though LISP processing is suspended during a garbage collection, LISP processing continues when a garbage collection is complete. Sections 6.3.1 through 6.3.5 provide information about garbage collector. 0 6.3.1 the VAX LISP Frequency of Garbage Collection The frequency of garbage collection is proportional to the amount of dynamic memory space that is availa~le in the VAX LISP system. You can set the amount of dynamic memory space that is to be available by specifying the MEMORY (-m) option (see Chapter 2) when you invoke the LISP system. Garbage collection occurs less often if you use this ooption to increase the size of the dynamic memory space. The degree to which the frequency of garbage collection and the size of dynamic memory affects run-time efficiency depends on the program being executed. If a program creates more permanent objects than objects that can be referred to for a short period of time, the garbage collector has to perform more copy operations. As a result, the program slows down. The fewer the copy operations the garbage collector has to perform, the faster the garbage collection is ofinished. 6.3.2 Static Space LISP objects that are created in stati~ space are not collected by the garbage collector. These objects do not move and they are not deleted, even if they can no longer be referred to. You can create objects in static space by using the :ALLOCATION keyword with the , MAKE-ARRAY function (see Part II) or with the constructor function~ that are defined by the DEFINE-ALIEN-STRUCTURE macro for alien structures. (See the description of the DEFINE-ALIEN-STRUCTURE macro in Part II.), 0 6-15 - - - - - - --------------·~----··--------- - - - VAX LISP/ULTRIX IMPLEMENTATION NOTES 6.3.3 Messages When a garbage collection occurs, a message is displayed when theO operation begins and when it is finished. You can suppress these messages by changing the value of the VAX LISP *GC-VERBOSE* variable to NIL. When the value is NIL, messages are not displayed. You can also specify the contents of the messages values of the VAX LISP *PRE-GC-MESSAGE* and variables. The *GC-VERBOSE*, *PRE-GC-MESSAGE*, and variables are described in Part II: by changing the *POST-GC-MESSAGE* *POST-GC-MESSAGE* NOTE If you suppress or change the garbage collection messages and a garbage collection is initiated due to a control stack overflow, to determine whether your program is in a recursive loop is difficult. Therefore, you should not suppress or change the messages before you debug your program. 6.3.4 Available Space Garbage collection generally occurs when a LISP object is being created. If a garbage collection occurs and not enough dynamic memory space is available to allocate the object, an error is signaled. When this situation· exists, you can suspend the LISP image and resume it later with more dynamic-memory·space. For information· about how to suspend and resume a LISP image, see Ch~pter 2. 6.3.5 0 Q 0 Garbage Collection Failure The garbage collection process may fail to complete. If, for example, a garbage collection is initiated because of control stack overflow, the size of the control stack must increase, and the amount. of dynamic memory space must decrease. If the reduced dynamic memory space cannot contain all the LISP objects that can be referred to, the VAX LISP process is terminated, and control returns to the shell. This condition is usually caused by a user programming_ error, such as a function that is recursive and nonterminating. 6.4 INPUT AND OUTPUT VAX LISP terminal I/0 and file I/0 are implemented by way of low-level ULTRIX system I/0 routines. See the ULTRIX-32 Programmer's Manual for a description of ULTRIX I/0. 6-16 0 VAX LISP/ULTRIX IMPLEMENTATION NOTES 0 The VAX LISP implementation dependencies for I/0 have to do following topics: with the topics is COMMON LISP defines the #\NEWLINE character as a character that returned from the READ-CHAR function as an end-of-line indicator. VAX LISP, the character code for the #\NEWLINE character has integer value of 255. is In an In VAX LISP, the WRITE-CHAR and WRITE~STRING functions #\NEWLINE character as follows: the • Newline character • Terminal input • Terminal output • End-of-file operations • File organization • Functions 0 The implementation-dependent information provided in Sections 6.4.1 through 6.4.5. 6.4.1 0 about these Newline Character interpret the WRITE-CHAR function is called with the #\NEWLINE • When character as its argument value, the function starts writing a new line. This call is equivalent to a call function (see COMMON LISP: The Language). 0 • to the TERPRI When the WRITE-STRING function is called with an argument string that contains the #\NEWLINE character, the function divides the string into two lines. The following example shows the output that is displayed by the WRITE-STRING function when the #\NEWL_INE character is not used: Lisp> (WRITE-STRING (CONCATENATE 'STRING "NEW" "LINE")) NEWLINE "NEWLINE" 0 Both of the strings NEW and LINE are displayed on the same line. A call to the WRITE-STRING function, which includes a string argument that contains the #\NEWLINE character, looks like the following: 6-17 VAX LISP/ULTRIX IMPLEMENTATION NOTES Lisp> (WRITE-STRING (CONCATENATE 'STRING "NEW" (STRING #\NEWLINE) "LINE")) NEW LINE "NEW LINE" This call to the WRITE-STRING function NEW and LINE on separate lines. displays the 0 strings The #\NEWLINE character is the only character that causes a new line to be written. VAX LISP writes carriage returns and linefeeds without special interpretation. 6.4.2 0 Terminal Input In VAX LISP, ·terminals perform input operations in line mode. Input is returned by the READ-CHAR function only after you press the RETURN key. The READ-CHAR function returns ASCII characters as data unless a character is used by the ULTRIX terminal driver for terminal control. See the ULTRIX-32 Programmer's Guide [see ioctl(2) and stty(l) tty(4)] for information on terminal control characters. 6.4.3 Terminal Output ULTRIX truncates terminal output rather than wraps. more readable, set the *PRINT-PRETTY* variable to T. 6.4.4 0 To make output Q End-of-File Operations In VAX LISP, read operations from a file do_ not indicate the end of the file until the operation after the last character in the file is performed. Read operations from a terminal do not indicate the end of a VAX LISP. file in In VAX LISP, you can close a stream that is connected to your terminal if the stream is not·related to the stream bound to the *TERMINAL-IO*_ variable. If you attempt to close the stream boupd to *TERMINAL-IO*, no action is performed. 6-18· Q VAX LISP/UL TRIX IMPLEMENTATION NOTES 6.4.5 CJ File Organization VAX LISP creates ULTRIX files that are sequential streams. 6.4.6 Functions Two COMMON LISP functions used for I/0 have VAX LISP dependencies and need further explanation. The implementation information for the following functions is provided in the next two sections: CJ CJ e OPEN e WRITE-CHAR 6.4.6.1 OPEN Function - Before you can access a file, you must open it with the OPEN function or the WITH-OPEN-FILE macro. The OPEN function can be specified with keywords that determine the type of stream that is to be created and how errors are to be handled. The keywords you can specify are the following: e :DIRECTION @ ·:ELEMENT-TYPE o :IF-EXISTS e :IF-DOES-NOT-EXIST VAX LISP restricts the values you can specify for the preceding keywords. The rest of this section explains the restrictions. CJ For the :IF-EXISTS keyword values of :RENAME, :RENAME-AND-DELETE, and :SUPERSEDE, the old file is renamed to the same name with the string "old" appended to the file type. On closing files opened with any of these three values, and specifying :ABORT T, the new version is deleted and the old is restored to its former name. On closing files with :ABORT NIL, on :RENAME there is no action; with :RENAME-AND DELETE or :SUPERSEDE, the old file is deleted. VAX LISP supports all the values for the :ELEMENT-TYPE keyword except CHARACTER. VAX LISP allows you to open binary streams, but the maximum byte size for a stream is 512 8-bit bytes. CJ 6.4.6.2 WRITE-CHAR Function - In VAX LISP/ULTRIX, if a file is opened with :DIRECTION :IO, the user must set the file position with the FILE-POSITION function when changing from reading to writi~g and vice 6-19 VAX LISP/ULTRIX IMPLEMENTATION NOTES versa. Not setting the file position will cause the file to be left in an inconsistent state. The WRITE-CHAR function disregards the characters. 6.5 bit and font attributes Q of KEYBOARD FUNCTIONS A keyboard function is a function that is invoked when the user types a particular control key. The BIND-KEYBOARD-FUNCTION function binds an ASCII control character to a function, creating a keyboard function. A keyboard function interrupts the current LISP processing as soon as the specified control key is typed. When the keyboard function exits, the VAX LISP system resumes processing at the point where it was interrupted. Note that you can use the BIND-KEYBOARD-FUNCTION to bind only three characters (C, \, and Z). See Chapter 2 foi more information on these characters. Keyboard functions are not always called as soon. as the specified control key is typed. If a low-level LISP function, such as CDR or CONS, is being evaluated or a garbage collection is being performed, keyboard functions are placed in a queue until they can be evaluated. Delays in keyboard function evaluation are generally not perceptible. An example of when you might perceive a delay is when the system performs a garbage collection. 0 0 VAX LISP also provides a means· by which you can assign different priorities for keyboard functions. These priorities, called interrupt levels, are described in the VAX LISP/ULTRIX system Access Programming Guide. If you suspend the LISP system when keyboard functions are defined, the functions are still defined when the system is resumed. The key/function bindings are not lost. Q Besides the BIND-KEYBOARD-FUNCTION function are. the VAX LISP functions GET-KEYBOARD-FUNCTION and UNBIND-KEYBOARD-FUNCTION. The GET-KEYBOARD-FUNCTION function returns information about a function that is bound to a control character, and the UNBIND-KEYBOARD-FUNCTION function removes the binding of a function from a.control character. Descriptions of the BIND-KEYBOARD-FUNCTION, GET-KEYBOARD-FUNCTION, and UNBIND-KEYBOARD-FUNCTION functions are provided in Part II. 0 6-20 VAX LISP/UL TRIX IMPLEMENTATION NOTES 0 6.6 COMPILER For inform~tion on how to compile LISP expressions and the advantages and disadvantages of compiling LISP expressions, see Chapter 2. This section describes two compiler restrictions (one with the COMPILE function and one with the COMPILE-FILE function) and compiler optimizations. • 6.6.1 0 0 0 Compiler Restrictions The VAX LISP compiler translates interpreted function definitions into function objects that contain VAX instructions. The COMPILE function causes these objects to be bound as the definitions of the symbols that name them. The COMPILE-FILE function puts the objects into an output file. Because of the way these two functions handle such objects, a restriction exists for the use of each of the functions. 6.6.1.1 COMPILE Function - The compiler cannot compile pieces of code unless they are function definitions defined at top level. Therefore, you cannot use the COMPILE function to compile a function unless you create the function in a null lexical environment (not top level). An example of a LISP expression that cannot be evaluated follows: Lisp> (LET ((COUNTER 0)) (COMPILE NIL #'(LAMBDA() (INCF COUNTER)))) The COMPILE function cannot compile the function object in the preceding example because the object depends. on the lexical environment in which it was created. In the following example, the COMPILE function is called with a lambda expression rather than a function object: Lisp> (LET ((COUNTER 0)) (COMPILE NIL '(LAMBDA() (INCF COUNTER)))) The call to the COMPILE function in the preceding example compiles the lambda expression. The value that is returned is a compiled object that increments the dynamic value of COUNTER. The compiled object does not increment the local value of COUNTER, which encloses the call to the COMPILE function. 0 6.6.1.2 COMPILE-FILE Function - The COMPILE-FILE function encloses each top-level form of the file it is compiling with an anonymous function definition. Therefore, the function cannot put a compiled function object that is recognized as data into an output file. Consider the following form: 6-21 VAX LISP/ULTRIX IMPLEMEN'rATION NOTES Lisp> (SETF F '#.(COMPILE NIL '(LAMBDA (C) (PRINT C)))) #<Compiled Function #:G1149 #x504C4C> 0 When the COMPILE-FILE function reads the preceding form from a file that is being compiled, an anonymous function is created. This function becomes part of the third element of the list wl\ose first element is the SETF special form. The preceding call to the ~ETF special form can be compiled but the list cannot be put into the output file. 6.6.2 Compiler Optimizations In VAX LISP, you can control two qualities of compiled code: the speed of the generated code and whether run-time safety checking is to be performed. The default value for these qualities is 1. You ·-can set the values globally and locally.· To set the values globally in VAX LISP, you can either use the shell vaxlisp command with the COMPILE (-C) and the OPTIMIZE (-V "OPTIMIZE=value") options (see Chapter 2) or specify the OPTIMIZE declaration in a call to the PROCLAIM function ( see COMMON LISP: The Language). Both' '·methods of setting the quality values produce the same results. For example, if you are in the ·shell and you want to set the global values of the speed quality (speed of object code) to 3 · and the safety quality (run-time error checking) to·· 2, _use the following ULTRIX command specification: Q Q % vaxlisp -V "COMPILE OPTIMIZE=(SPEED:3,SAFETY:2)" myprog.lsp If you are in LISP and you want to set the global values of the speed and safety qualities, specify the PROCLAIM function as the first form in the file. For example, to set the values of the qualities to the same values that were set in the preceding example, specify the following call to the PROCLAIM function as the first form in the file myprog.lsp: Q (PROCLAIM '(OPTIMIZE (SPEED 3) (SAFETY 2))) You can also set the quality values locally. To do this,' you must use the OPTIMIZE declaration within the form for which you-want the values to be set. Local optimization quality-values override global ·quality values. All proclamations are put into the fastload file so that they also occur when fastloaded. However, the compiler observes INLINE proclamations only when the OPTIMIZE SPEED quality is greater than the OPTIMIZE SPACE quality, and does not check for stack overflow. If you are more concerned about the safety of your code than the speed at which it .is evaluated, the ·value of the safety quality must be greater than 1, or the value of the speed quality must be less than 2. 6-22 Q VAX LISP/ULTRIX IMPLEMENTATION NOTES O - 0 When this relationship exists between the two quality values, the compiler generates safe code. Safe code is code that checks arguments to ensure that the arguments are of the proper data type. Examples of safe code are the following: • Code that uses generic arithmetic • Code that checks if the arguments of calls to require list arguments are lists o Code that checks whether indices used bound 0 access that arrays are If you are more interested in producing code that is evaluated fast than in producing safe code, the value of the speed quality must be greater than or equal to 2, and the value of the safety quality must be less than or equal to 1. When this relationship exists between the two quality values, the compiler considers type declarations and generates type-specific code. Type-specific code executes faster than safe code. If you want the compiler to generate type-specific code, you must specify declarations in your code in addition to setting the values of the speed and the safety qualities to the correct values. Consider the following code and suppose quality is 1 and the speed quality is 2: 0 to • functions the value of the safety (DEFUN LOOP-OVER-A-SUBLIST (INPUT-LIST) (DO ((I (GET-INITIAL-VALUE) (1+ I)) (L INPUT-LIST (CDR L))) ((OR(>= I (THE FIXNUM *FINAL-VALUE*)) ( ENDP L) ) L) (DECLARE (FIXNUM I) (LIST L)) (DO-SOME-WORK LI))) Since the value of the safety quality is less than 2 and the value of the speed quality is greater than 1, the compiler regards the type declarations. In this example, the types FIXNUM and LIST are declared with the following form: (DECLARE (FIXNUM I) (LIST L)) When the example code is compiled, the compiler uses the type declarations and translates the 1+, CDR, ENDP, and>= functions in the code as follows: Q • The 1+ function becomes one VAX instruction. • The CDR function becomes one VAX instruction. 6-23 VAX LISP/ULTRIX IMPLEMENTATION NOTES The ENDP function is transformed into the NULL function. function becomes two VAX • The>= comparison and a branch. instructions: a longwordO The value of the *FINAL-VALUE* variable and the return value of the GET-INITIAL-VALUE function must be fixnums. Also, the fNPUT-LIST argument specified for the LOOP-OVER-A-SUBLIST function must be a true list (not an atom or a dotted list). If a declaration is violated, the error that results is not signaled. For example, if you call the LOOP-OVER-A-SUBLIST function with the symbol LOOP, an error results because the argument is not a list, but the error is not signaled. Errors such as this can cause damage to the LISP environment, which cannot be repaired. By default, the values of the speed and safety qualities are set such that error checking and signaling code are generated for all operations; such values prevent you from damaging the LISP environment. Q If the INPUT-LIST argument in the preceding example is not guaranteed to always be a list, you can add an explicit type check before the DO loop. The following form is an example of an explicit type check: (UNLESS (LISTP INPUT-LIST) ;but doesn't check for a dotted-list (ERROR "Cannot loop through this object: -s." INPUT-LIST)) O The check performed by the LISTP function is evaluated at run time, even though the compiler might heed the FIXNUM and LIST declarations. If you want a function to be compiled inline, you must proclaim it INLINE. Declaring a function INLINE has no effect. However, once a function has been proclaimed INLINE, it will be compiled inline unless specifically declared NOTINLINE. For more information on making LISP compiled code run release notes. 6. 7 fast, see theQ FUNCTIONS AND MACROS Several functions and macros described in COMMON LISP: The Language have implementation dependencies. Table 6-4 lists the names of these functions and macros and provides a brief explanation of the type of information that is implementation dependent. For a summary description of these functions and macros, see Part II •. Each description consists of the function's or macro's use, implementation-dependent information, format, applicable arguments, return value, and examples of use. See COMMON LISP: The Language for. further information regarding these functions and.macros. Q 6-24 VAX LISP/ULTRIX IMPLEMENTATION NOTES 0 0 0 0 Table 6-4: Summary of Implementation-Dependent Functions and Macros Name Function or Macro Implementation-Dependent Information APROPOS Function Optional argument and tDO-SYMBOLS macro APROPOS-LIST Function Optional argument and DO-SYMBOLS macro BREAK Function Facility invoked COMPILE-FILE Function Keywords and return value DESCRIBE Function Displayed output DIRECTORY Function Argument merged with wildcards DRIBBLE Function Cannot nest calls GET-INTERNAL-RUN-TIME Function Meaning of return value LOAD Function Finds latest file LONG-SITE-NAME Function Location of information string returned MACHINE-INSTANCE Function Return value MACHINE-VERSION Function Return value MAKE-ARRAY Function :ALLOCATION keyword REQUIRE Function Modules ROOM Function Displayed output SHORT-SITE-NAME Function Location of information string returned TIME Macro Displayed output TRACE Macro Keywords WARN Function Facility invoked 0 6-25 ------------------------··-·---·---·------- for for 0 0 0 0 0 0 0 0 0 0 PART II VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS 0 0 0 0 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS APROPOS Function 0 Searches through packages for symbols whose print names contain a specified string. The function is not sensitive to the case of characters. The string can be either the print name or a substring of the symbol's print name. The APROPOS function displays a message that shows the string that 'is being searched for and the name of the package that is being searched. When the function finds a symbol whose print name contains th_e string, the function displays the symbol's name. If the symbol has a value, the function displays the phrase "has a value" after the symbol as follows: *MY-SYMBOL*, has a value 0 If the symbol has a function definition, the function phrase "has a definition" after the symbol as follows: displays the MY-FUNCTION, has a definition In VAX LISP, the APROPOS function uses the DO-SYMBOLS macro rather than the DO-ALL-SYMBOLS macro. As a result, the function displays by default only symbols that are accessible from the current or specified package. For information on packages, see COMMON LISP: The Language. Q Format APROPOS string &OPTIONAL package Arguments string 0 The string to be searched for in the symbols' print names. If you specify a symbol for this argument, the symbol's print name is used. package An optional argument. If you specify the argument, the symbols in the specified package are searched. If you specify T, all packages are searched. If you do not specify the argument, the symbols that are accessible in the current package are searched. Return Value No value. 0 1 --------·-------------------· VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS APROPOS Function (cont.) 0 Example Lisp> (APROPOS. "*PRINT") Symbols in package USER containing the string "*PRINT":•. *PRINT-CIRCLE*, has a value *PRINT-SLOT-NAMES-AS-KEYWORDS*, has a value *PRINT-RADIX*, has a value *PRINT-ESCAPE*, has a value *PRINT-ARRAY*, has a value *PRINT-GENSYM*, has a value *PRINT-LEVEL*, has a value *PRINT-PRETTY*, has a value *PRINT-LENGTH*, has a value *PRINT-RIGHT-MARGIN*, has a value *PRINT-MISER-WIDTH*, has a value *PRINT-BASE*, has a value *PRINT-CASE*, has a value *PRINT-LINES*, has a value Searches the package USER for the string *PRINT and displays list of the symbols that contain the specified string.· O a 0 0 0 2 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS QAPROPOS-LIST Function Searches through packages for symbols whose print names contain a speci~ied string. The function is not sensitive to the case of characters. The string can be either the print name or a substring of the symbol's print name. When the function completes its search, it returns symbols whose print names contain the string. a list of the In VAX LISP, the APROPOS-LIST function uses the DO-SYMBOLS macro rather than the DO-ALL-SYMBOLS macro. As a result, the function includes by default only symbols that are accessible from the current package in the list it returns. For information on packages, see COMMON LISP: The Language. QFormat APROPOS-LIST string &OPTIONAL package Arguments string 0 The string to be ~earched for in th~ symbols' print names. If you specify a symbol for this argument, the symbol's print name is used. package An optional argument. If you specify the argument, the symbols in the specified package are searched. If you specify T, all packag~i are searched. If you do not specify the argument, the symbols that are accessible in the current package are searched. OReturn Value A list of the symbols whose print names contain the string. Example Lisp> (APROPOS-LIST "ARRAY") (ARRAY-TOTAL-SIZE ARRAY-DIMENSION ARRAY-DIMENSIONS SIMPLE-ARRAY ARRAY-DIMENSION-LIMIT ARRAY-ELEMENT-TYPE ARRAYP *PRINT-ARRAY* ARRAY-RANK ARRAY-RANK-LIMIT MAKE-ARRAY ARRAY-TOTAL-SIZE-LIMIT ARRAY-ROW-MAJOR-INDEX ADJUST-ARRAY ARRAY ARRAY-IN-BOUNDS-P ADJUSTABLE-ARRAY-P ARRAY-HAS-FILL-POINTER-P) 0 Searches the symbols that are accessible in the current package for the string ARRAY and returns a list of the symbols that contain the specified string. 3 ' VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS BIND-KEYBOARD-FUNCTION Function Binds an ASCII keyboard control character (characters of codes O t o o 31) to a function. When a control character is bound to a function, you can execute the function by typing the control character on your terminal keyboard. A function bound in this way is called a keyboard function. ' On ULTRIX, the control characters that can be bound are those that generate the SIGINT, SIGQUIT, and SIGTSTP signals, by default <CTRL/C>, <CTRL/\>, and <CTRL/Z> respectively. You can use the shell command stty(l) (stty all) to find the current bindings of these signals. When you type the control character, the LISP system is interrupted at its current point, and the function the control character is bound to is called asynchronously. The LISP system then evaluates the function and returns control to where the interruption occurred. Q You can delete the binding of a function and a control character by using the UNBIND-KEYBOARD-FUNCTION function. You can use the GET-KEYBOARD-FUNCTION function to get information about a function that is bound to a control character. You can specify an interrupt level (an integer in the range O through 7) for a keyboard function by using the :LEVEL keyword. A keyboardo function can only interrupt code that is executing at an interrupt level below its own. Keep the following guidelines in mind when specifying an interrupt level: • The default interrupt level for keyboard functions is 1. · Interrupt level 6 is used by LISP to handle keyboard input; • therefore, a keyboard function executing at interrupt level 6 cannot receive input from the keyboard. careful when using interrupt level 6. For this reason, be Q • Interrupt level 7 can interrupt any code that is not in the body of a CRITICAL-SECTION macro. A keyboard function executing at interrupt level 7 must terminate by executing a THROW to a tag, such as CANCEL-CHARACTER-TAG. • If you bind a control character to the BREAK or DEBUG functions, use a level that is high enough to interrupt your other keyboard functions but that is less than 6. The VAX LISP/ULTRIX System Access Programming Guide contains information about using interrupt levels and about CRITICAL-SECITON macro. more the 0 4 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS BIND-KEYBOARD-FUNCTION Function (cont.) 0 NOTE When you bind a control character to a function, the stream bound to the *TERMINAL-IO* variable must be connected to your terminal. • See Chapter 6 asynchronously. for an explanation about calling functions Format BIND-KEYBOARD-FUNCTION control-character function &KEY :ARGUMENTS :LEVEL O Arguments control-character The ASCII control character to be bound to the function. You can bind a function to a control character that generates the ULTRIX SIGINT, SIGQUIT, or SIGTSTP signal (by default, <CTRL/C>, <CTRL/\>, and <CTRL/Z>). Q function The function to which the control character is to be bound. :ARGUMENTS 0 A list containing arguments to be passed to the specified function when it is called. The arguments in the list are evaluated when the BIND-KEYBOARD-FUNCTION function is called. :LEVEL An integer in the range 0-7, specifying the interrupt the keyboard function. The default is 1. Return Value T. 0 5 level for VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRiPTIONS BIND-KEYBOARD-FUNCTION Function. (cont.) 0 Example Lisp> (BIND-KEY.BOARD-FUNCTION #\FS #'BREAK). T Lisp> <CTRL/\> Break> Binds <CTRL/\> to the BREAK function. loop by typing <CTRL/\>. You can theri invoke a break 0 0 0 6 VAX 'USP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS BREAK Function 0 For Invokes a break loop. A break loop is a nested read-eval-print loop. more information about break loops, see Chapter 4. Format BREAK &OPTIONAL format-string &REST args Arguments format-string · The string of characters that is passed to the FORMAT function to create the break-loop message. 0 args The arguments that are passed to the FORMAT function as arguments for the format string. Return Value When the CONTINUE function is called to exit the break loop, BREAK function returns NIL. the Q Example (WHEN (UNUSUAL-SITUATION-P CONDITION) (BREAK "Unusual situation -n encountered. Please investigate" CONDITION)) 0 Calls the BREAK function if the value of the UNUSUAL-SITUATION-P function is not NIL. The break message contains the condition code. 0 7 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS CANCEL-CHARACTER-TAG Tag CANCEL-CHARACTER-TAG, when used in a CATCH construct,· catches the throw that occurs whenever the cancel character is typed at the keyboard. In VAX LISP/ULTRIX, <CTRL/C> by default causes a THROW to CANCEL-CHARACTER-TAG. Thus, you can use CANCEL-CHARACTER-TAG in a CATCH construct to alter the behavior when a user types <CTRt/C>. To check the characters that are bound to signals, type the shell command stty all. 0 You can also use CANCEL-CHARACTER-TAG in a THROW construct to cause an exit to the VAX LISP read-eval-print loop. In this way, you can partially simulate the action of the cancel character from within your code. (The cancel character also invokes the CLEAR-INPUT function on the *TERMINAL-IO* stream.) Format 0 CANCEL-CHARACTER-TAG Example Lisp> (DEFUN TRAPPER() (CATCH 'CANCEL-CHARACTER-TAG (LOOP)) (PRINC "Execution came through here")) TRAPPER Lisp> (TRAPPER) <CTRL/C> Execution came through here "Execution came through here" Lisp> 0 for • The TRAPPER function sets up a catcher CANCEL-CHARACTER-TAG, then enters an infinite loop. • The user types <CTRL/C>. • The PRINC function prints a string, indicating that execution continued following the CATCH form rather than returning directly to the Lisp> prompt. 0 0 8 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS 0 CHAR-NAME-TABLE Func.tion Displays a formatted list of the VAX LISP character names. Format CHAR-NAME-TABLE Return Value No value. Example Lisp> (CHAR-NAME-TABLE) 0 0 Hex Code 00 01 02 03 04 05 06 07 08 09 OA OB oc 0 0 OD OE OF 10 11 12 13 14 15 16 17 18 19 lA 1B lC 1D 1E lF 20 7F Preferred Name Other Names NULL "A ,. B NUL SOH STX ETX EOT ENQ ACK .. G BEL ,. H BS .. I HT ... J LF VT "L FORM FEED "M CR ,. c ,. D .. E ,. F BELL BACKSPACE TAB LINEFEED "K PAGE RETURN "'N "O "P ,. Q "'R "S "T ,. u "V "W ,. x "Y ... z ESCAPE FS GS RS so SI DLE XON DCl DC2 XOFF DC3 DC4 NAK SYN ETB CAN EM SUB ESC ALT MODE us SPACE RUBOUT SP DELETE 9 DEL FF VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS CHAR-NAME-TABLE Function (cont.) 84 85 86 87 88 89 BA BB BC BD BE 8F 90 91 92 93 94 95 96 97 9B 9C 9D 9E 9F FF 0 IND NEL SSA ESA HTS HTJ VTS PLD PLU RI SS2 SS3 DCS PUl PU2 STS CCH MW SPA EPA CSI ST 0 osc PM APC NEWLINE 0 0 0 10 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS COMPILEDP Function 0 A predicate that checks whether an object compiled function definition. is a symbol has a definition is that Format COMPILEDP name Argument name The symbol whose function, macro, or special form to be checked. 0 0 0 Return Value The interpreted function, macro, or special form definition, if the symbol has an interpreted definition that was compiled with the COMPILE function. Returns T, if the symbol has a compiled definition that was not compiled with the COMPILE function. Returns NIL, if the symbol does not have a compiled function definition. Example Lisp> (DEFUN ADD2 (X) (+ X 2)') ADD2 Lisp> (COMPILEDP 'ADD2) NIL Lisp> (COMPILE 'ADD2) ADD2 compiled. ADD2 Lisp> (COMPILEDP 'ADD2) (LAMBDA (X) (BLOCK ADD2 (+ X 2))) • The call to the DEFUN macro defines a function named ADD2. • The first call to the COMPILEDP function returns NIL, the function ADD2 has not been compiled. • The call to the COMPILE function compiles the function ADD2. • The second call to the COMPILEDP function returns the interpreted function definition, because the function ADD2 was previously compiled. 0 11 ----··-------------·----..- - - because VAX LISP/ULTRIX FUNCTION, MACHO, AND VARIABLE DESCRIPTIONS COMPILE-FILE Function Compiles a specified LISP source file and writes the compiled code a binary fast-loading file (type fas). Format COMPILE-FILE input-pathname &KEY :LISTING :MACHINE-CODE :OPTIMIZE :OUTPUT-FILE :VERBOSE :WARNINGS Arguments input-pathname A pathname, namestring, symbol, or stream. The compiler uses the value of the *DEFAULT-PATHNAME-DEFAULTS* variable to fill in file specification components that are not specified. The file type defaults to lsp. O :LISTING Specifies whether the compiler is to produce a listing file. The value can be T, NIL, or a· pathname, namestring, symbol, or stream. If you specify T, the compiler produces a listing file. The listing file is assigned the same name as the source file with the file type lis, and is placed in the directory that contains the source file. If you specify NIL, no listing is produced. NIL. O The default value is If you specify a pathname, nam·estring, symbol, or stream, the compiler uses the value as the specification of the listing file. The compiler uses the lis file type and the value of the input-pathname to fill the components of the file specification that are not specified. Q :MACHINE-CODE Specifies whether the compiler is to include the machine code it produces for each function and macro .it compiles in the listing file. The value can be Tor NIL. If you specify T, the listing file contains the machine code. If you spe~ify NIL, the listing file does not contain the machine code. The default value is NIL. :OPTIMIZE Specifies the optimization qualities the compiler is to use during compilation. The value must be a li&t of sublists. Each sublist must contain a symbol and a value, which specify the 12 0 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS COMPILE-FILE Function (~ont.) 0 optimization qualities and corresponding values that the compiler is to use during compilation. For example: ((SPACE 2) (SAFETY 1)) . The default value for each quality is one. For discussion of compiler optimizations, see Chapter 6. a detailed :OUTPUT-FILE 0 Specifies whether the compiler is to produce a fast-loading file. The value can be T, NIL, or a pathname, namestring, symbol, or stream. If you specify T, the compiler produces a fast-loading file. The output file is assigned the same name as the source file with the file type fas and is placed in the directory that contains the source file. The default value is T. If you specify NIL, no fast-loading file is produced. 0 0 If you specify a pathname, namestring, symbol, or stream, the compiler uses the value as the specification of the output file. The compiler uses the fas file type and the value of the input-pathname to fill the components of the file specification that are not specified. :VERBOSE Specifies whether the compiler is to display the name of functions and macros it compiles. The value can be Tor NIL. If you specify T, the compiler displays the name of each function and macro. If a listing file exists, the compiler also includes the names in the listing file. If you specify NIL, the names are not displayed or included in the listing file. The default value is the value of the *COMPILE-VERBOSE* variable (By default, T). :WARNINGS Specifies whether the compiler is to display warning messages. The value can be T or NIL. If you specify T, the compiler displays warning messages. If a listing file exists, the compiler also includes the messages in the listing file. If you specify NIL, warning messages are not displayed or included in the listing file. The default value is the value of the *COMPILE-WARNINGS* variable (By default, T). Return Value 0 If the compiler generated an output returned. Otherwise, NIL is returned. 13 file, a namestring is VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS COMPILE-FILE Function (cont.) 0 Examples 1. Lisp> (COMPILE-FILE "factorial" :VERBOSE T) Starting compilation of file /usr/users/smith/facto~ial.lsp FACTORIAL compiled. Finished compilation of file /usr/users/smith/factorial.lsp O Errors, 0 Warnings "/usr/usrs/smith/factorial.fas" Compiles the file factorial.lsp, which is in the current directory. A fast-loading file named factorial.fas is produced. The compilation is logged to the terminal, because the :VERBOSE keyword is specified with the value T. 2. Lisp> (COMPILE-FILE "factorial" :OUTPUT-FILE NIL :LISTING T :WARNINGS NIL :VERBOSE NIL) NIL Compiles the file factorial.lsp, which is in the current directory. A fast-loading file is not produced, because the :OUTPUT-FILE keyword is specified with the value NIL. A listing file named factorial.lis is produced. warning messages are suppressed, because the :WARNINGS keyword is specified with the value NIL. o o 0 0 14 VAX USP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS *COMPILE-VERBOSE* Variable Ocontrols the amourit of information 'that the compiler displays. The COMPILE-FILE function binds the *COMPILE-VERBOSE* variable to the value supplied by the :VERBOSE keyword. If the :VERBOSE keyword is not specified, the function uses the existing ~alue t of the *COMPILE-VERBOSE* variable. If the value is not NIL, the compiler displays the name of each function as it is compiled; if the value is NIL, the compiler does not display the function names. The default value is T. Example Lisp> (COMPILE-FILE "math") Starting compilation of file /usr/users/smith/math.lsp 0 0 0 FACTORIAL compiled. FIBONACCI compiled. Finished compilation of file /usr/users/smith/math.lsp O Errors, 0 Warnings "/usr/users/smith/math.fas" Lisp> (SETF *COMPILE-VERBOSE* NIL) NIL Lisp> (COMPILE-FILE "math") "/usr/users/smith/math.fas" • The first call to the COMPILE-FILE function shows the output the compiler displays during the compilation of a file, when the *COMPILE-VERBOSE* variable is set to T. • The call to the SETF macro sets the value of the NIL. • The second call to the COMPILE-FILE function compiles the file without displaying output, because the variable's value is NIL. 0 15 variable to VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS *COMPILE-WARNINGS* Variable D Controls whether the compiler displays warning messages during compilation. The COMPILE-FILE function binds the *COMPILE-WARNINGS* variable to the value supplied with the :WARNINGS keyword. If the :WARNINGS keyword is not specified, the function uses the existin0 valu~ of the *COMPILE-WARNINGS* variable. If the value is not NIL, the compiler displays warning messages; if the value is NIL, the compiler does not display warning messages. The default value is T. NOTE The compiler always error messages. displays fatal and continuable 0 Example Lisp> (COMPILE-FILE "math") Starting compilation of file /usr/users/smith/math.lsp Warning in FACTORIAL N bound but value not used. FACTORIAL compiled. Warning in FIBONACCI N bound but value not used . . FIBONACCI compiled. 0 Finished compilation of file /usr/users/smith/math.lsp O Errors, 2 Warnings "/usr/users/smith/math.fas" Lisp> (SETF *COMPILE-WARNINGS* NIL) NIL Lisp> (COMPILE-FILE "math") Starting compilation of file /usr/users/smith/math.lsp 0 FACTORIAL compiled. FIBONACCI compiled. Finished compilation of file /usr/users/smith/math.lsp O Errors, 2 Warnings "/usr/users/smith/math.fas" • The first call to the COMPILE-FILE function shows the output the compiler displays during the compilation of a file, when the *COMPILE-WARNINGS* variable is set to T. • The call to the SETF macro sets the value of the NIL.. 16 variable to 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *COMPILE-WARNINGS* V~riable (cont.) 0 · • The second call to the COMPILE-FILE function compiles the file without displaying warning messages in the output, because the variable's value is NIL. 0 0 0 0 17 VAX LISP/ULTRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS CONTINUE Function Enables you to exit the .break loop. When you call this function, it causes the BREAK function to return NIL and the evaluation of your program to continue from the point at which the break loop was entered. 0 Format CONTINUE Return Value NIL. Example Lisp> (BIND-KEYBOARD-FUNCTION #\FS #'BREAK) Lisp> (LOAD "fileb.lsp") ; Loading contents of file /usr/usrs/smi ... 0 "\ Break> (LOAD "filea.lsp") Loading contents of file /usr/usrs/smith/filea.lsp FUNCTION-A Finished loading /usr/usrs/smith/filea.lsp T Break> (CONTINUE) Continuing from break loop ... , FUNCTION-B ; Finished loading /usr/usrs/smith/fileb.lsp 0 T Lisp> • The BREAK function is bound to <CTRL/\> ("\). • The file fileb.lsp is loaded. • The programmer, realizing that filea.lsp (which is needed to initialize an environment for fileb.lsp) is not yet loaded, invokes the BREAK loop. • The file filea.lsp is then loaded. 0 Finally, the call to the CONTINUE function continues the • loading of fileb.lsp and then returns the programmer to the top-level loop. 0 18 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTION~ 0 DEBUG Function Invokes the VAX LISP debugger. For information about how to use the VAX LISP debugger, see Chapter 4. Format DEBUG Return Value Returns NIL. You can cause the debugger to return (see Chapter 4). other values Example 0 Lisp> (DEBUG) Control Stack Debugger Frame #5: (DEBUG) Debug 1> Invokes the VAX LISP debugger. When you invoke the debugger, it displays an identifying message, stack frame information, and the debugger prompt. 0 0 0 19 VAX LISP/ULTRIX FUNCTION ..MACRO, AND VARIABLE DESCRIPTIONS DEBUG-CALL Function Returns a list representing the current debug frame function call.O This function is a debugging tool and takes no arguments. The list returned by the DEBUG-CALL function can be used to access the values passed to the function in the current stack frame. Format DEBUG-CALL Return Value A list representing the current debug frame function call. is returned if this function is called outside the debugger. Example Lisp> (SETF THIS-STRING "abed") "abed" Lisp> (FUNCTION-Y THIS-STRING 4) .... Error in function FUNCTION-Y Frame #4 (FUNCTION-Y "abed" 4) Debug 1> (SETF STRING (SECOND (DEBUG~CALL))) "abed" Debug 1> (EQ "abed" STRING) NIL Debug 1> (EQ THIS-STRING STRING) NIL 0 0 T In this case, the function in the current stack frame is FUNCTION-Y. The call to (DEBUG-CALL) returns the list (FUNCTION-Y "abed 4). The fo~m (SECOND (DEBUG-CALL)) evaluates "abed", the first argument to FUNCTION-Yin the current stack frame. Note that the string returned by the call (SECONDO (DEBUG-CALL)) is the same string passed to the function FUNCTION-Y. See the description of the TRACE macro for another example of the use of the DEBUG-CALL function. 0 20 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS () *DEBUG-PRINT-LENGTH* .Variable Controls the output that the debugger, stepper, and tracer facilities display. This variable controls the number of objects these facilities can display at each level of a nested data object. The variable's value can be either a positive integer or NIL. If the value is a positive integer, the integer indicates the ~umber of objects at each level of a nested object to be displayed. If the value is NIL, no limit is on the number of objects that can be displayed. The default value is NIL. The value of this variable might cause the printer to truncate output. An ellipsis ( ... ) indicates truncation. This variable is similar to the *PRINT-LENGTH* variable COMMON LISP: The Language. Q described in Example Lisp> (SETF ALPHABET '(ABC DEF G HI J K)) (ABC DEF G HI J K) Lisp> (SETF *DEBUG-PRINT-LENGTH* 5) 5 Lisp> (+ 2 ALPHABET) 0 Fatal error in function+ (signaled with ERROR). Argument must be a number: (ABC DEF G HI J K) Control Stack Debugger Frame #5: (+ 2 (ABC DE ... )) Debug 1> (SETF *DEBUG-PRINT-LENGTH* 3) 3 Debug 1> WHERE Frame #5: (+ 2 (ABC ... )) 0 0 • The call to the SETF macro sets the symbol ALPHABET to a of single-letter symbols. e The value of the *DEBUG-PRINT-LENGTH* variable is set to 5. e The illegal call to the plus sign(+) function causes the LISP system to invoke the debugger. The debugger displays only five elements of the list that is the value of the symbol ALPHABET the first time it displays the stack frame numbered 5. e The call to the SETF macro within the debugger sets the of the *DEBUG-PRINT-LENGTH* variable to 3. • The debugger displays three elements of the change the value of the variable. 21 list, after list value you VAX LISP/ULTRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS *DEBUG-PRINT-LEVEL* Variable Controls the output that the debugger, stepper, and tracer facilities display. This variable controls the number of levels of a nested object these facilities can display. The variable's value can be either a positive integer or NIL. If the value is a positive integer, the integer indicates the number of levels of a nested objett to be displayed. If the value is NIL, no limit is on the number of levels that can be displayed. The default value is NIL. O The value of this variable might cause the printer to truncate output. A number sign(#) indicates truncation. This variable is similar to the *PRINT-LEVEL* COMMON LISP: The Language. variable described in Q Example Lisp> (A (B Lisp> 3 Lisp> (SETF ALPHABET '(A (B (C (D (E)))))) (C (D (E))))) (SETF *DEBUG-PRINT-LEVEL* 3) (+ 2 ALPHABET) Fatal error in function+ (signaled with ERROR). Argument must be a number: (A (B (C (D (E))))) 0 Control Stack Debugger Frame #5: (+ 2 (A (B #))) Debug 1> (SETF *DEBUG-PRINT-LEVEL* NIL) NIL Debug 1> WHERE Frame #5: (+ 2 (A (B (C (D (E)))))) sets the symbol ALPHABET to • The call to the SETF macro nested list. • The value of tpe *DEBUG-PRINT-LEVEL* variable is set to 3. • The illegal call to the plus sign(+) function causes the LISP system to invoke the debugger. The debugger displays only three levels of the nested list (that is the value of the symbol ALPHABET) the first time it displays the stack frame numbered 5. • The call to the SETF macro within the debugger sets the of the *DEBUG-PRINT-LEVEL* variable to NIL. value The debugger displays all the levels of the nested list, after you change the value of the variable. 22 VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS DEFAULT-DIRECTORY Function 0 Returns a pathname with the host and directory fields filled with values of the current default directory. the The DEFAULT-DIRECTORY function is similar to the ULTRIX shell command pwd. For information about the pwd command, see the'ULTRIX-32 Programmer's Guide. You can change the default directory by using the SETF macro. Setting your default directory with this macro also resets the value of the *DEFAULT-PATHNAME-DEFAULTS* variable. Performing this operation is similar to using the ULTRIX shell command ed. See Chapter 6 and COMMON LISP: The Language for information about pathnames and the *DEFAULT-PATHNAME-DEFAULTS* variable. 0 Note that the directory must exist for succeed. the change of directory to Format DEFAULT-DIRECTORY Return Value 0 The pathname that refers to the default directory. Examples 1. 0 Lisp> (DEFAULT-DIRECTORY) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY 11 /usr/users/smith" :NAME NIL :TYPE NIL :VERSION NIL) Lisp> (SETF (DEFAULT-DIRECTORY) "./tests/") "./tests/" Lisp> (DEFAULT-DIRECTORY) #S(PATHNAME :HOST "miami:" :DEVICE NIL :DIRECTORY 11 /usr/users/smith/tests" :NAME NIL :TYPE NIL :VERSION NIL) • The first call to the DEFAULT-DIRECTORY function returns the pathname that points to the default directory. e The call. to the SETF macro changes the default directory to /usr/users/smith/tests. A slash is included in the string to indicate that tests is a subdirectory rather than a file. • The second call to the DEFAULT-DIRECTORY function verifies the directory change. 0 23 VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS DEFAULT-DIRECTORY Function (cont.) 2. 0 Lisp> (DEFAULT-DIRECTORY) #S(PATHNAME :HOST "rniami:" :DEVICE NIL :DIRECTORY "/usr/users/smith/tests" :NAME NIL :TYPE NIL :VERSION NIL) Lisp> *DEFAULT-PATHNAME-DEFAULTS* ' #S(PATHNAME :HOST "rniami:" :DEVICE NIL :DIRECTORY "/usr/users/srnith/tests" :NAME NIL :TYPE NIL :VERSION NIL) Lisp> (NAMESTRING (DEFAULT-DIRECTORY)) 11 /usr/users/srnith/tests/ 11 Lisp> (SETF (DEFAULT-DIRECTORY) " .. /") II • • I" Lisp> (NAMESTRING (DEFAULT-DIRECTORY)) 11 /usr/users/smith/ 11 Lisp> (NAMESTRING *DEFAULT-PATHNAME-DEFAULTS*) 11 /usr/users/smith/" 0 • The first call to the DEFAULT-DIRECTORY function returns the pathname that points to the default directory • • The call to the *DEFAULT-PATHNAME-DEFAULTS* variable shows that its value is the same as the value returned by the DEFAULT-DIRECTORY function. • The call to the NAMESTRING function returns as a string. • The call to the SETF macro changes the to /usr/users/smith: the pa thnarne default directory Q. last two calls to the NAMESTRING function show that • The the return values of the DEFAULT-DIRECTORY function and the *DEFAULT-PATHNAME-DEFAULTS* same. variable are still the 0 0 24 VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS .o DEFINE-FORMAT-DIRECTIVE Macro Defines a directive for use in a FORMAT control string, supplementing directives supplied with VAX LISP. In a call to FORMAT, specify a directive you have defined in the form: -;name/ You can also specify colon and at-sign modifiers: -@ :/name/ You can also specify one or more parameters: -n,n/name/ 0 DEFINE-FORMAT-DIRECTIVE provides means for the body of the format directive you define to receive the value of parameters and the presence or absence of colon and at-sign modifiers. See Section 5.4 for more information about defining format directives. Format DEFINE-FORMAT-DIRECTIVE name (arg stream colon-p atsign-p &OPTIONAL {parameter1 default) (parameter2 default) ... ) &BODY forms 0 Arguments name The name of the FORMAT directive defined with this macro. 0 NOTE If you do not specify a package with name when you define the directive, name is placed in the current package. If you do not specify a package when you refer to the directive, the FORMAT directive looks in the USER package for the directive definition. arg 0 A symbol that is bound to the argument to directive. 25 be formatted by the VAX LISP/ULTRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS DEFINE-FORMAT-DIRECTIVE Macro (cont.) 0 stream A symbol that is bound to the stream to which the printing is be done. to colon-p A symbol that is bound to Tor NIL, indicating was specified in the directive. whether a colon atsign-p A symbol that is bound to Tor NIL, indicating whether an at-sign was specified in the directive. 0 parameters There must be one optional argument for each prefix parameter that is allowed in the directive. A symbol supplied as a parameter argument will be bound to the corresponding prefix parameter if it was specified in the directive. Otherwise, the default value will be used, as with all optional arguments. forms Forms which are evaluated to print argument to stream. The can begin with a declaration and/or documentation string. body 0 Return Value The name of the FORMAT directive that has been defined. Example Lisp> (DEFINE-FORMAT-DIRECTIVE EVALUATION-ERROR (SYMBOL STREAM COLON-P ATSIGN-P &OPTIONAL (SEVERITY 0)) (DECLARE (IGNORE ATSIGN-P)) (FRESH-LINE STREAM) (PRINC (CASE SEVERITY (0 "Warning: ") (1 "Error:")' (2 "Severe Error: ")) STREAM) (FORMAT STREAM "-:!The symbol -s -:_does not have an integer value.-%Its value is: -=_-s-." SYMBOL (SYMBOL-VALUE SYMBOL)) (WHEN COLON-P (WRITE-CHAR #\BELL STREAM))) EVALUATION-ERROR 26 0 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS 0 DEFINE-FORMAT-DIRECTIVE Macro (cont.) Lisp> (SETF PROCESS NIL) NIL Lisp> (FORMAT T "-1:/EVALUATION-ERROR/" 'PROCESS) Error: The symbol PROCESS does not have an integer value. Its value is: NIL , <BEEP> • This example shows the definition of a FORMAT directive, a use of the directive, and the printed output. • The prefix parameter 1 in "-1:/EVALUATION-ERROR/" indicates the severity of the error being signaled. The colon produces a beep on the terminal. 0 0 0 0 27 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS DEFINE-GENERALIZED-PRINT-FUNCTION Macro Defines a function that specifies how any object is to be prett() printed, regardless of its form. Generalized print functions are effective only when they are enabled (globally or locally) and when pretty printing is enabled. You can enable a generalized print function globally, using GENERALIZED-PRINT-FUNCTION-ENABLEb-P. Or, you can enable it locally, using WITH-GENERALIZED-PRINT-FUNCTION. An enabled generalized print function is used if its predicate evaluates to a non-NIL value. See Section functions. 5.6 for more information about generalized print Format DEFINE-GENERALIZED-PRINT-FUNCTION name (object stream) predicate &BODY forms O Arguments name The name of the generalized print function being defined. object 0 A symbol that is bound to the object to be printed. stream A symbol that is bound to the stream to which sent. output is to be predicate A form. When the generalized print function has been enabledo (globally or locally), the system evaluates this form for every object to be pretty printed. If the form evaluates to non-NIL on the object to be pretty printed, the generalized print function will be used. forms Forms that print object to stream, or take any other action. These forms can refer to the object and stream by means of the symbols used for object and stream. The body can begin with a declaration and/or documentation string. Return Value The name of the generalized print function that has been defined. 28 0 VAX LISP/ULTRIX FUNCTION, MACRO, ANU VAHIADLI: UC.:>vn11- 11v .....;, DEFINE-GENERALIZED-PRINT-FUNCTION Macro (cont.) Example 0 Lisp> (DEFINE-GENERALIZED-PRINT-FUNCTION PRINT-NIL-AS-LIST (OBJECT STREAM) (NULL OBJECT) ( PR INC II ( ) II STREAM) ) PRINT-NIL-AS-LIST Lisp> (PRINT NIL) NIL NIL Lisp>(PPRINT NIL) NIL Lisp> (WITH-GENERALIZED-PRINT-FUNCTION 'PRINT-NIL-AS-LIST (PRINT NIL) (PPRINT NIL)) NIL ( ) Lisp> (SETF (GENERALIZED-PRINT-FUNCTION-ENABLED-P 'PRINT-NIL-AS-LIST) T) T Lisp> (PPRINT NIL) ( 0 0 ) • The first PRINT call prints NIL, because the generalized print function PRINT-NIL-AS-LIST is.not enabled • • The first PPRINT call prints NIL, because PRINT-NIL-AS-LIST is still not enabled. • The second PRINT call prints NIL, because pretty not enabled. printing is second PPRINT call prints , because the generalized • The print function is enabled locally. ( ) third PPRINT call prints , because the generalized • The print function is enabled globally. ( 0 29 ) VAX LISP/ULTRIX FUNCTION, MACRO, AND- VARIABLE DESCRIPTIONS DEFINE-LIST-PRINT-FUNCTION Macro Defines and enables a function to print lists that begin with specified element. Defined functions are effective only when pretty printing is enabled. The system checks the first element of each list to be printed for a match. If the first element of a list matches the name of a list-print function, the list is printed according to the format you have defined. See Section 5.5 for more information about list-print.functions. Format DEFINE-LIST-PRINT-FUNCTION symbol (list stream) &BODY forms Arguments 0 symbol The first element of any format. list to be printed in the defined list A symbol that is bound to the list to be printed. 0 stream A symbol that is bound to the stream on which printing is done. to be forms Forms to be evaluated. The forms refer to the list to be printed and the stream by means of the symbols you supply for list ando stream. The body can include declarations. Calls to FORMAT may also be included. Return Value The name of the list-print function that has been_defined. Example Lisp> (DEFINE-LIST-PRINT-FUNCTION MY-SETQ (LIST STREAM) (FORMAT STREAM .. -1 !'"w"'"' - : r @Cw"'"' - : _-w"' ... - %- 1- • " LIST)) MY-SETQ Lisp> (SETF BASE '(MY-SETQ HI 3 BYE 4)) (MY-SETQ HI 3 BYE 4) 30 0 VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS 0 0 DEFINE-LIST-PRINT-FUNCTION Macro (cont.) Lisp> (PRINT BASE) (MY-SETQ HI 3 BYE 4) (MY-SETQ HI 3 BYE 4) Lisp> (PPRINT BASE) (MY-SETQ HI 3 BYE 4) e The list-print function MY-SETQ is defined. • The call to PRINT does not use the list-print function MY-SETQ to print the value of BASE, because pretty-printing is not enabled. • The call to PPRINT does use the list-print function MY-SETQ to print the value of BASE. 0 0 0 31 VAX LISP/UL TRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS DELETE-PACKAGE Function Uninterns all the symbols interned in the package, unuses all t h e o packages the function uses, and deletes the package. An error is signaled if the package is used by iny other package. Format DELETE-PACKAGE package Argument package A package, or a string or symbol naming a package 0 Return Value T. Example Lisp> (DELETE-PACKAGE "TEST-PACKAGE") T Lisp> (FIND-PACKAGE "TEST-PACKAGE") NIL 0 0 0 32 VAX LISP/ULTRIX FUNCTION 1 MACRO! AND VARIABLE DESCRIPTIONS DESCRIBE Function 0 object Displays information about a specified object. If the specified has a documentation string, this function displays the string in addition to the other information the function displays. The type of information the function displays depends on the t¥pe of the object. For example, if a symbol is specified, the function displays the symbol's value, definition, properties, and other types of information. If a floating-point number is specified, the number's internal representation is displayed in a way that is useful for tracking such things as roundoff errors. Format DESCRIBE object 0 Argument object The object about which information is to be displayed. Return Value No value. Q Examples 1. Lisp> (DESCRIBE 'C) It is the symbol C Package: USER Value: unbound Function: undefined 0 2. Lisp> (DESCRIBE 'FACTORIAL) It is the symbol FACTORIAL Package: USER Value: unbound Function: a compiled-function FACTORIAL n 3. Lisp> (DESCRIBE PI) It is the long-float 3.1415926535897932384626433832795LO Sign: + Exponent: 2 (radix 2) ~ Significand: 0.78539816339744830961566084581988LO 0 33 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTtONS DESCRIBE Function (cont.) 4. Lisp> (DESCRIBE '#(1 2 3 4 5)) It is a simple-vector Dimensions: ( 5) Element type: t · Adjustable: no Fill Pointer: no Displaced: no 0 Displays information about the simple-vector #(1 2 3 4 5). 0 0 0 0 34 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS 0 DIRECTORY Function Converts its argument to a pathname and returns a pathnames for the files matching the specification. function is similar to the ULTRIX ls command. list of the The DIRECTORY Format DIRECTORY pathname Argument pathname 0 The pathname, namestring, stream, or symbol for which the list of file system pathnames is to be returned. In VAX LISP/ULTRIX, this argument is merged with the following default file specification: host::directory/* The host and directory values *DEFAULT-PATHNAME-DEFAULTS* variable. 0 are supplied by the Specifying just a directory is equivalent to specifying a directory with wild cards (*) in the name field of th~ argument. For example, the following two e~pressions are equivalent: (DIRECTORY "MYDIRECTORY/") (DIRECTORY "MYDIRECTORY/*") Both expressions return a list of pathnames files in the directory mydirectory. O that represent the The following equivalent expressions return the list of pathnames for files in your de~ault directory: (DIRECTORY"") (DIRECTORY (DEFAULT-DIRECTORY)) Return Value A list of pathnames, if the specified pathname NIL, if the pathname is not matched. 0 35 is matched, and VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS DIRECTORY Function (cont.) 0 Example Lisp> (DEFUN MY-DIRECTORY (&OPTIONAL (FILENAME"")) (LET ((PATHNAME (PATHNAME FILENAME)) (DIRECTORY (DIRECTORY FILENAME))) (COND ((NULL DIRECTORY) (FORMAT T "-%No files match -A.-%" (NAMESTRING FILENAME))) (T (FORMAT T "-%The following -:[files are-;file is-] in the directory -A" (EQUAL (LENGTH DIRECTORY) 1) (PATHNAME-DIRECTORY (NTH O DIRECTORY))) (DOLIST (DIRECTORY) ( FORMAT T .. - &-2T- A" ( FILE-NAMESTRING X))) (TERPRI))) (VALUES))) MY-DIRECTORY Lisp> (MY-DIRECTORY) The following files are in the 'directory /usr/usrs/smith/tests testS.drb testl.lsp example.txt test3.lsp test6.lsp Lisp> (MY-DIRECTORY "*.lsp") The following files are iri the directory /usr/usrs/smith/tests testl.lsp test3.lsp test6.lsp • The call to the DEFUN macro defines a function that formats the output of the DIRECTORY function, making the output more readable. The function is defined such that it accepts an optional argument and does not return a value. • The first call to the function MY-DIRECTORY Bhows how the function formats the directory output when an argument is not specified. • The second call to the function MY-DIRECTORY includes argument; the output includes only the files of type lsp. 0 0 Q an 0 36 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS DRIBBLE Function 0 Echoes the input and output of an interactive LISP session to a specified file, enabling you to save a record of what you do during the session in the form of a file. When you want to stop the DRIBBLE function from echoing 'input and output to the pathname, close the file by calling the DRIBBLE function without an argument. In VAX LISP/ULTRIX, there is one restriction on the use of the DRIBBLE function: you cannot nest calls to the DRIBBLE function. Format DRIBBLE &OPTIONAL pathname Q Argument pathname The pathname to which the input and output of the LISP session is to be sent. Return Value 0 If an argument is specified with the function, no value is returned and dribbling is turned on. If debugging is on and the function is called with no arguments, then T is returned and dribbling is turned off. If dribbling is off and is called without an argument, NIL is returned. Examples 0 1. Lisp> (DRIBBLE "newfunction.lsp") Dribbling to /usr/users/smith/newfunction.lsp Lisp> Creates a dribble file named newfunction.lsp. The LISP system sends input and output to the file until you call the DRIBBLE function again (without an argument) or exit LISP. 2. Lisp> (DRIBBLE) T Closes the dribble file that was previously opened. 0 37 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *ERROR-ACTION* Variable Determines the action the VAX LISP error handler is to take when an error occurs. The value of this variable can be the :EXIT or the :DEBUG keyword. If the value is :EXIT, the error handler causes the LISP system to exit; if the value is :DEBUG, the handler invokes the VAX LISP debugger. The default value is :DEBUG for interaclive LISP sessions; the default value is :EXIT otherwise. 0 In addition to setting this variable within a LISP form, you can also set it on LISP initialization with the -v "ERROR_ACTION=value" option (see Chapter 2). Example Lisp> (CAR 'A) 0 Fatal error in function CAR (signaled with ERROR). Argument must be a list: A. Control Stack Debugger Frame #5: (CAR A) Debug 1> QUIT Lisp> (SETF *ERROR-ACTION* :EXIT) :EXIT Lisp> (CAR 'A) 0 Fatal error in function CAR (signaled with ERROR). Argument must be a list: A. % • When the first error occurs, the LISP system invokes the VAX LISP debugger because the value of the *ERROR-ACTION* variable' is :DEBUG (the default). • The call to the SETF macro sets the value of the :EXIT. • The second time the error occurs, the LISP control returns to ULTRIX. system variable to exits and Q 0 38 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS EXIT Function ()Causes the LISP system to exit and to return control to ULTRIX. You can pass the status of the LISP system to the shell when you exit the LISP system by specifying an optional argument. Whe~ the LISP system exits, the argument's value is passed to ULTRIX. Format EXIT &OPTIONAL status Argument status A fixnum or a keyword that indicates the status of the LISP syste·m that is to be returned to ULTRIX when the LISP system exits. The keywords you can specify and the types of status they return are the following: () :ERROR :SUCCESS Error status (-1) Success status (0) Return Value () No value. Examples 1. Lisp> (EXIT) % Exits the LISP system. ()_ 2~ Lisp> (EXIT :ERROR) Exits the LISP system. LISP has returned -1. When control returns to () 39 ULTRIX, VAX - VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS Format Directives Provided with VAX LISP VAX LISP provides eight directives for the FORMAT function, inO addition to those described in COMMON LISP: The Language. Table 1 lists and describes these directives. See Section 5.3 for more information about using these directives. • Table 1: Format Directives Provided with VAX LISP Directive Effect -w Prints the corresponding argument under direction of the current print variable values. The argument for -w can be any LISP object. This directive takes a colon modifier and four prefix parameters. Use the colon modifier (-:W) when you want to set *PRINT-PRETTY* and *PRINT-ESCAPE* to T, and set *PRINT-LENGTH*, *PRINT-LEVEL*, and *PRINT-LINES* to NIL. The prefix parameters parameters are identical directive. 0 specify padding. These to those used with the -A 0 -mincol,colinc,minpad,padcharw mincol specifies the minimum width of the printed representation of the object. FORMAT inserts padding characters on the right, until the width is at least mincol columns. Use the at-sign with minpad to insert the padding characters on the left instead. The default for mincol is 0. colinc specifies an increment: the number of padding characters to be inserted at one time until the width is at least mincol columns. The default is 1. minpad specifies the m1n1mum number of characters to be inserted. The default is 0. padchar, preceded by a padding character. character. single quote, The default padding specifies the is the space Begins a logical block. A logical block ·is a hierarchical grouping of FORMAT directives treated as a unit. FORMAT must be processing a logical block with *PRINT-PRETTY* true to enable pretty printing .. Directives inside a logical block refer to elements of a single list taken from the argument list to FORMAT. 40 Q Q VAX LISP/ULTRIX FUNCTION. M/•;..;RO. AND VARIABLE DESCRIPTIONS Format Directives Provided with VAX LISP (cont.) OTable 1 (cont.) Directive Effect (If the argument supplied to the logical block is not a list, then the logical block is skipped and the argument is printed as if with -w.) The logical block directive takes colon and at-sign modifiers. When the directive is modified by a colon (-:!), the directive sets *PRINT-PRETTY* and *PRINT-ESCAPE* to T and *PRINT-LENGTH*, *PRINT-LEVEL*, and *PRINT-LINES* to NIL. 0 When the directive is modified by an at-sign (-@!), the directives within the logical block take successive arguments from the FORMAT argument list. The logical block uses up all the arguments, not just a single list argument. Arguments not needed by the logical block are used up as well, so that they are not available for subsequent directives. o_ Specify a parameter of 1 (-1!) to enclose the output in parentheses. 0 Ends a logical block. If modified by an at-sign(-@!), the directive inserts a new line if needed after every blank space character. Specifies a multiline mode new line and marks a logical block section. This directive takes colon and at-sign modifiers. When modified by a colon (-:_), the directive starts a new line if not enough space is on the line to print the next logical block section. When modified by an at-sign(-@_), the directive starts a new line if miser mode is enabled. The directive and its variants are effective only when used within a logical block with pretty printing enabled. 0 Sets indentation for subsequent lines to n columns after the beginning of the logical block or after the prefix. When modified by a colon (-n:I), the directive causes FORMAT to indent subsequent lines n spaces from the column corresponding to the position of the directive. The -nI directive and the -n:I variant are effective only when used within a logical block with pretty printing enabled. 41 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS Format Directives Provided with VAX LISP (cont.) Table 1 (cont.) Directive Effect -n/FILL/ Prints the elements of a list with as many el~ments as possible on each line. If n is 1, FORMAT encloses the printed list in parentheses. If pretty printing is not enabled, the directive causes FORMAT to print the output on a single line. -n/LINEAR/ If the elements of the list to be printed cannot be printed on a single line, this directive prints each element on a separate line. If n is 1, FORMAT encloses the printed list in parentheses. If pretty printing is not enabled, this directive causes FORMAT to print the output on a single line. -n,rn/TABULAR/ 0 Q Prints the list in tabular form. If n is 1, FORMAT encloses the list in parentheses; rn specifies the column spacing. If pretty printing is not enabled, this directive causes FORMAT to print the output on a single line. 0 0 0 42 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS GC Function ( ) Invokes the garbage collector. The LISP system initiates garbage collection during normal system use whenever necessary. You cannot disable this process. However, the GC function enables you to initiate garbage collection during system interaction. • NOTE The LISP system does not use the GC function to initiate garbage collections. Therefore, redefining the GC function does not prevent garbage collection. () You might want to use the GC function to invoke the garbage collector just before a time-critical part of a LISP program. Using the GC function this way reduces the possibility of the LISP system initiating a garbage collection when a critical part of the program is executing. See Chapter 6 for a description of the garbage collector. Format GC () Return Value T, when garbage collection is completed. Example () Lisp> (GC) Starting garbage collection due ~o GC function. Finished garbage collection due to GC function. T Invokes the garbage collector. Whether the messages are printed when a garbage collection occurs depends on the value of the *GC-VERBOSE* variable. () 43 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS * GC-VERBOSE * Variable A variable whose value is used as a flag to determine whether the LISP system is to display messages when a garbage collection occurs. If the flag is NIL, the system displays messages. If the flag is not NIL, the system displays a message before and after ,a garbage collection occurs. The default value is T. The messages the LISP system displays are controlled by the *PRE-GC-MESSAGE* and *POST-GC-MESSAGE* variables. VAX O LISP For more information on garbage collector messages, see Chapter 6. Example Lisp> *GC-VERBOSE* T 0 Lisp> (GC) ; Starting garbage collection due to GC function. ; Finished garbage collection due to GC function. T Lisp> (SETF *GC-VERBOSE* NIL) NIL Lisp> (GC) T • The first evaluation of the *GC-VERBOSE* variable returns the default value T, which indicates that the LISP system will display a message before and after a garbage collection occurs (depending on the values of the *PRE-GC-MESSAGE* and *POST-GC-MESSAGE* variables). Q call to the GC function shows the default messages the • The system displays when a garbage collection occurs and the variable's value is T. The call to the SETF macro sets the value of the variable • NIL. • The second call to the GC function shows that the system not display messages when the variable's value is NIL. does 0 44 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS GENERALIZED-PRINT-FUNCTION-ENABLED-P Function Used to globally enable a generalized print function or test whether a generalized print function is enabled. GENERALIZED-PRINT-FUNCTIONENABLED-P is a predicate, and it can be used as a place form with SETF. See Chapter 5 for functions. more information about using ' generalized print Format GENERALIZED-PRINT-FUNCTION-ENABLED-P name Argument 0 name A symbol identifying the generalized print function to be enabled or tested. Return Value Tor NIL. 0 0 Example Lisp> (GENERALIZED-PRINT-FUNCTION-ENABLED-P 'PRINT-NIL-AS-LIST) NIL Lisp> (DEFINE-GENERALIZED-PRINT-FUNCTION PRINT-NIL-AS-LIST (OBJECT STREAM) (NULL OBJECT) ( PRINC II ( ) II STREAM) ) PRINT-NIL-AS-LIST Lisp> (SETF (GENERALIZED PRINT-FUNCTION-ENABLED-P 'PRINT-NIL-AS-LIST) T) T Lisp> (PPRINT NIL) ( 0 ) e The first use of the GENERALIZED-PRINT-FUNCTION-ENABLED-P function returns NIL, because no generalized print function named PRINT-NIL-AS-LIST has been defined . • The call to DEFINE-GENERALIZED-PRINT-FUNCTION generalized print function PRINT-NIL-AS-LIST. • The call to SETF globally function PRINT-NIL-AS-LIST. • The PPRINT call prints ( ), because the generaljzed print function is enabled globally and pretty printing is enabled. 45 enables the defines generalized the print VAX LISP/ULTRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS GET-GC-REAL-TIME Function Lets you inspect the elapsed time used by the garbage collector during program execution. This function is useful for tuning programs. 0 The function measures its value in terms ,of the INTERNAL-TIME-UNITS-PER-SECOND constant. This value is cumulative. It includes the elapsed time used for all the garbage collections that have occurred. A description of the INTERNAL-TIME-UNITS-PER-SECOND constant is provided in COMMON LISP: The Language. When a suspended system is resumed, the elapsed time is set to 0. For more information on the garbage collector, see Chapter 7. Format 0 GET-GC-REAL-TIME Return Value The real time that has been used by the garbage collector. Examples 1. Lisp> (GET-GC-REAL-TIME) 3485700000 Lisp> (GC) ; Starting garbage collection due to GC function. ; Finished garbage collectiori due to· GC function. 0 T Lisp> (GET-GC-REAL-TIME) 401210000 e The first call to the -GET-GC-REAL~TIME function the real time used by the garbage collector. • The call to the GC function invokes a garbage collection. • The second call to the GET-GC-REAL-TIME function returns the updated real time that has been used by the garbage collector. 46 returns 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE- DESCRIPTIONS GET-GC-REAL-TIME Funct.ion (cont.) 0 0 . 2. Lisp> (DEFMACRO 'GC-ELAPSED-TIME (FORM) '(LET* ((START-GC (GET-GC-REAL-TIME)) (VALUE ,FORM) · (END-GC (GET-GC-REAL-TIME))) (FORMAT *TRACE-OUTPUT* "-%GC elapsed time: -o seconds-%" (TRUNCATE (- END-GC START-GC) INTERNAL-TIME-UNITS-PER-SECOND)))) GC-ELAPSED-TIME Lisp> (GC-ELAPSED-TIME (SUSPEND "myfile.sus")) Starting garbage collection due to GC function. Finished garbage collection due to GC function. Starting garbage collection due to SUSPEND function. Starting garbage collection due to SUSPEND function. GC elapsed time: 54 seconds NIL The call to the DEFMACRO macro defines a macro named • GC-ELAPSED-TIME, which evaluates a form and displays the amount of elapsed time that was used collector during a form's evaluation. 0 • by the garbage The call to the GC-ELAPSED-TIME function displays the amount of elapsed time the garbage collector used when the LISP system evaluated the.form (SUSPEND "myfile.sus"). 0 0 47 VAX LISP/ULTRIX ~UNCTION, MACRO, AND VARIABLE DESCRIPTIONS GET-GC-RUN-TIME Function Lets you inspect the CPU time used by the garbage collector during program execution. This function is useful for tuning programs. 0 The function measures its value in terms of the INTERNAL-TIME-UNITS-PER-SECOND constant. This value is c~mulative. It includes the CPU time used for all the garbage collections that have occurred. A description of the INTERNAL-TIME-UNITS-PER-SECOND constant is provided in COMMON LISP: The Language. When a suspended system is resumed, the CPU time is set to 0. For more information on the garbage collector, see Chapter 6. Format 0 GET-GC-RUN-TIME Return Value The CPU time that has been used by the garbage collector. Examples 1. Lisp> (GET-GC-RUN-TIME) 0 Lisp> (GC) ; Starting garbage collection due to GC function. ; Finished garbage collection due to GC function. 0 T Lisp> (GET-GC-RUN-TIME) 13400000 first call to the GET-GC-RUN-TIME function returns the • The CPU time used by the garbage collector. Q • The call to the GC function invokes a garbage collection. second call to the GET-GC-RUN-TIME function returns • The the updated CPU time that has been used by the garbage collector. 0 48 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS GET-GC-RUN-TIME Functipn (cont.) 0 0 0 2. Lisp> (DEFMACRO GC-CPU-TIME (FORM) '(LET* ((START-GC (GET-GC-RUN-TIME)) (VALUE ,FORM) (END-GC (GET-GC-RUN-TIME))) (FORMAT *TRACE-OUTPUT* "-%GC CPU time: -o seconds-%" (TRUNCATE (- END-GC START-GC) INTERNAL-TIME-UNITS-PER-SECOND))) GC-CPU-TIME Lisp> (GC-CPU-TIME (SUSPEND "myfile.sus")) ; Starting garbage collection due to GC function. ; Finished garbage collection due to GC function. ; Starting garbage collection due to SUSPEND function. ; Starting garbage collection due to SUSPEND function. GC CPU time: 10 seconds NIL • The call to the DEFMACRO macro· defines a macro named GC-CPU-TIME, which evaluates a form and displays the amount of CPU time that was used by the garbage collector during a form's evaluation. • The call to the GC-CPU-TIME function displays the amount of CPU time the garbage collector used when the LISP system evaluated the form· (SUSPEND "myfile.sus"). 0 0 49 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS GET-INTERNAL-RUN-TIME Function Returns an integer that represents the elapsed CPU time used for the current process. The function value is measured in terms of the INTERNAL-TIME-UNITS-PER-SECOND constant. A description of the INTERNAL-TIME-UNITS-PE.R-SECOND constant is provided in COMMON LISP: The Language. • 0 Format GET-INTERNAL-RUN-TIME Return Value The elapsed CPU time used for the current process. Example 0 Lisp> (DEFMACRO MY-TIME (FORM) '(LET* ((START-REAL-TIME (GET-INTERNAL-REAL-TIME)) (START-RUN-TIME (GET-INTERNAL-RUN-TIME)) (VALUE ,FORM) (END-RUN-TIME (GET-INTERNAL-RUN-TIME)) (END-REAL-TIME (GET-INTERNAL-REAL-TIME))) (FORMAT *TRACE-OUTPUT* "-&Run Time: -,2F sec., Real.Time: -,2F sec.-%" · (/ (- END-RUN-TIME START-RUN-TIME) INTERNAL-TIME-UNITS-PER-SECOND) (/ (- END-REAL-TIME START-REAL-TIME) INTERNAL-TIME-UNITS-PER-SECOND)) VALUE)) MY-TIME Defines a macro that displays evaluation of a specified form. timing information about 0 the 0 0 50 · VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS O Returns information about the function that is bound to a control GET-KEYBOARD-FUNCTION Function character. Format GET-KEYBOARD-FUNCTION control-character Argument control-character The control character to which a function is bound. Return Value 0 0 Three values: 1. The function that is bound to the control character. 2~ The function's argument list. 3. The function's interrupt level. If a function is not bound to the specified control the function returns NIL for all three values. character, Examples 1. . Lisp> (BIND-KEYBOARD-FUNCTION #\FS #'BREAK) T Lisp> (GET-KEYBOARD-FUNCTION #\FS) #<Compiled Function BREAK #x261510> NIL 0 1 2. 0 e The call to the BIND-KEYBOARD-FUNCTION <CTRL/\> to the BREAK function. function binds - e The call to the GET-KEYBOARD-FUNCTION function returns the function to which <CTRL/\> is bound; the function's argument list, which is NIL; and the function's interrupt level, which is 1. Lisp> (GET-KEYBOARD-FUNCTION #\AZ) NIL NIL; NIL All three values returned are NIL, because bound to a function. 51 <CTRL/Z> is not VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS HASH-TABLE-REHASH-SIZE Function Returns the rehash size of a hash table. The rehash size indicates how much a hash table is to increase when it is full. You specify that value when you create a hash table with the MAKE-HASH-TABLE function. For information on hash tables, see COMMON LISP: The O • Language. Format HASH-TABLE-REHASH-SIZE hash-table Argument hash-table The name of the hash table whose rehash size is to be returned. Return Value An integer greater than O or a floating-point number greater than 1. If an integer is returned, the value indicates the number of entries that are to be added to the table. If a floating-point number is returned, the value indicates the ratio of the new size to the old size. Example Lisp> (SETF *PRINT-ARRAY* NIL) NIL Lisp> (SETF TABLE-1 (MAKE-HASH-TABLE :TEST #'EQUAL :SIZE 200 :REHASH-SIZE 1.5 :REHASH-THRESHOLD .95)) #<Hash Table #x503BA8> Lisp> (HASH-TABLE-REHASH-SIZE TABLE-1) 1.5 sets the value of O 0 • The first call to the SETF macro *PRINT-ARRAY* variable to NIL. • The second call to the SETF macro sets TABLE-1 to the hash table created by the call to the MAKE-HASH-TABLE function. • The call to the HASH-TABLE-REHASH-SIZE function rehash size of the hash table, TABLE-1. returns 0 the the 0 52 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS HASH-TABLE-REHASH-THRESHOLD Function 0 Returns the rehash threshold for a hash table. The rehash threshold indicates how full a hash table can get before its size has to be increased. You specify that value when you create a hash table with the MAKE-HASH-TABLE function. For information on hash tables, see COMMON LISP: The Language. I Format HASH-TABLE-REHASH-THRESHOLD hash-table Argument hash-table 0 The hash table whose rehash threshold is to be returned. Return Value An integer greater than O and less than hash table's rehash or a floating-point number greater than O and less than 1. size Example 0 Lisp> (SETF *PRINT-ARRAY* NIL) NIL Lisp> (SETF TABLE-1 (MAKE-HASH-TABLE :TEST #'EQUAL :SIZE 200 :REHASH-SIZE 1.5 :REHASH-THRESHOLD .95)) #<Hash Table #x503BA8> Lisp> (HASH-TABLE-REHASH-THRESHOLD TABLE-1) 0.95 0 • The first call to the SETF macro *PRINT-ARRAY* variable to NIL. • The second call to the SETF macro sets TABLE-! to the hash table created by the call to the MAKE-HASH-TABLE function. e The call to the HASH-TABLE-REHASH-THRESHOLD function the rehash threshold of the hash table, TABLE-1. 0 53 sets the value of the returns VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCHIPTIONS HASH-TABLE-SIZE Function Returns the current size of a hash table. You specify that value when you create a hash table with the MAKE-HASH-TABLE function. For information on hash tables, see COMMON LISP: The Language. 0 Format HASH-TABLE-SIZE hash-table Argument hash-table The hash table whose initial size is to be returned. 0 Return Value An integer that indicates the initial size of the hash table. Example Lisp> (SETF *PRINT-ARRAY* NIL) NIL Lisp> (SETF TABLE-1 (MAKE-HASH-TABLE :TEST #'EQUAL :SIZE 200 :REHASH-SIZE 1.5 :REHASH~THRESHOLD .95)) #<Hash Table #x503BA8> Lisp> (HASH-TABLE-SIZE TABLE-1) 233 • The first call to the SETF macro *PRINT-ARRAY* variable to NIL. sets the value of 0 the second call to the SETF macro sets TABLE-1 to the hash O • The table created by the call to the -MAKE-HASH-TABLE function. • The call to the HASH-TABLE-SIZE function returns size of the hash table, TABLE-1. 54 the initial VAX LISP/ULTRIX . FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS QHASH-TABLE-TEST Function Returns a value or a symbol that indicates how a hash table's keys are compared. The value is specified when you create a hash table with the MAKE-HASH-TABLE function. For information on hash tables, see COMMON LISP: The Language. Format HASH-TABLE-TEST hash-table Argument hash-table The hash table whose test value is to be returned. QReturn Value Either a function (#'EQ, #'EQL, or #'EQUAL) or a symbol (EQ, EQL, or EQUAL). EQL is the default when creating a hash table. Example 0 0 Lisp> (SETF *PRINT-ARRAY* NIL) NIL Lisp> (SETF TABLE-1 (MAKE-HASH-TABLE :TEST #'EQUAL : SIZE 200' :REHASH-SIZE 1. 5 :REHASH-THRESHOLD .95)) #<Hash Table #x503BA8> Lisp> (HASH-TABLE-TEST TABLE-1) EQUAL • The first call to the SETF macro *PRINT-ARRAY* variable to NIL. • The second call to the SETF macro sets TABLE-1 to the hash table created by the call to the MAKE-HASH-TABLE function. • The call to the HASH-TABLE-TEST function returns the test the· ·hash table, TABLE-1. 0 55 sets the value of the for VAX LISP/ULTRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS LOAD Function Reads and evaluates the contents of a file into the LISP environment. 0 In VAX LISP, if the specified file name does not specify an explicit file type, the LOAD function locates the source file (type lsp) or fast-loading file (type fas) with the latest file write date and loads it. This ensures that the latest version of the file is loaded, whether or not the file is compiled. Format LOAD filename &KEY :IF-DOES-NOT-EXIST :PRINT :VERBOSE Arguments 0 filename The name of the file to be loaded. :IF-DOES-NOT-EXIST Specifies whether the LOAD function signals an error if the file does not exist. The value can.be Tor NIL. If you specify T, the function signals an error if the file does not exist. If you specify NIL, the function returns NIL if the file does not exist. The default value is T. O :PRINT Specifies whether the value of each form that is loaded is printed to the stream bound to the *STANDARD-OUTPUT* variable. The value can be Tor NIL. If you specify T, the value of each form in the file is printed to the stream. If you specify NIL, no action is taken. The default value is NIL. This keyword is useful for debugging. Q :VERBOSE Specifies whether the· LOAD function is to print a message in the form of a comment to the stream bound to the *STANDARD-OUTPUT* variable. The value can be Tor NIL. If you specify T, the function prints a message. The message includes information such as the name of the file that is being loaded. If you specify NIL, the function uses the value of *LOAD-VERBOSE* variable. The default is T. Return Value A value other than NIL if the load operation .is successful. 56 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS 0 LOAD Function (cont.) Example Lisp> (COMPILE-FILE "factorial") Starting compilation of file /usr/users/smith/factorial!lsp FACTORIAL compiled. Finished compilation of file /usr/users/smith/factorial.lsp O Errors, 0 Warnings 0 "/usr/users/smith/factorial.fas" Lisp> (LOAD "factorial") Loading contents of file /usr/users/smith/factorial.fas FACTORIAL Finished loading /usr/users/smith/factorial.fas T • The call to the COMPILE-FILE function produces a file named factorial.fas. • The call to the LOAD function locates the fast-loading file factorial.fas and loads the file into the LISP environment. 0 0 0 57 fast-loading VAX LISP/ULTRIX FUNCTION. MACRO, AND VARIABLE DESCRIPTIONS LONG-SITE-NAME Function If the file lispsite.txt exists in the LISP product directory, the LONG-SITE-NA~E function finds the file, reads it, and returns its content as a string that represents the physical location of the computer hardware on which the VAX LISP system is running. Otherwise, 1 the LONG-SITE-NAME function returns NIL. 0 The LISP product directory is the directory referred to by the environment variable VAXLISP if it exists, or by /usr/lib/v.axlisp if the environment variable does not exist. See the VAX LISP/ULTRIX Installation Guide for more information on the LONG-SITE-NAME function and on creating the file lispsite.txt. Format 0 LONG-SITE-NAME Return Value A string that represents the physical location of the computer hardware on which the VAX LISP system is running or NIL. Example 0 Lisp> (LONG-SITE-NAME) "Smith's Computer Company Artificial Intelligence Group 22 Plum Road Canterbury, Ohio 47190, " 0 0 58 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS O Returns a string naming the current host or NIL. MACHINE-INSTANCE Func_tion Format MACHINE-INSTANCE Return Value A string naming the computer hardware on which a VAX LISP system is running. This string is the current node name. If no host name exists, this function returns NIL. Example 0 Lisp> (MACHINE-INSTANCE) "miami" 0 0 0 59 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS MACHINE-VERSION Function The MACHINE-VERSION function displays the same shell command hostid(l) displays. information that Format MACHINE-VERSION Return Value An integer is returned, which is the host ID. Example Lisp> (MACHINE-VERSION) 332 0 0 0 0 60 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS MAKE-ARRAY Function 0 Creates and returns an array. VAX LISP has added the :ALLOCATION keyword to this COMMON LISP function. When the function is used with the :ALLOCATION keyword and the value :STATIC, the function creates a statically allocated array. ' During system usage, the garbage collector moves LISP objects. You can prevent the garbage collector from moving an object by allocating it in static space. Arrays, vectors, and strings can be statically allocated if you use the :ALLOCATION keyword and :STATIC value in a call to the MAKE-ARRAY function. Once an object is statically allocated, its virtual address does not change. Note that such objects ar never garbage collected and their space cannot be reclaimed. By default, LISP objects are allocated in dynamic space. 0 NOTE A statically allocated object maintains its memory address even if a SUSPEND/RESUME operation is performed. 0 :ALLOCATION :STATIC Calling the MAKE-ARRAY function with the keyword-value pair is useful if you are creating a large array. Preventing the garbage collector from moving the array causes the garbage collector to go faster. The MAKE-ARRAY function has a number of other keywords that can be used. See COMMON LISP: The Language for information on the other MAKE-ARRAY keywords. 0 VAX LISP creates a specialized array when the array's element type is STRING-CHAR, (SIGNED-BYTE 32), or a subtype of FLOAT or (UNSIGNED BYTE 1-29). For all other element types, VAX LISP creates a generalized array, with the element type T. For compatibility of VAX types with LISP types when calling external routines, see the tables on data conversion in the call-out chapter of the VAX LISP/ULTRIX System Access Programming Guide. Format MAKE-ARRAY dimensions &KEY :ALLOCATION other-keywords Arguments dimensions 0 A list of positive integers that are to be the dimensions of array. 61 the VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS MAKE-ARRAY Function (cont.) 0 :ALLOCATION Specifies whether the LISP object is to be statically allocated. You can specify one of the following values with the :ALLOCATION keyword: ' :DYNAMIC The LISP object is not to be statically allocated. This value is the default. :STATIC The LISP object allocated. is to be statically other-keywords See COMMON LISP: The Language. Return Value 0 The statically allocated object. Example Lisp> (DEFPARAMETER BIT-BUFFER (MAKE-ARRAY '(1000 1000) :ELEMENT-TYPE 'BIT :ALLOCATION :STATIC)) BIT-BUFFER 0 Creates a large array of bits named BIT-BUFFER, which is not intended to be removed· from the system. The :ELEMENT-TYPE keyword is one of the other keywords (described in COMMON LISP: The Language) that this function accepts. 0 62 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS 0 * MODULE-DIRECTORY* Variable A variable whose value refers to the directory containing the module that is being loaded into the LISP environment due to a call to the REQUIRE function. The value is a pathname. This variable is useful to determine the location of a lodule if additional files from the same directory must be loaded by the module. For example, consider the following contents of a file called requiredfilel.lsp: (PROVIDE "requiredfilel") (LOAD (MERGE-PATHNAMES "reguiredfile2" *MODULE-DIRECTORY*}) (DEFUN TEST ... ) 0 When you specify the preceding module with the REQUIRE function, you do not have to identify the module's directory if it is in one of the places the REQUIRE function searches (see Part II for a description of the REQUIRE function). Furthermore, using the *MODULE-DIRECTORY* variable as in this example ensures that the file requiredfile2 will be loaded from the same directory. After the module is loaded, the *MODULE-DIRECTORY* variable is rebound to NIL. 0 NOTE As this variable is bound tluring calls to the REQUIRE function, nested calls to the function cause its value to be updated appropriately. 0 0 63 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *POST-GC-MESSAGE* Variable Controls the message the LISP system displays after a garbage collection occurs. The value of this variable can be NIL, a string of message text, or the null string(""). If the value is NIL, the system displays a system message. If the value is a string, the system displays the string. If the v~riable's value is 'the null string (""), the system displays no output. The default value is NIL. O The system messages appear in the following form: Finished garbage collection due to GC function. System messages differ according to the cause of the garbage collection. If you set the *POST-GC-MESSAGE* variable, the message you establish supersedes all system messages displayed after a garbage collection, regardless of cause. Example 0 Lisp> (GC) ; Starting garbage collection due to GC function. ; Finished garbage collection due to GC function. T Lisp> (SETF *POST-GC-MESSAGE* II II ) II II 0 Lisp> (GC) ; Starting garbage collection due to GC function. T Lisp> (SETF *POST-GC-MESSAGE* "GC finished") "GC -- finished" Lisp> (GC) ; Starting garbage collection due to GC function. GC -- finished T The first call to the GC function shows the garbage collection Q • messages the LISP system displays by default. • The first call to the SETF macro sets the value *POST-GC-MESSAGE* variable to the null string(""). • The second call to the GC function shows that the system does not display a message when a garbage collection is finished when the variable's value is the null string. • The second call to the SETF variable to the string "GC macro sets finished". the value of of the the The third call to the GC function shows that the system • displays the new message when a garbage collection is finished if the variable's value is a string. 64 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS PPRINT-OEFINITION Function 0 Pretty prints to a stream the function definition of a symbol. Format PPRINT-DEFINITION symbol &OPTIONAL stream Arguments symbol The symbol whose function value is to be pretty-printed. stream 0 The stream to which default stream is variable. the the code is to be pretty-printed. The stream bound to the *STANDARD-OUTPUT* Return Value No value. Examples 0 1. 0 2. Lisp> (DEFUN FACTORIAL (N) "Returns the factorial of an.integer." (COND ((<= N 1) 1) (T (* N (FACTORIAL (- N 1)))))) FACTORIAL Lisp> (PPRINT-DEFINITION 'FACTORIAL) (DEFUN FACTORIAL (N) "Returns the factorial of an integer." (COND ((<= N 1) 1) (T (* N (FACTORIAL (- N 1)))))) • The call to the DEFUN macro defines a function called FACTORIAL, which returns the factorial of an integer . • The call to the PPRINT-DEFINITION function the function value of the symbol FACTORIAL. pretty-prints Lisp> (DEFUN RECORD-MY-STATISTICS (NAME AGE SIBLINGS MARRIED?) (UNLESS (SYMBOLP NAME) (ERROR "-s must be a symbol." NAME)) (SETF (GET NAME 'AGE) AGE (GET NAME 'NUMBER-OF-SIBLINGS) SIBLINGS (GET NAME 'IS-THIS-PERSON-MARRIED?) MARRIED?) NAME) RECORD-MY-STATISTICS 0 65 VAX LISP/UL TRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS PPRINT-DEFINITION Function (cont.) Lisp> (PPRINT-DEFINITION 'RECORD-MY-STATISTICS) (DEFUN RECORD-MY-STATISTICS (NAME AGE SIBLINGS MARRIED?) (UNLESS (SYMBOLP NAME) (ERROR n-s must be a symbol." NAME)) (SETF (GET NAME 'AGE) AGE (GET NAME 'NUMBER-OF-SIBLINGS) SIBLINGS (GET NAME 'IS-THIS-PERSON-MARRIED?) MARRIED?) NAME) • The call to the DEFUN RECORD-MY-STATISTICS. macro defines a function 0 called call to the PPRINT-DEFINITION function pretty-prints • The the function value of the symbol RECORD-MY-STATISTICS. 0 0 0 ·o 66 VAX. LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS PPRINT-PLIST Function O Pretty-prints to a stream the property list of a symbol. A property list is a list of symbol-value pairs; each symbol is associated with a value or an expression. The PPRINT-PLIST function prints the property list in a way that emphasizes the relationship between the s1mbols and their values. PPRINT-PLIST prints only the symbol-value pairs for which a symbol is accessible in the current package. (For information on packages, see COMMON LISP: The Language.) On the other hand, SYMBOL-PLIST returns all the symbol-value pairs (the entire property list) of a symbol, even those not accessible in the current package. So, the form (PPRINT-PLIST 'ME) is not equivalent to the form (PPRINT (SYMBOL-PLIST 'ME). The following example shows the differences between the two forms: 0 Lisp> (MAKE-PACKAGE 'PLANET) Lisp> (SETF (SYMBOL-PLIST 'ME) '(GIRL "SAMANTHA" BOY "DANIEL" PLANET::INHABITANT-OF "EARTH")) (GIRL "SAMANTHA" BOY "DANIEL" PLANET::INHABITANT-OF "EARTH") Lisp> (PPRINT (SYMBOL-PLIST 'ME)) (GIRL "SAMANTHA" BOY "DANIEL" PLANET::INHABITANT-OF "EARTH") Lisp> (PPRINT-PLIST 'ME) (GIRL "SAMANTHA" BOY "DANIEL") 0 The form (PPRINT (SYMBOL-PLIST 'ME)) prints the symbol-value pair PLANET::INHABITANT-OF "EARTH", but the form (PPRINT-PLIST 'ME) does not print that pair. This is because the symbol INHABITANT-OF in the package PLANET is not accessible in the current package (a symbol can be in another package but still be accessible in the current package). The symbol ME in the current package is associated with the symbol-value pair INHABITANT-OF "EARTH" in the PLANET package, but the PPRINT-PLIST function does not print that symbol-value pair because it is not accessible in the current package. Q Format PPRINT-PLIST symbol &OPTIONAL stream Arguments 1 symbol The symbol whose property list is to be pretty-printed. 0 67 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS PPRINT-PLIST Function (cont.) 0 stream The stream to which the pretty-printed output is to be sent. The default stream is the stream. bound to the *STANDARD-OUTPUT* variable. ' Return Value No value. Examples 1. Lisp> (SETF (GET 'CHILDREN 'SONS) '{DANNY GEOFFREY)) (DANNY GEOFFREY) Lisp> (SETF (GET 'CHILDREN 'DAUGHTERS) 'SAMANTHA) SAMANTHA Lisp> (PPRINT-PLIST 'CHILDREN) (DAUGHTERS SAMANTHA SONS (DANNY GEOFFREY)) 0 calls to the SETF macro give the symbol CHILDREN the • The properties SONS and DAUGHTERS. The property list of the symbol CHILDREN has two properties: DAUGHTERS whose value is SAMANTHA and SONS whose value is the list (DANNY GEOFFREY). ~ I ·--- 2. 0 ~he call to the PPRINT-PLIST function pretty-prints the property list of the symbol CHILDREN. The pretty-printed output emphasizes the relationship between each property and its value. Lisp> (DEFUN RECORD-MY-STATISTICS (NAME AGE SIBLINGS MARRIED?) (UNLESS (SYMBOLP NAME) {ERROR .. - s must be a symbol." NAME))· (SETF {GET NAME 'AGE) AGE {GET NAME 'NUMBER-OF-SIBLINGS) SIBLINGS (GET NAME 'IS-THIS-PERSON-MARRIED?) MARRIED) NAME) RECORD-MY-STATISTICS. Lisp> (DEFUN SHOW-MY-STATISTICS (NAME) (UNLESS (SYMBOLP NAME) (ERROR "-s must be a symbol." NAME)) (PPRINT-PLIST NAME)) SHOW-MY-STATISTICS Lisp> (RECORD-MY-STATISTICS 'TOM 29 3 NIL) TOM Lisp> (SHOW-MY-STATISTICS 'TOM) (IS-THIS-PERSON-MARRIED? NIL NUMBER-OF-SIBLINGS 3 AGE 29) 68 Q 0 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS PPRINT-PLIST Function (cont.) 0 • The first call to the DEFUN macro defines a function named RECORD-MY-STATISTICS. • The second call to the DEFUN macro defines a, function named SHOW-MY-STATISTICS. The definition incluaes a call to the PPRINT-PLIST function . • The call to the RECORD-MY-STATISTICS function properties for the symbol TOM. e The call to the SHOW-MY-STATISTICS function the property list for the symbol TOM. 0 0 0 0 69 inputs the pretty-prints VAX LISP/ULTRIX FUNCTION, MACRO; AND VARIABLE DESCRIPTIONS *PRE-GC-MESSAGE* Variable Controls the message the LISP system displays whe~ a garbage collection starts. The value of this variable can be NIL, a string of message text, or the null string(""). If the value is NIL, the system displays a system message. If the value is a string ~f message text, the system displays the message text. If the variable's value is the null string, the system displays no output. The default value is NIL. 0 System messages appear in the following form: Starting garbage collection due to GC function. VAX LISP messages preceding garbage collection differ depending on the cause of the garbage collection. If you set the *PRE-GC-MESSAGE* variable, the message you establish supersedes all system messages, regardless of cause. 0 Example Lisp> (GC) ; Starting garbage collection due to GC function. ; Finished garbage collection due to GC function. T Lisp> (SETF *PRE-GC-MESSAGE* "") 0 1111 Lisp> (GC) ; Finished garbage collection due to GC function. T Lisp> (SETF *PRE-GC-MESSAG~* "GC -- started") "GC -- started" Lisp> ( GC) GC -- started Finished garbage collection due to GC function. 0 T • The first call to the GC function shows the garbage collection messages that are printed by default. • The first call to the SETF macro sets the value *PRE-GC-MESSAGE* variable to the null string(""). of the • The second call to the GC function causes the system display a message when the garbage collection starts. not to • The second call to the SETF macro sets variable to the string "GC -- started". of the • The third call to the GC function causes the system to display the new message text when the garbage collection starts. 70 the value Q VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *PRINT-LINES* Variable Ospecifies the number of lines to be printed by an outermost logical block. The default for this variable is NIL, which specifies no abbreviation. *PRINT-LINES* is effective only when pretty printing is enabled. When the system limits output to the number of lines specified by *PRINT-LINES*, it indicates abbreviation by replacing the last four characters on the last line printed with" ... ". The WRITE and WRITE-TO-STRING functions have been extended in VAX LISP to accept the :LINES keyword. If you specify this keyword, *PRINT-LINES* is bound to the value you supply with the keyword before any output is produced. See Chapter variable. O 0 0 5 for more information on using the *PRINT-LINES* Example Lisp> (SETF *PRINT-LINES* 4) 4 Lisp> ( FORMAT T II Stars: - : !- /LINEAR/'. 11 '(POLARIS DUBHE MIRA MIRFAK BELLATRIX CAPELLA ALGOL MIRZAM POLLUX CANOPUS ALBIREO CASTOR ALPHECCA ANTARES)) Stars: POLARIS DUBHE MIRA MI ... e With *PRINT-LINES* set to 4, printing stops at the end of fourth line. • The last four characters of the last MIRFAK becomes MI. 0 71 line are not the printed. VAX LISP/UL!RIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS "PRINT-MISER-WIDTH* Variable Controls miser mode printing. If the available line width between the indentation of the current logical block and the end of the line is less than the value of this variable, the pretty printer enables miser mode. When output is printed in miser mode, all indentations are ignored. In addition, a new line is started for every condiiional new line directive·(-_, ._, -@_). The default value for *PRINT-MISER-WIDTH* is 40. You can prevent the use of miser *PRINT-MISER-WIDTH* variable to NIL. mode by setting the The WRITE and WRITE-TO-STRING functions have been extended in VAX LISP to accept the :MISER-WIDTH keyword. If you specify this keyword, *PRINT-MISER-WIDTH* is bound to the value you supply with the keyword before any output is produced. For more information about miser mode and the use *PRINT-MISER-WIDTH* variable, see Sections 5.5 and 5.8. of 0 the 0 Example Lisp> (SETF *PRINT-RIGHT-MARGIN* 60) 60 Lisp> (SETF *PRINT-MISER-WIDTH* 35) 35 Lisp> (FORMAT T "-!stars with Arabic names: -:@!-s -:_-s -21I-:_-s -:r@_-s -_-s -1r_-s-.-." '(BETELGEUSE (DENEB SIRIUS VEGA) ALDEBERAN ALGOL (CASTOR POLLUX) BELLATRIX) Stars with Arabic names: BETELGEUSE (DENEB SIRIUS VEGA) ALDEBERAN ALGOL (CASTOR POLLUX) BELLATRIX • The text, "Stars with Arabic names:", in the outer logical block causes the inner logical block to begin at column 26. With *PRINT-MISER-WIDTH* set to 35, FORMAT enables miser mode when the logical block begins past column 25. • FORMAT conserves space by starting a pew line at every multiline mode new line directive(-_) and every if-needed new line directive c-:_). • FORMAT starts a new line at the miser mode new line c-@_) and ignores the indentation directives c-nI). 0 0 directive 0 72 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *PRINT-RIGHT-MARGIN* Variable 0 Specifies the right margin for pretty printing. Output may exceed this margin if you print long symbol names or strings, or if your FORMAT control string specifies no new line directives of any type. If the value of *PRINT-RIGHT-MARGIN* is NIL, the print function uses a value appropriate to the output device. • The WRITE and WRITE-TO-STRING functions have been extended in VAX LISP to accept the :RIGHT-MARGIN keyword. If you specify this keyword, *PRINT-RIGHT-MARGIN* is bound to the value you supply with the keyword before any output is produced. See Chapter 5 for more *PRINT-RIGHT-MARGIN* variable. 0 0 0 about using the function named Example Lisp> (DEFUN RECORD-MY-STATISTICS (NAME AGE SIBLINGS MARRIED?) (UNLESS (SYMBOLP NAME) ( ERROR .,- s must be a symbol." NAME)) (SETF (GET NAME 'AGE) AGE (GET NAME 'NUMBER-OF-SIBLINGS) SIBLINGS (GET NAME 'IS-THIS-PERSON-MARRIED?) MARRIED) NAME) RECORD-MY-STATISTICS Lisp> (SETF *PRINT-RIGHT-MARGIN* 40) 40 Lisp> (PPRINT-DEFINITION 'RECORD-MY-STATISTICS) (DEFUN RECORD-MY-STATISTICS (NAME AGE SIBLINGS MARRIED?) (UNLESS (SYMBOLP NAME) (ERROR .,- S must be a symbol." NAME)) (SETF , (GET NAME 'AGE) AGE (GET NAME 'NUMBER-OF-SIBLINGS) SIBLINGS (GET NAME 'IS-THIS-PERSON-MARRIED?) MARRIED) NAME) • 0 information The call to the DEFUN RECORD-MY-STATISTICS. macro 73 defines a VAX LISP/ULTRIX FUNCTION. MACRO. AND VARIABLE DESCRIPTIONS *PRINT-RIGHT-MARGIN* Variable (cont.) • The call to the SETF macro sets *PRINT~RIGHT-MARGIN* variable to 40. the value of the 0 The call to the • variable's value PPRINT function showi the effect the has on the pretty-printed' output. PPRINT-DEFINITION stops printing each line before reaching column 40. 0 0 0 0 74 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS CJ PRINT-SIGNALED-ERROR Function Used by the VAX LISP error handler to display a formatted error message when an error is signaled. The function prints all output to the stream bound to the *ERROR-OUTPUT* variable. The error message formats are described in Chapter 3. You can include a call to this function in an error handler create (see Chapter 3). ' that you Format PRINT-SIGNALED-ERROR function-name error-signaling-function &REST args Arguments 0 function-name The name of the function error-signaling function. that is to specified call the Valid function error-signaling-function 0 The name of an error-signaling function. are ERROR, CERROR, and WARN. names args The specified error-signaling function's arguments. Return Value Undefined. O Example Lisp> (DEFUN CONTINUING-ERROR-HANDLER (FUNCTION-NAME ERROR-SIGNALING-FUNCTION &REST ARGS) (IF (EQ ERROR-SIGNALING-FUNCTION 'CERROR) (PROGN (APPLY #'PRINT-SIGNALED-ERROR FUNCTION-NAME ERROR-SIGNALING-FUNCTION ARGS) (FORMAT *ERROR-OUTPUT* "-&It will be continued automatically.-2%.") NIL) 0 75 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS PRINT-SIGNALED-ERROR Function (cont.) (APPLY #'UNIVERSAL-ERROR-HANDLER FUNCTION-NAME ERROR-SIGNALING-FUNCTION ARGS))) CONTINUING-ERROR-HANDLER 0 Defines an error handler that automatically continues from a continuable error after displaying an error message. All other errors are passed to the system's error handler. 0 0 0 0 76 - VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTION!:> 0 *PRINT-SLOT-NAMES-AS-KEYWORDS* Variable Determines how the slot names of a structure are formatted when they are displayed. The value can be Tor NIL. If the value is T, slot names are preceded with a colon(:). For example: #S(SPACE :AREA 4 :COUNT 10) If the value is NIL, slot names are not preceded with example: a colon. For #S(SPACE AREA 4 COUNT 10) The default value is T. Example O 0 Lisp> (DEFSTRUCT HOUSE ROOMS FLOORS) HOUSE Lisp> (MAKE-HOUSE :ROOMS 8 :FLOORS 2) #S(HOUSE :ROOMS 8 :FLOORS 2) Lisp> (SETF *PRINT-SLOT-NAMES-AS-KEYWORDS* NIL) NIL Lisp> (MAKE-HOUSE :ROOMS 8 :FLOORS 2) #S(HOUSE ROOMS 8 FLOORS 2) • The call to the DEFSTRUCT HOUSE. macro defines a structure named first call to the constructor function MAKE-HOUSE creates • The a structure named HOUSE. Colons are included in the output 0 because the value variable is T. of the *PRINT-SLOT-NAMES-AS-KEYWORDS* call to the SETF macro changes the value of • The *PRINT-SLOT-NAMES-AS-KEYWORDS* variable to NIL. • the The second call to the constructor function MAKE-HOUSE creates a structure named HOUSE. Colons are not included in the output because the value of the *PRINT-SLOT-NAMES-AS-KEYWORDS* variable is NIL. 0 77 VAX LISP/UL TRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS REQUIRE Function Examines the *MODULES* variable to determine if a specified module has been loaded. If the module is not loaded, the function loads the files that you specify for the module. If the module is loaded, its files are not reloaded. 0 ' When you call the REQUIRE function in VAX LISP, the function checks whether you explicitly specified pathnames that name the files it is to load. If you specify pathnames, the function loads the files the pathnames represent. If you do not specify pathnames, the function searches for the module's files in the following order: 1. I The function searches the current directory for a source file or a fast-loading file with the specified module name. If the function finds such a file, it loads the file into the LISP environment. This search forces the function to locate a module you have created before the function locates a module of the same name that is present in one of the public places (see following steps). 2. If the environment variable MODULES.is defined, the function searches the directory this environment variable refers to for a source file or a fast-loading file with the specified module name. This search enables the VAX LISP sites to maintain a central directory of modules. 3. The function searches the directory referred to by the environment variable VAXLISP if it is defined or the directory /usr/lib/vaxlisp for a source file or a fast-loading file with the specified module name. This search enables you to locate modules that are provided with the VAX LISP system. See the VAX LISP/ULTRIX Installation Guide for a description of the use of the environment variable VAXLISP. 4. If the function does not find a file module name, an error is signaled. •- · - with the specified o 0 Q When you load a module, the pathname that refers to the directory that contains the module is bound to the *MODULE-DIRECTORY* variable. A description of the *MODULE-DIRECTORY* variable is provided earlier in Part II. The REQUIRE function checks the *MODULES* variable to determine if a module has already been loaded. However, the REQUIRE function, when loading a module, does not update the *MODULES* variable to indicate that the module has been loaded. The PROVIDE function (described in COMMON LISP: The Language) does update the *MODULES* variable. use the PROVIDE function in a file containing a module to be loaded to indicate to the LISP system that the file contains a module of this name. 78 0 VAX LISP/UL TRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS O REQUIRE Function (cont.) If the loaded file does not contain a corresponding PROVIDE, a subsequent REQUIRE of the module will cause the file to be reloaded. Format REQUIRE module-name &OPTIONAL pathname Arguments module-name o A string or a symbol that names the module whose files are to loaded. be pathname A pathname or a list of pathnames that represent the files to be loaded into LISP memory. The files are loaded in the same order the pathnames are listed, from left to right. Return Value Undefined. O Example Lisp> *MODULES* ("calculus" "newtonian-mechanics") Lisp> (REQUIRE 'relative) T Lisp> *MODULES* ("relative" "calculus" "newtonian-mechanics") 0 • The first call to the *MODULES* variable shows that modules calculus and newtonian-mechanics are loaded. the call to the REQUIRE function checks whether the module • The relative is ioaded. The previous call to the *MODULES* o variable indicated that the module was not loaded, the function loaded the module relative. therefore, The second call to the *MODULES* module relative was loaded. that 0 79 variable shows the VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS ROOM Function Displays information about LISP memory. the following memory spaces: • Read-only space • Static space • Dynamic space Information is displayed for O The following information is provided for each type of space: • Total number of memory pages that can be used • Current number of memory pages being used • Percentage of free memory pages available for use 0 The information for each storage type is displayed on one line in following format: Read-Only Storage the Total Size: 4352, Current Allocation: 4113, Free: 6% All counts are in 512-byte pages. 0 Format ROOM &OPTIONAL value Argument value Optional argument whose value can be Tor NIL. If you specify NIL, the function displays the same information that it displays when the argument is, not specified. If you specify T, the function displays additional information for the read-only, static, and dynamic storage spaces. The additional information consists of a breakdown of the storage space being used by each VAX LISP data type. The information is displayed in the following tabular format: Q Read-Only Storage Total Size: 4352, Current Allocation: 4113, Free: 6% (reserved) 0 Functions: 191 Arrays: 0 B-Vectors: 6 Strings: 381 U-Vectors: 3403 S Flo Vecs: 0 D Flo Vecs: 0 L Flo Vecs: 0 L Wrd Vecs: 0 Bignums: 1 (reserved) 0 Sngl Floe: 1 Dbl Flos: 1 Long Floe: 1 Ratios: 0 Complexes: 0 Symbols: 0 Conses: 128 (reserved) 0 Ctrl Stack: 0 Bind Stack: 0 Table 2 lists the headings and VAX LISP data types function displays for each type of storage space. 80 the ROOM Q VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTION!::> ROOM Function (cont.) . 0 Return Value No value. 0 0 0 Table 2: Data Type Headings Heading Data Type Functions Compiled function descriptors Arrays Nonsimple array descriptors B-Vectors Boxed vectors -- simple vectors of LISP objects Strings Character strings u-vectors Unboxed vectors -- simple vectors that contain compiled code, alien structures, or integers of type (mod n) S Flo Vecs Simple float vectors D Flo Vecs Simple double float vectors L Flo Vecs Simple long float· vectors L Wrd Vecs Simple longword vectors Bignums Bignums Sngl Flos Single float numbers Dbl Flos Double float numbers Long Flos Long float numbers Ratios Ratios Symbols Symbols Cons es .conses Ctrl Stack Control Stack Bind Stack Binding Stack 0 81 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS ROOM Function (cont.) O Examples 1. Lisp> (ROOM) Read-Only Storage Static Storage Dynamic-0 Storage Total Size: 4352, Current Allocation: 4113, Free: 5'Y, Total Size: 2176, Current Allocation: 2146, Free: 1% Total Size: 3065, Current Allocation: 1292, Frcee: 58% Displays a list of the current memory storage information. 2. Lisp> (ROOM T) Read-Only Storage Total Size: 4352, Current Allocation: 4113, Free: 5% (reserved) 0 Functions: 191 Arrays: 0 B-Vectors: 6 Strings: 381 U-Vectors: 3403 S Flo Vecs: 0 D Flo Vecs: 0 L Flo Vecs: 0 Bignums: 0 L Wrd Vecs: 0 1 (reserved) Sngl Flos: 1 Dbl Flos: 1 Long Flos: 1 Ratios: 0 Complexes: 0 Symbols: 0 Conses: 128 (reserved) 0 Ctrl Stack: 0 Bind Stack: 0 Static Storage (reserved) Strine,s: L Flo Vecs: Sngl Flos: Complexes: Ctrl Stack: Total Size: 2176, Current Allocation: 2146, Free: 1% 322 Arrays: Functions: 1 B-Vectors: 81 U-Vectors: 257 S Flo Vecs: 0 D Flo Vecs: 0 0 L Wrd Vecs: 0 Bignums: 1 (reserved) 0 0 Ratios: 2 Dbl Flos: 2 Long Flos: 0 0 Symbols: 360 Conses: 544 (reserved) 0 0 Bind Stack: 0 0 576 Dynamic-0 Storage Total Size: 3065, Current Allocation: 1280, Free: 58% (reserved) 3 Arrays: 0 Functions: 1 B-Vectors: 214 Strings: 254 U-Vectors: 12 S Flo Vecs: 1 D Flo Vecs: 0 0 Bignums: L Flo Vecs: 3 (reserved) 0 0 L Wrd Vecs: Sngl Flos: 1 Dbl Flos: 1 Long Flos: 1 Ratios: 0 Complexes: 656 (reserved) 0 Symbols: 4 Conses: 0 Ctrl Stack: 129 Bind Stack: 36 Read-Only Storage 0 0 Total Size: 4352, Current Allocation: 4113, Free: S'Y, Displays a detailed information. list of · the current memory storage O 0 82 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS SHORT-SITE-NAME Function 0 If the file lispsite.txt exists in the LISP product directory, the SHORT-SITE-NAME function finds the file, reads it, and returns the first line of text as a string that represents the physical location of the _computer hardware on which the VAX LISP system ii running. Otherwise, the SHORT-SITE-NAME function returns NIL. The LISP product directory is the directory referred to by the environment variable VAXLISP if it exists, or by /usr/lib/vaxlisp if the environment variable does not exist. See the VAX LISP/ULTRIX Installation Guide for more information on the SHORT-SITE-NAME function and on creating the file lispsite.txt. Format 0 SHORT-SITE-NAME Return Value A string with a brief description of the physical location of the computer hardware on which a VAX LISP system is running, or NIL. Example 0 Lisp> (SHORT-SITE-NAME) "Smith's Computer Company" 0 0 83 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS STEP Macro 0 Invokes the VAX LISP stepper. The STEP macro evaluates the form that is its argument and returns what the form returns. In the process, you can interactively step through the evaluation of the form. Entering a question marl (?) in response to the stepper prompt displays helpful information. The stepper is command oriented rather than expression oriented - do not surround commands with parentheses. For further information on using the VAX LISP stepper, see Chapter 4. Format STEP form Argument 0 form A form to be evaluated. Return Value The value returned by form. 0 Example Lisp> (STEP (FACTORIAL 3)) : #9: (FACTORIAL 3) Step 1> Invokes the VAX LISP stepper for the function call (FACTORIAL 3). 0 0 84 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS * STEP-ENVIRONMENT* Va.riable 0 The *STEP-ENVIRONMENT* variable, a debugging tool, is bound to the lexical environment in which *STEP-FORM* is being evaluated. By default in the stepper, the lexical environment is used if you use the EVALUATE command. See COMMON LISP: The Language for a description of dynamic and lexical environment variables. Some COMMON LISP functions (for example, EVALHOOK, APPLYHOOK, and MACROEXPAND) take an optional environment argument. The value bound to the *STEP-ENVIRONMENT* variable can be passed as an environment to these functions to allow evaluaton of forms in the context of the stepped form. Example 0 Step> EVAL *STEP-FORM* (FUNCTION-X (- X 1)) Step> (EVALHOOK '(- x 1) NIL NIL *STEP-ENVIRONMENT*) 2 The use of the *STEP-ENVIRONMENT* variable in this call to the EVALHOOK function causes the local value of X to be used in the evaluation of the form (- X 1). See Chapter 4 for the full stepper sessions from which this excerpt is taken. 0 0 0 85 VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS *STEP-FORM* Variable The *STEP-FORM* variable, a debugging tool, is bound to the form beingo evaluated while stepping. For example, while executing the form (STEP (FUNCTION~z ARG1 ARG2)) the value of *STEP-FORM* is the list (FUNCTION-Z ARG1 ARG2). stepping, the value is undefined. When not Example Step> STEP .. . . : #39: X => 4 #35: => NIL #34: (+ FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))) Step> STEP . . . . . . : #38: (FUNCTION-X (- X 1)) Step> EVAL *STEP-FORM* (FUNCTION-X (- X 1)) 0 See Chapter 4 for the full stepper session from which this excerpt is taken. In this case, the *STEP-FORM* variable is bound to (FUNCTION-X (- X 1)). 0 0 0 86 VAX LISP/UL TRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS SUSPEND Function O Writes information about a LISP system to a file, making it possible to resume the LISP system at a later time. The function does not stop the current system, but copies the state of the LISP system when the function is invoked to the specified file. When you reinvoke the LISP system with the RESUME (-r) option and the file name 'that was specified with the SUSPEND function, program execution continues from -the point where the SUSPEND function was called. Only the static and dynamic portions of the LISP environment are written to the specified file. When you resume a suspended system, the read-only sections of the LISP environment are taken from lispsus.sus in VAXLISP or in /usr/lib/vaxlisp. You must make sure that your original LISP system is in lispsus.sus; if it is not, you will not be able to resume the system. 0 0 When a suspended system is resumed, the LISP environment is identical to the environment that existed when the suspend operation occurred, with the following exceptions: s All streams except the standard streams are closed. e The *DEFAULT-PATHNAME-DEFAULTS* variable is set to the current directory. @ Call-out state might be lost (see Chapter LISP/ULTRIX System Acess Programming Guide). 2 of the VAX Format SUSPEND pathname Argument Q pathname A pathname, namestring, or symbol that represents the to which the function writes the LISP-system state. file name - Return Value T, when the LISP system is resumed at a later time and NIL, execution continues after a suspend operation. 0 87 when VAX LISP/ULTRIX FUNCTION, MACRO. AND VARIABLE DESCRIPTIONS SUSPEND Function (cont.) 0 Example Lisp> (DEFUN PROGRAM-MAIN-LOOP NIL (LOOP (PRINC "Enter number> ") (SETF X (READ *STANDARD-INPUT*)) (FORMAT *STANDARD-OUTPUT* "-%The square root of-Fis -F. - "'06 " x ( SQRT X) ) ) ) PROGRAM-MAIN-LOOP Lisp> (DEFUN DUMP-PROGRAM NIL (SUSPEND "myprog.sus") (FRESH-LINE) (PRINC "Welcome to my program!") (TERPRI) (PROGRAM-MAIN-LOOP)) DUMP-PROGRAM Lisp> (DUMP-PROGRAM) Starting garbage collection due to GC function. Finished garbage collection due to GC function. Starting garbage collection due to SUSPEND function. Finished garbage collection due to SUSPEND function. Welcome to my program Enter number> 25 The square root of 25.0 is 5.0. Enter number> 5 The square root of 5.0 is 2.236038. Enter number> 0 0 <CTRL/C> Lisp> (EXIT) % vaxlisp -r myprog.sus Welcome to my program Enter number> 0 • The first call to the DEFUN macro PROGRAM-MAIN-LOOP. defines a function named • The second call to the DEFUN macro defines DUMP-PROGRAM. a function named • The call to the DUMP-PROGRAM function copies the current state of the LISP environment to the file myprog.sus. The LISP system continues to run, displaying the message "Welcome to my program" and then executes the PROGRAM-MAIN-LOOP function. • The call to the EXIT function exits the LISP system. 88 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS SUSPEND Function (cont:) 0 • The vaxlisp -r myprog.sus specification system, displays the message, PROGRAM-MAIN-LOOP function. 0 0 0 0 89 reinvokes the and executes LISP the VAX LISP/ULTRIX FUNCTION, MACRO, AND. VARIABLE DESCRIPTIONS THROW-TO-COMMAND-LEVEL Function Transfers control. This function exists only for compatibility· with VAX LISP/VMS Vl.x, in which it transferred control to a.numbered command level. VAX LISP V2 does not have numbered command levels. In VAX LISP V2, THROW-TO-COMMAND-LEVEL either throw~• to the CANCEL-CHARACTER-TAG tag or does nothing. 0 Format THROW-TO-COMMAND-LEVEL level Argument level Either an integer or a keyword. Depending on the THROW-TO-COMMAND-LEVEL takes the following action: integer :CURRENT :PREVIOUS :TOP argument, 0 No action Throw to CANCEL-CHARACTER-TAG No action Throw to CANCEL-CHARACTER-TAG Return value 0 Undefined. Example Lisp> (FACTORIAL M) Fatal error in function SYSTEM::%EVAL (signaled with ERROR). Symbol has no value: M 0 Control Stack Debugger Frame #3: (EVAL (FACTORIAL M)) Debug> (THROW-TO-COMMAND-LEVEL :TOP) Lisp> • The debugger is invoked, because an error the FACTORIAL function was called • . · was signaled • The call to the THROW-TO-COMMAND-LEVEL control to the top-level loop. function when returns 0 90 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TIME Macro OEvaluates a form, displays the form's CPU returns the values the form returns. time and real time, and The time information is displayed in the following format: CPU Time: 0.03 sec., Real Time: 0.23 sec. If garbage collections occur during the evaluation of a call to the TIME macro, the macro displays another line of time information. This line includes information about the CPU time and real time used by the garbage collector. Format O TIME form Argument form The form that is to be evaluated. Return value Q The form's return values are returned. Example Lisp> (TIME (TEST)) CPU Time: 0.03 sec., Real Time: 0.23 sec. 6 0 0 91 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *TOP-LEVEL-PROMPT* Variable Lets you change the top-level prompt. be: The value of this variable • A string • A function of no arguments that returns a string e NIL cano If you specify NIL, the default prompt "Lisp>" is used. Example Lisp> (SETF *TOP-LEVEL-PROMPT* "TOP> " TOP> "TOP> ") Sets the value of the variable *TOP-LEVEL-PROMPT* to "TOP> 0 II 0 0 0 92 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro 0 Enables tracing for one or more functions and macros. VAX LISP allows you to specify a number of options that suppress the TRACE macro's displayed output or that cause additional in;o;mation to be displayed. The options are specified as keyword-valu~ pairs. The keyword-word value pairs you can specify are listed in Table 3. NOTE The arguments specified in a call to the TRACE macro are not evaluated when the call to TRACE is executed. Some forms are evaluated repeatedly, as described below. 0 Format TRACE &REST trace-description Argument trace-description 0 One or more optional arguments. If an argument is not specified, the TRACE macro returns a list.of the functions and macros that are currently being traced. Trace-description arguments can be specified in three formats: • 0 One or more function and/or macro names can be specified which enables tracing for that function(s) and/or macro(s). narne-1 narne-2 ... • The name of each function or macro can be specified with keyword-value pairs. The keyword-value pairs specify the operations the TRACE macro is to perform when it traces the specified function or macro. The name and the keyword-value pairs must be specified as a list whose first element is the function or macro name. (name keyword-1 value-1 keyword-2 value-2 ... ) • 0 A list of function and/or macro names can be specified with keyword-value pairs. The keyword-value pairs specify the operations the TRACE macro is to perform when it traces each function and/or macro in the list. The list of names and the keyword-value pairs must be specified as a list whose first element is the list of names. 93 · VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) ((narne-1 name-2 ... ) keyword-1 value-1 0 keyword-2 value-2 ... ) Table 3 lists the keywords and values that can be specified. The forms that are referred to in the value descriplions are evaluated in the null lexical environment and the current dynamic environment. Table 3: TRACE Options Keyword-Value Pair Description :DEBUG-IF form Specifies a form that is to be evaluated before and after each call to the specified function or macro. If the form returns a value other than NIL, the VAX LISP debugger is invoked before and after the function or macro is called. :PRE-DEBUG-IF form :POST-DEBUG-IF form :PRINT form-list Specifies a form that is to be evaluated before each call to the If specified function or macro. the form returns a value other than is NIL, the VAX LISP debugger before specified invoked the function or macro is called. Specifies a form that is to be evaluated after each call to the specified function or macro. If the form returns a value other than NIL, the VAX LISP debugger is invoked after the specified function or macro is called. Specifies a list of forms that are to be evaluated and whose values are to be displayed before and after 'each call to the specified function or macro. The values are displayed one per line and are indented to match other output displayed by the TRACE macro. If the TRACE macro cannot evaluate the argument, the debugger is invoked (see Chapter 4)~ 94 0 0 0 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 Table 3 (cont. ) Keyword-Value Pair :PRE-PRINT form-list 0 Specifies a list of forms•that are to be evaluated and whose values are to be displayed before each call to the specified function or macro. The values are displayed one per line and are indented to match other output displayed by the TRACE macro. If the TRACE macro cannot evaluate the argument, the debugger is invoked (see Chapter 4) • :POST-PRINT form-list 0 Specifies a list of forms that are to be evaluated and whose values are to be displayed after each call to the specified function or macro. The values are displayed one per line and are indented to match other output displayed by the TRACE macro. If the TRACE macro cannot evaluate the argument, the debugger is invoked (see Chapter 4). :STEP-IF form Specifies a form that is to be evaluated before each call to the specified function or macro. If the form returns a value other than NIL, the stepper is invoked and the function or macro is stepped through. See Chapter 4 for information on the stepper. :SUPPRESS-IF form Specifies a form that is to be evaluated before each call to the specified function or macro. If the form returns a value other than NIL, the TRACE macro does not display the arguments and the return value of the specified function or macro. :DURING name Specifies a function or macro name or a list of function and macro names. The function or macro specified by the TRACE function is traced only when it is called 0 0 Description 95 VA.A Ll::;1-'/UL I HIX .-:UNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 Table 3 (cont. ) Keyword-Value Pair Description indi rect\y) f rorn (directly or within one of the functions or macros specified by the :DURING keyword. Return Value A list of the functions currently being traced. Examples 1. 0 Lisp> (TRACE FACTORIAL COUNT1 COUNT2) (FACTORIAL COUNTl COUNT2) Enables the tracer for the functions FACTORIAL, COUNT2. 2. and tracer is Lisp> (TRACE) (FACTORIAL COUNT1 COUNT2) Returns a list of the enabled. 3. COUNT1, functions for which the Lisp> (DEFUN REVERSE-COUNT (N) (DECLARE (SPECIAL *GO-INTO-DEBUGGER*)) ( IF ( > N 3) (SETQ *GO-INTO-DEBUGGER* T) (SETQ *GO-INTO-DEBUGGER* NIL)) ( COND ( ( = N O) 0 ) (T (PRINT N) (+ 1 (REVERSE-COUNT (- N 1)))))) Lisp> (SETQ *GO-INTO-DEBUGGER* NIL) NIL Lisp> (REVERSE-COUNT 3) 0 0 3 2 1 3 Lisp> (TRACE (REVERSE-COUNT :DEBUG-IF *GO-INTO-DEBUGGER*)) (REVERSE-COUNT) Lisp> (REVERSE-COUNT 3) #4: (REVERSE-COUNT 3) 3 • #16: (REVERSE-COUNT 2) 2 •• #28: (REVERSE-COUNT 1) 96 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 1 . #40: (REVERSE-COUNT 0) #40=> 0 . • #28=> 1 . #16=> 2 #4=> 3 3 Lisp> (REVERSE-COUNT 4) #4: (REVERSE-COUNT 4) 4 • #16: (REVERSE-COUNT 3) Control Stack Debugger Frame #17: (DEBUG) Debug 1> CONTINUE 3 0 •• #28: (REVERSE-COUNT 2) 2 . #40: (REVERSE-COUNT 1) 1 • • • • #52: (REVERSE-COUNT 0) • • • • #52=> 0 • • . #40=> 1 . • #28=> 2 • #16=> 3 #4=> 4 0 4 Lisp> The recursive function REVERSE-COUNT is defined to count down from the number it is given and to return. that number after the function is evaluated. If, however, the number given is greater than 3 (set low to simplify the example), the global variable *GO-INTO-DEBUGGER* (preset to NIL) is set to T. 0 The first time the REVERSE-COUNT function is traced using the DEBUG-IF keyword, the argument is 3. The second time the function is traced, the argument is over 3. This sets the global variable *GO-INTO-DEBUGGER* to T, which causes the debugger to be invoked during a trace of the REVERSE-COUNT function. The debugger is invoked after the function's argument is evaluated. To reset the global variable *GO-INTO-DEBUGGER* to NIL, the REVERSE-COUNT function must be completed. So, the evaluation of the function was continued with the Debug command CONTINUE. 4. 0 Lisp> (TRACE (REVERSE-COUNT :PRE-DEBUG-IF *GO-INTO-DEBUGGER*)) (REVERSE-COUNT) 97 VAX USP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 Lisp> (REVERSE-COUNT 4) #4: (REVERSE-COUNT 4) 4 . #16: (REVERSE-COUNT 3) Control Stack Debugger Frame #17: Debug 1> The 4 argument to the REVERSE~COUNT function causes the *GO-INTO-DEBUGGER* variable to be set to T, which in turn causes the debugger to be invoked before the first recursive call to the REVERSE-COUNT function. 5. Lisp> (TRACE (REVERSE-COUNT :POST-DEBUG-IF *GO-INTO-DEBUGGER*)) (REVERSE-COUNT) Lisp> (REVERSE-COUNT 4) #4: (REVERSE-COUNT 4) 4 • #16: (REVERSE-COUNT 3) 3 #28: (REVERSE-COUNT 2)· 2 . #40: (REVERSE-COUNT 1) 1 . #52: (REVERSE-COUNT 0) . #52=> 0 . #40=> 1 #28=> 2 . #16=> 3 #4=> 4 4 Lisp> (TRACE (REVERSE-COUNT :POST-DEBUG-IF (NOT *GO-INTO-DEBUGGER*))) (REVERSE-COUNT) Lisp> (REVERSE-COUNT 4) #4: (REVERSE-COUNT 4) 4 . #16: (REVERSE-COUNT 3) 3 #28: (REVERSE-COUNT 2) 2 . #40: (REVERSE-COUNT 1) 0 0 0 1 • • #52: (REVERSE-COUNT 0) Control stack Debugger Frame #53: (DEBUG) Debug 1> CONTINUE 0 • #52=> 0 98 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 Control Stack Debugger Frame #41: (DEBUG) Debug 1> CONTINUE . . . #40=> 1 Control Stack Debugger Frame #29: (DEBUG) Debug 1> CONTINUE . . #28=> 2 Control Stack Debugger Frame #17: (DEBUG) Debug 1> CONTINUE • #16=> 3 Control Stack Debugger Frame #5: (DEBUG) Debug 1> CONTINUE 0 #4=> 4 4 Lisp> Here, the first time the REVERSE-COUNT function is evaluated, the debugger is not invoked despite the :POST-DEBUG-IF keyword, because the keyword invokes the debugger only if its condition is met after the function is evaluated. However, after the function is evaluated, the *GO-INTO-DEBUGGER* variable is reset back to NIL. If the form (SETQ *GO-INTO-DEBUGGER* NIL) were removed from the definition of the REVERSE-COUNT function, the variable would not have been reset to NIL, and the debugger would have been invoked. 0 0 The second time the REVERSE-COUNT function is invoked, the form (NOT *GO-INTO-DEBUGGER*) evaluates to T, since the value of its argument is NIL. This gives the :POST-DEBUG-IF keyword a T value, which in turn fulfills the condition of invoking the debugger after the function is evaluated. In this situation, the Debug CONTINUE command causes only one evaluation. Here, the CONTINUE command must be repeated to evaluate all the recursive calls. This example differs from example 1, where the CONTINUE command did not have to be repeated. 6. Lisp> (SETF *L* 5 *M* 6 *N* 7) 7 0 Lisp> (TRACE (* :PRINT (*L* *M* *N*) ) ) ( *) Lisp> (+ 2 3 *L* *M* *N*) 99 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 23 Lisp> ( * 2 # 4: ( * 2 3 #4 *L* is #4 *M* is #4 *N* is #4=> 1260 #4 *L* is #4 *M* is #4 *N* is 1260 3 *L* *M* *N*) 5 6 7) 5 6 7 5 6 7 The+ function is not traced, but the* function is traced. The values of the global variables *L*, *M*, and *N* are displayed before and after the call to the * function is evaluated. 7. Lisp> (TRACE ( * :PRE-PRINT (*L* *M* *N*))) ( *) Lisp> (* 2 3 *L* *M* *N*) #4: (* 2 3 5 6 7) #4 *L* is 5 #4 *M* is 6 #4 *N* is 7 #4=> 1260 1260 0 0 The values of the global variables *L*, *M*, and *N* are displayed before the call to the* function is evaluated. 8. Lisp> (TRACE ( * :POST-PRINT (*L* *M* *N*))) ( *) Lisp> (* 2 3 *L* *M* *N*) #4: (* 2 3 5 6 7) #4=> 1260 #4 *L* is 5 #4 *M* is 6 #4 *N* is 7 1260 The values of the global variables *L*, *M*, and *N* displayed after the call to th&* function is evaluated. 9. 0 are Lisp> (TRACE+) ( +) Lisp> (+ 2 3 (SQUARE 4) (SQRT 25)) #4: (+ 2 3 16 5.0) #4=> 26.0 26.0 Lisp> (SETQ *STOP-TRACING* T) 100 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 NIL Lisp> (TRACE(+ :SUPPRESS-IF *STOP-TRACING*)) ( +) Lisp> (+ 2 3 (SQUARE 4) 26.Q (SQRT 25)) G In the first example, the call to the+ function is traced. In the second example, the call to the+ function is not traced because of the form(+ :SUPPRESS-IF *STOP-TRACING*). 10. 0 0 Lisp> (TRACE (FACTORIAL :STEP-IF T)) (FACTORIAL) Lisp> (+ (FACTORIAL 2) 3) #5: (FACTORIAL 2) #9: (BLOCK FACTORIAL (IF(> 2 N) 1 (* N (FACTORIAL (1- N))))) Step> : #16: (IF (> 2 N) 1 (* N (FACTORIAL (1- N)))) Step> : : #22: (> 2 N) Step> The call to the FACTORIAL function invokes the stepper. 11. Lisp> (TRACE (LIST-LENGTH :DURING PRINT-LENGTH)) (LIST-LENGTH) Lisp> (PRINT-LENGTH '(CAT DOG PONY)) #13: (LIST-LENGTH (CAT DOG PONY)) #13=> 3 The length of (CAT DOG PONY) is 3. NIL 0 The PRINT-LENGTH function has been defined to find the length of its argument with the function LISP-LENGTH. The LIST-LENGTH function is traced during the call to the PRINT-LENGTH function. 12. 0 Lisp> (DEFUN FUNCTION-X (X) (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) FUNCTION-X Lisp> (TRACE (FUNCTION-X :PRE-DEBUG-IF(< (SECOND *TRACE-CALL*) 2) :SUPPRESS-IF T)) (FUNCTION-X) Lisp> (FUNCTION-X 5) 101 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) Control Stack Debugger Frame #26: (DEBUG) Debug 1> DOWN Frame #21: (BLOCK FUNCTION-X (IF (< X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Debug 1> DOWN Frame #19: (FUNCTION-X 3) Debug 1> (CADR (DEBUG-CALL)) 0 3 Debug 1> CONTINUE Control Stack Debugger Frame #19: (DEBUG) Debug 1> CONTINUE 5 0 • In this example, FUNCTION-Xis first defined. • Then the TRACE macro is called for FUNCTION-X. TRACE is specified to invoke the debugger if the first argument to FUNCTION-X (the function call being traced) is less than 2. Since the PRE-DEBUG-IF option is specified, the debugger is invoked before the call to FUNCTION-X. As t h e o :SUPPRESS-IF option has a value of T, calls to FUNCTION-X do not cause any trace output. e The DOWN command moves the pointer down the control stack. The DEBUG-CALL function returns a list representing the current debug frame function call. In this case, the CADR of the list is 3. This accesses the first argument to the function in the current stack frame. the CONTINUE command continues the evaluation • Finally FUNCTION-X. 13. Lisp> (TRACE (FUNCTION-X :POST-DEBUG-IF(> (FIRST *TRACE-VALUES*) 2))) (FUNCTION-X) Lisp> (FUNCTION-X 5) #4: (FUNCTION-X 5) . #11: (FUNCTION-X 4) #18: (FUNCTION-X 3) . #25: (FUNCTION-X 2) . #25=> 1 • #25: (FUNCTION-X 1) . • • #25=> 1 • . #18=> 2 102 0 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS TRACE Macro (cont.) 0 0 0 . . #18: (FUNCTION-X 2) . . #18=> 1 Control Stack Debugger Frame #12: (DEBUG) Debug 1> BACKTRACE -- Backtrace start -Frame #12: (DEBUG) Frame #7: (BLOCK FUNCTION-X ( IF ( < X 3) 1 (+ (FUNCTION-X (- X 1)) (FUNCTION-X (- X 2))))) Frame #5: (FUNCTION-X 5) Frame #1: (EVAL (FUNCTION-X 5)) -- Backtrace ends -Frame #12: (DEBUG) Debug 1> CONTINUE . #11=> 3 . #11: (FUNCTION-X 3) #18: (FUNCTION-X 2) #18=> 1 #18: (FUNCTION-X 1) #18=> 1 . #11=> 2 Control Stack Debugger Frame #5: (DEBUG) Debug 1> CONTINUE #4=> 5 TRACE is called for FUNCTION-X (the same function as in the previous example) to start the debugger if the value returned exceeds 2. The value returned exceeds 2 twice once when it returns 3 and at the end when it returns 5. 0 0 103 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *TRACE-CALL* Variable The *TRACE-CALL* variable, a debugging tool, is bound to the or macro call being traced. function O Examples 1. Lisp> (TRACE (FUNCTION-X :SUPPRESS-IF(> (SECOND *TRACE-CALL*) 1))) This causes FUNCTION-X argument is 1 or less 2. to be traced only if its first Lisp> (TRACE (FUNCTION-X :SUPPRESS-IF(<= (LENGTH *TRACE-CALL*) 2))) This causes FUNCTION-X to be traced if it is called with more than 1 argument. 3. Q Lisp> (TRACE (FUNCTION-X :PREDEBUG-IF (< (SECOND *TRACE-CALL*) 2) :SUPPRESS-IF(< (SECOND *TRACE-CALL*) 2))) FUNCTION-X In this case, the TRACE macro is enabled for FUNCTION-X. The debugger will be invoked and tracing suppressed if the first argument to FUNCTION-X (the SECOND of the value of the *TRACE-CALL* variable) is less than 2. So for example, if FUNCTION-Xis called with the arguments 3 and 5, *TRACE-CALL* is bound to the form (FUNCTION-X 3 5); as 3 is greater than 2, the call is traced and the debugger not entered. See the description of the TRACE macro for further examples of the use of *TRACE-CALL*. Q 0 0 104 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS *TRACE-VALUES* Variable 0 The *TRACE-VALUES* variable, a debugging tool, is bound to the list of values returned by the traced function. You can use the value bound to this variable in the forms used with the trace option keywords such as :DEBUG-IF. Example 0 0 Lisp (FACTORIAL 4) #4: (FACTORIAL 4) . #11: (FACTORIAL 3) •• #18: (FACTORIAL 2) . • • #25: (FACTORIAL 1) . • . #25=> 1 . • • #25=> *TRACE-VALUES* is (1) . • #18=> 2 •• #18=> *TRACE-VALUES* is (2) • #11=> 6 • #11=> *TRACE-VALUES* is (6) #4=> 24 #4=> *TRACE-VALUES* is (24) 24 In this case, the values returned by the FACTORIAL function and bound to the *TRACE-VALUES* variable are displayed as (1), (2), (6), and (24). Since the *TRACE~VALUES* variable is bound to the list of values returned by a function, it can be used only in the :POST- options to the TRACE macro. Before being bound to the return values, it returns NIL. See the description of the TRACE macro for further examples of the use of the *TRACE-VALUES* variable. 0 0 105 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS JNBIND-KEYBOARD-FUNCTION Function 0 Removes the binding of a function from a control character. Format UNBIND-KEYBOARD-FUNCTION control-character Argument control-character The control character from which a function's binding removed. is to be Return Value T, if a binding is removed. bound to a function. NIL, if the control character is not O Example Lisp> (BIND-KEYBOARD-FUNCTION #\FS #'BREAK) T Lisp> (UNBIND-KEYBOARD-FUNCTION #\FS) T e The call to the BIND-KEYBOARD-FUNCTION function binds <CTRL/\> to the BREAK function. e The call to the UNBIND-'KEYBOARD-FUNCTION function removes binding of the function that is bound to <CTRL/\>. 0 the 0 0 106 · 'VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS UNCOMPILE Function Q Restores· the interprete~ function definition of a symbol, if the symbol's definition was compiled with a call to the COMPILE function. The UNCOMPILE function is useful for looking at function .dffinitions and debugging. For example, if you are not satisfied with the results of a function compilation, you can uncompile the function, look at it, redefine it, and then recompile it. NOTE You cannot uncompile system functions and macros or functions and macros that were loaded from files that were compiled by the COMPILE-FILE function or the compile (-c) option of the vaxlisp command. 0 Format UNCOMPILE symbol Argument 0 symbol The symbol that repr~sents the function that is to be uncompiled. Return Value The name of the function, if the specifed symbol represents an existing compiled lambda expression and has an interpreted definition; NIL, if it does not. Q Example Lisp> (DEFUN ADD2 (FIRST SECOND) (+ FIRST SECOND)) ADD2 Lisp> (COMPILE 'ADD2) ADD2 compiled. ADD2 Lisp> (UNCOMPILE 'ADD2) ADD2 0 • The call to the DEFUN macro defines the function ADD2. • The call to the COMPILE function compiles the function ADD2. call to the UNCOMPILE function successfully restores the • The interpreted definition of the function ADD2, because the function is function. defined and 107 was compiled with th_e COMPILE --------- - - - VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS UNDEFINE-LIST-PRINT-FUNCTION Macro Disables the list-print function defined for a symbol. . If anotheO list-print function was superseded by the list-print function undefined, the older function is reenabled. Otherwise, no other list-print function exists for the given symbol. See Chapter 5 for more information about list-print functions. Format UNDEFINE-LIST-PRINT-FUNCTION symbol Argument symbol The name of the list-print function to be disabled. 0 Return Value The name of the list-print function that has been disabled. Example Lisp> (UNDEFINE-LIST-PRINT-FUNCTION MY-SETQ) MY-SETQ 0 Undefines the list-print function named MY-SETQ. 0 0 108 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS UNIVERSAL-ERROR-HANDLER Function 0 The function to which the VAX LISP system sends all errors that are signaled during program execution. By default, the VAX LISP *UNIVERSAL-ERROR-HANDLER* variable is bound to this function. The VAX LISP error handler is described in Chapter 3. Format UNIVERSAL-ERROR-HANDLER function-name error-signaling-function &REST args Arguments function-name 0 The name of the function that produced or signaled the error. error-signaling-function The name of an error-signaling function. are ERROR, CERROR, and WARN. Valid function names args Q The specified error-signaling function's arguments. Return Value Invokes the VAX LISP debugger, exits the LISP system, or NIL. returns Example 0 0 Lisp> (DEFUN CRITICAL-ERROR-HANDLER (FUNCTION-NAME ERROR-SIGNALING-FUNCTION &REST ARGS) (WHEN (OR (EQ ERROR-SIGNALING-FUNCTION 'ERROR) (EQ ERROR-SIGNALING-FUNCTION 'CERROR)) (FLASH-ALARM-LIGHT)) (APPLY #'UNIVERSAL-ERROR-HANDLER FUNCTION-NAME ERROR-SIGNALING-FUNCTION ARGS)) CRITICAL-ERROR-HANDLER Defines an error handler that checks whether a fatal or continuable error is signaled. If either type of error is signaled, the handler flashes an alarm light and then passes the error signal information to the universal error handler. For information on how to create an error handler, see Chapter 3. 109 VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS * UNIVERSAL-ERROR-HANDLER* Variable By default, this variable is bound to the VAX LISP error handler, the UNIVERSAL-ERROR-HANDLER function. If you create an error handler, you must bind the *UNIVERSAL-ERROR-HANDLER* to it. 0 Example Lisp> (DEFUN CRITICAL-ERROR-HANDLER (FUNCTION-NAME ERROR-SIGNALING-FUNCTION &REST ARGS) . (WHEN (OR (EQ ERROR-SIGNALING-FUNCTION 'ERROR) (EQ ERROR-SIGNALING-FUNCTION 'CERROR)) (FLASH-ALARM-LIGHT)) (APPLY #'UNIVERSAL-ERROR-HANDLER FUNCTION-NAME ERROR-SIGNALING-FUNCTION ARGS)) CRITICAL-ERROR-HANDLER Lisp> (LET ((*UNIVERSAL-ERROR-HANDLER* #'CRITICAL-ERROR-HANDLER)) (PERFORM-CRITICAL-OPERATION)) • The call to the DEFUN macro defines CRITICAL-ERROR-HANDLER. an error handler • The call to the special form LET binds the *UNIVERSAL-ERROR-HANDLER* variable to the error handler named CRITICAL-ERROR-HANDLER, while the PERFORM-CRITICAL-OPERATION function is evaluated. O named Q 0 \ 0 110 VAX USP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS WARN Function 0 Invokes the VAX LISP error handler. The error handler displays an error message and checks the value of the *BREAK-ON-WARNINGS* variable. If the value is NIL, the WARN functions returns NIL; if the value is not NIL, the error handler checks the value of the *ERROR-ACTION* variable. The value of the *ERROR-ACTION* va~iable can be either the :EXIT or the :DEBUG keyword. If the value is :EXIT, the error handler causes the LISP system to exit; if the value is :DEBUG, the handler invokes the VAX LISP debugger. For more information on warnings, see Chapter 3. Format WARN format-string &REST args 0 Arguments format-string The string of characters that is passed to the FORMAT function to create a warning message. args 0 The arguments that are passed to the FORMAT function as arguments for the format string. Return Value NIL. Example 0 Lisp> (DEFUN LOG-ERROR (STATUS-CODE) (LET ((MESSAGE (FIND-MESSAGE-FOR-STATUS-CODE STATUS-CODE))) (IF MESSAGE (WRITE-LINE MESSAGE *ERROR-LOG*) (WARN "There is no message for status code -D." STATUS-CODE)))) LOG-ERROR Defines a function that is an error logging facility. The function logs a message to an error log file. If the message for a status code cannot be determined, a warning is issued. 0 111 - - - - - - - ------. - - - - - - VAX LISP/ULTRIX FUNCTION, MACRO, AND VARIABLE DESCRIPTIONS WITH-GENERALIZED-PRINT-FUNCTI-ON Macro Locally enables a generalized print function when it evaluates t h ~ specified forms. See Chapter 5 for more information about using generalized print functions. Format WITH-GENERALIZED-PRINT-FUNCTION name &BODY forms Arguments name A symbol identifying the generalized print function to be enabled. The enabled generalized print function supersedes any previously enabled generalized print function for name. Q forms A call or calls to print functions. Return Value Output generated by the call or calls to print functions. 0 Example Lisp> (DEFINE-GENERALIZED-PRINT-FUNCTION PRINT-NIL-AS-LIST (OBJECT STREAM) (NULL OBJECT) ( PR INC II ( ) II STREAM) ) PRINT-NIL-AS-LIST Lisp> (WITH-GENERALIZED-PRINT-FUNCTION 'PRINT-NIL-AS-LIST (PPRINT NIL)) ( ) 0 The PPRINT call prints ( ), because the generalized print function is enabled locally and pretty printing is enabled. 0 112 10 APPENDIXES 0 0 0 0 0 0 0 0 0 APPENDIX A PERFORMANCE HINTS 0 LISP code normally does much type checking at runtime. You can reduce execution time and amount of memory required by using data structures more efficiently and by using certain programming and debugging techniques. This appendix lists what you can do to optimize the speed of execution of your LISP code and the amount of memory required. The sections also give the following information: 0 0 • Number of instructions executed by certain functions o Relative speed of certain functions compared with others can be used to achieve the same result • Explanations of why certain functions and so much time and memory • Data structure representation operations that require This information can help you choose the most efficient way to code program. a Some VAX instructions are mentioned in this appendix. Refer to the Architecture Handbook for more information on the VAX instruction set. VAX A.1 DATA STRUCTURES This section describes how to optimize the use of data your code. 0 A-1 structures in PERFORMANCE HINTS A.1.1 Integers Fixnurn arithmetic is much faster than bignum arithmetic. Therefore, if possible use numbers in the range -2**29 to 2**29-1. (The range of integers represented as fixnums in future versions is likely to be cut in half: -2**28 to 2**28-1. Keep this in mind when placing fixnum declarations in your programs.) You must use fixnum declaralions for each argument to an arithmetic function and for the result as well to generate fixnum-only in-line VAX instructions. The result must be declared to be type fixnum, and even though all input values for an arithmetic function may be fixnums, the result may not be. (That is, fixnums are not closed under arithmetic operations). 0 When fixnum declarations are used, fixnum arithmetic takes two instructions for each addition or subtraction operation (except incrementing and decrementing, which require one instruction each) and four instructions for each multiplication and division operation. Fixnum comparisons consist of a CMPL instruction and the appropriate branch; the result's type need not be declared. Q Fixnums are never allocated (they are immediate: they are always manipulated directly, rather than through pointers). Therefore, fixnum arithmetic requires less memory and less .time for garbage collect.ion than arithmetic with bignums. Bignums require two longwords for a header and enough space to represent the number in two's complement format. Therefore, working with bignums consumes much more time than working with fixnums. For example, to print 1000 factorial take~ much longer than to compute it. Much more garbage is produced while calculating the print representation than in calculating the result. A.1.2 Q Floating-Point Numbers When using floating-point arithmetic, the system allocates new space for the results. In-line code is generated only when both arguments to an arithmetic function are declared to be of the same floating-point type. In-line conversions (CVTxx) are not done. The VMS math library routines are used for complicated functions, such as trigonometric functions. Q Floating-point numbers always have a 1-longword h~ader. A.1.3 Ratios When working with ratios, the system calls the GCD function after each ratio is created, and stores the ratio in canonical form. Use the TRUNCATE or REM function when you do not need exact answers or when A-2 Q PERFORMANCE HINTS 0 you want a remainder.. The TRUNCATE function executes faster if you can declare the result to be a fixnum. The TRUNCATE and REM functions are faster than the FLOOR and MOD functions. These in turn are faster than the ROUND function. Ratios occupy two longwords; they do not have headers. A.1.4 Characters When representing characters, it is usually not necessary to specify bit and font attributes. String characters utilize an 8-bit code that is compatible with the ASCII and DIGITAL multinational standards, and with the VAX architecture. 0 The CHAR= function used without type checking is the same as the EQ function. The CHAR<, CHAR<=, CHAR>, and CHAR>= functions generate the same code as the fixnum comparisons when no type checking is required because declarations were used. This code consists of a CMPL instruction followed by the appropriate branch. Like fixnums, characters are never allocated (they are immediate), thereby requiring less memory and less time for garbage collection. Q A.1.5 Symbols Symbols let you easily associate data with a name. Symbols are interned when read by the READ function, and remain interned until they are uninterned from all packages using them. So, when you create anony~ous variables and functions, use uninterned symbols (created using the MAKE-SYMBOL or GENSYM function). 0 0 For VAX LISP, accessing a dynamic variable may require several instructions, depending on the declarations and optimizations used. Normally, accessing a dynamic variable is slower than accessing local variables but faster than accessing closed-over lexical variables. A local variable can be accessed quickly because it is stored on the stack. A closed-over variable is stored in a vector and passed to other functions that use them. Therefore, to access a closed-over variable may require several instructions. To reduce the overhead of dynamic variable access to one instruction, set the optimization declaration SPEED ·to 3 and SAFETY to O, eliminating unbound variable , checking, and thus reducing execution time. When a special variable is bound to a new value, LISP saves the symbol and its old value on the binding stack and stores the new value in the value cell of the symbol. This requires either four or five instructions. Unbinding a special variable requires one instruction. Accessing the parts of a symbol, such as its name, property list, package, and value, requires only one instruction each, .if you have A-3 - - - - - - - - - - -------·-- - - - - - - - - PERFORMANCE HINTS used the appropriate declarations to declare the variable as a symbol. However, setting a symbol's function cell is very slow. o Symbols occupy five longwords each. . A.1.6 ti Lists and Vectors Use lists when the number of elements changes often. Typically, you push elements onto and pop elements off the front of the list to simulate a stack. Conses are convenient for creating tree structures, especially when you need values only at the leaves. If you must access many values at each internal node of a tree, use structures rather than lists. Conses require two longwords. Use vectors when you must access elements often at any position. Vectors use half as much space as lists, and can cause less paging when accessed because vector elements are stored in adjacent memory locations. A simple-vector has a single-longword header. Use the noncopying (or destructive) versions of the sequence and list functions whenever possible. For example, the NCONC function is faster than the APPEND function and· the NSTRING-UPCASE function is faster than the STRING-UPCASE function. You can use the form (NREVERSE (THE LIST X)) rather than the copying version (the REVERSE function) to get elements back to their original order if you are just gathering the results in a list. To copy input lists or strings one~ and then do destructive operations is more efficient than to always use copying versions of functions. Copying vectors by using the COERCE or SUBSEQ function results in simple vectors (of the type SIMPLE-VECTOR, SIMPLE-STRING, SIMPLE-BIT-VECTOR, or SIMPLE-ARRAY) which can be manipulated by simpler, faster operations. Therefore, you can copy a vector to manipulate it quickly thereafter. However, to avoid numerous garbage collections, do not use copying versions of functions unless you must. Q O Q NOTE Use destructive versions of functions shared data may be modified. with care, as CAR, CDR, and the other list-manipulating functions by default always check their arguments to make sure they are lists and not atoms. To increase the speed of list-intensive applications, properly declare all lists and use the optimization declaration SPEED= 2 or use SPEED = 3 and SAFETY= o. The CAR, CDR, RPLACA, and RPLACD functions each require one instruction when used with these declarations. A-4 Q PERFORMANCE HINTS 0 If you frequently splice or concatenate lists, use a pointer to the middle or end of the list. This is faster than using the NTHCDR, MEMBER, APPEND, and NCONC functions on the entire list, as they always process from the beginning of the list. The fastest (and default) tests for the MEMBER, ASSOC, and RASSOC functions are EQ and EQL. Use property lists when you want values for keys to be. ~lobal in scope. Do not use property lists if the number of keys is fairly constant and known in advance. Instead, use structures and include a slot in the structure for a list to be used like a property list for the keys that change. Use association lists when you want values for keys to be dynamic in scope, since pushing entries onto the front of an association list shadows later entries. You can use dynamic variables as pointers into association lists to help you recall additions to the lists. 0 A.1. 7 Strings, General Vectors, and Bit Vectors Simple-vectors are processed faster than nonsimple vectors (vectors with fill pointers, adjustable vectors, or displaced vectors). Simple-vectors take less space since they do not have separate array headers and they are created faster. 0 0 Avoid using lists of characters when manipulating symbol names (that is, never implement EXPLODE or IMPLODE). Strings are fully supported in this language, unlike in older versions of LISP. Some common operations on simple strings use the VAX character instructions. Many data structures that used to be implemented with lists can be more efficiently implemented with simple-vectors (the default DEFSTRUCT representation). If the domain of a set is fixed and set operations are frequent, using simple bit vectors is much faster than using lists. Accessing or updating slots of a declared structure takes only one instruction given the appropriate declarations. Accessing or updating characters in a simple string or bits in a simple bit vector is slower than accessing or updating elements of a simple-vector; when accessing or updating characters in a simple string or bits in a simple bit vector, data must be converted between the internal representation and the LISP representation. For both characters and fixnums, this involves at least an ASHL instruction. However, there are specialized routines for handling simple strings iand simple bit vectors (for example, the STRING-UPCASE and BIT-AND functions with the proper declarations). These representations take less space than simple characters or bits. 0 A-5 vectors that hold PERFORMANCE HINTS A.1.8 Hash Tables Hash tables provide a good way of storing and accessing arbitraryO objects. Although some overhead is required for each access or store, the total time required is usually .reasonable even for large numbers of objects. VAX LISP hash tables use chains to resolve collisions. You can access hash tables that use the EQ and EQL functions faster than hash tables that use the EQUAL function, because the comparisons are faster. However, hash tables that use the EQ and EQL .functions must be completely rehashed after each garbage ·collection. Hash tables are preferable to lists and bit vectors for representing sets, when the number of objects may be large and extremely variable. . A.1.9 Functions Compiled code is faster than interpreted code; when is evaluated, much consing occurs. interpreted code 0 Closures are slower than regular functions. You can compile single functions at·any time without using files. For example, to compile a function you have just defined, you can use (COMPILE 'FUNCTION-NAME) or (COMPILE NIL '(LAMBDA() , ••• ) if you want to create anonymous code to be stored and executed later. You can use the FUNCTION or FTYPE type specifier in a declaration or proclamation to inform the compiler about the types of the arguments and the return type of a function. A.2 Q DECLARATIONS This section describes how to use declarations to optimize LISP code. Q By default, most standard VAX LISP functions check their arguments for type and other attributes. The compiler can generate much faster code for many simple operations by assuming the arguments are of the correct type. Therefore, use declarations to supply this information. Whether the compiler takes advantage of declarations, and to what extent it does, is controlled by the OPTIMIZE declaration. Depending on the values of the optimization options, different code may be generated, given the presence of type declarations or the assumption of such type declarations. 0 A-6 PERFORMANCE HINTS NOTE 0 Currently, the COMPILATION-SPEED option is ignored. The format for using the OPTIMIZE declaration and its options with the PROCLAIM and DECLARE functions is as follows: · • (PROCLAIM '(OPTIMIZE (SPEED x) (SAFETY y) (SPACE z))) or (DECLARE (OPTIMIZE (SPEED X) (SAFETY y) (SPACE z))) The possible switch values are: 0 x=1,y=1,z=1 (the default) No particular optimizations done. Generally, type checking be done on all arguments to LISP functions. will x=2,y<2 Observes user supplied declarations. Useful when some variables are guaranteed to be of the declared type and speed is desired, but when not all variables (such as function arguments) can be guaranteed to be correct. Some macros (such as DOTIMES and DOLIST) expand into code with these declarations already supplied. 0 x>l,y=O Skips bounds checking for vector and array references. 0 x=3,y=O Assumes correct argument types to many functions, such as CAR, SYMBOL-NAME, and SCHAR. Useful for guaranteed correct and debugged functions. Special variable references do not check for unbound values. x>y Does tail recursion removal, if it can. y=3 0 The THE function generates tests for objects being the specified type. Useful for fixnum declarations to detect overflows into bignums. A-7 PERFORMANCE HINTS x>z Tries to open-code some declarations. sequence functions. Observes in-line Q Explicit type checking code, such as (IF (CONSP X) ... ),_ is always executed regardless of a type declaration for X and the op~imization settings. Therefore, you can retain type checking and still increase the speed of execution by using declarations. In the following example, faster code is generated for incrementing .X by using the appropriate optimization settings without having to rebind X. Meanwhile, type checking is retained at the start of the function by using the explicit type checking code (IF (FIXNUMP X). (DEFUN FOO (X) (DECLARE (FIXNUM X)) (IF (FIXNUMP X) ( LET . • . ( INCF X) .•. ) (ERROR •.. ))) 0 Another function that always executes is COERCE, since it is assumed that a type check will be executed, even if no coercion needs to be done. Use fixnum and floating-point declarations for fast arithmetic. The · compiler needs to know the types of all the arguments (and for fixnums, the result type, too) before it can generate the fast, type-specific code available on a VAX. Floating-point operations with operands (and therefore results) of the same type can also generate fast code. 0 Use simple-vector and similar array declarations for fast sequence and array operations. Declaring structures is equally helpful. The PROCLAIM and DECLARE functions are used to declare a function's arguments and results whenever the function is called. For example, when the proclamation (PROCLAIM '(FTYPE (FUNCTION (FIXNUM} SINGLE-FLOAT) MYFUNCTION)) is used, each time MYFUNCTION is called the arguments are automatically declared to be fixnums and its result is automatically declared to be a single-float. An FTYPE declaration does not automatically provide declaration of the LAMBDA-LIST variable in the function definition. Q It is important to provide type declarations, .especially for the SIMPLE-VECTOR, SIMPLE-STRING, and SIMPLE-BIT-VECTOR types, for the arguments to sequence functions. The compiler can generate fast code for many common cases such as calls without any keyword arguments. Multidimensional array operations also need declarations. Unlike the vector operations, multidimensional arrays need the actual (fixnum} · bounds for each dimension at compile-time, to generate efficient array indexing code. In these cases it is helpful to use the DEFTYPE macro or a macro that expands into a call to the. DECLARE function. A-8 Q PERFORMANCE HINTS 0 The functions defined in the following examples will be compiled with either (1) type-checking code if SPEED is less than 2, or (2) non-type-checking code if SPEED equals 3 and SAFETY equals 0. However, the second example produces code that does not check the type of X but does check the type of (CDR X), when SPEED equals 2 and SAFETY is less than 2. This is because there is a declaration allowin9 the optimization of the CDR operation, but no decla\ation for the CAR operation. (DEFUN EXAMPLE1 (X) ( CADR X)) (DEFUN EXAMPLE2 (X) (DECLARE (LIST X)) ( CADR X)) 0 In the following examples, a call to EXAMPLE3 always produces generic code, since it is not known that the result of the addition will necessarily be a fixnum. The declaration in EXAMPLE4 provides that information, and all the arithmetic operations are fixnum-specific. (DEFUN EXAMPLE3 (X Y) (DECLARE (FIXNUM X Y)) (+ X Y)) 0 0 (DEFUN EXAMPLE4 (X Y) (DECLARE (FIXNUM X Y)) (THE FIXNUM (+ X Y))) The next example returns a list of the first, indexed, and last characters. With SPEED greater than or equal to 2 and SAFETY equal to 0, all the character fetching from the STRING argument will be very fast. The LENGTH operation will also be very fast,· since it need not check for the type of the argument like the generic sequence function normally would. (This also means executing the form (LENGTH (THE LIST X)) is faster than executing the form (LENGTH X).) If SAFETY is greater than 0, bounds checking is still done, but type checking (of the string, for example) may not be, depending on what optimizations are used. (DEFUN EXAMPLES (STRING INDEX) (DECLARE (SIMPLE-STRING STRING) ( FIXNUM INDEX)) (LIST (AREF STRING 0) (CHAR STRING INDEX) (SCHAR STRING (1- (LENGTH STRING))))) Array access is fast in the following code: 0 A-9 PERFORMANCE HINTS (EVAL-WHEN (COMPILE LOAD EVAL) (DEFCONSTANT I-SIZE 3) (DEFCONSTANT J-SIZE 4) (DEFCONSTANT K-SIZE 5) (DEFTYPE FOOARRAY (&OPTIONAL ELEMENT-TYPE) '(SIMPLE-ARRAY ,ELEMENT-TYPE (,I-SIZE ,J-SIZE ,K-SIZE)))) • 0 • ( DE FUN FOO ( ) (DECLARE (TYPE (FOOARRAY T) X) (TYPE (FOOARRAY STRING-CHAR) Y)) (DOTIMES (I I-SIZE) (DOTIMES (J J-SIZE) (DOTIMES (K K-SIZE) (SETF (AREF XI J K) (FOO (AREF YI J K))))))) A.3 0 PROGRAM STRUCTURE Avoid using closed-over variables (that is, lexical variables used in functions created within their scope). References to closed-over variables are slower than references to true local variables (which are stack allocated), because closed-over variables must be found in simple vectors that represent the lexical environment that may take several instructions. In tight inner loops, use macros or in-line functions rather than called functions. Always compile macros, functions declared in-line, and calls to the DEFSTRUCT macro before compiling code that uses them. Normally, you proclaim a function in-line just before de.fining it. Any calls to that function will then have the body expanded in-line at the calling site, unless you use the NOTINLINE declaration. If you declare or proclaim a function using the INLINE declaration without later providing a definition, a compiler error will result because no definition was provided for an in-line function. Q Q The FUNCALL and APPLY functions are slower than calls to functions whose names are known at compile time. This is because the LISP system must check the following: • Whether the object is a function • What kind of function interpreted or compiled) (by symbol or function object, 0 A-10 PERFORMANCE HINTS • 0 The number· of arguments the function takes The FUNCALL and APPLY functions are usually two to three times slower than a compiled call to a fixed function with a fixed number of arguments. The CATCH mechanism function. • special form and operations that use the catch-throw are slower than calling a function, using the APPLY • No more penalty is inflicted for using the lambda-list keyword &OPTIONAL than for using required arguments. However, an &REST variable causes a list to be created for those arguments passed after the required and &OPTIONAL arguments~ &KEY arguments are the slowest; they have the consing overhead of &REST keyword, plus the run-time code to parse that list and assign the proper values for the given keywords. 0 Using multiple values requires less time and space than consing a list or vector of results. Both methods are slower than just returning single values. (Consing requires garbage collections later.) The READ function is slower than the READ-LINE or READ-CHAR function, since READ has to parse the input according to the current LISP reader syntax, create numbers, and intern symbols. The READ-CHAR function is slower than the READ-LINE function, due to the general overhead of streams. 0 The WRITE, FORMAT, and PPRINT functions are slower than explicit calls to the PRINC and PRINl functions. Using the xxx-TO-STRING functions for getting a stripg representation of a LISP object is faster than using the WITH-OUTPUT-TO-STRING function. The WITH-OUTPUT-TO-STRING function must create a stream and use the usual stream functions. The READ-FROM-STRING and PARSE-INTEGER functions are faster than the WITH-INPUT-FROM-STRING function for the same reason. 0 The compiler compiles each top-level form in a file when it compiles a file by surrounding arbitrary forms in the following manner: (PROGN (DEFUN #:TOP-LEVEL-FUNCTION() (#:TOP-LEVEL-FUNCTION)) 1 0 arbitrary-top-level-form) An arbitrary-top-level-form is any LISP form other than a call to the EVAL-WHEN or PROGN special form, the DEFUN or DEFMACRO macro, the PROCLAIM function, or a package function. Creating, compiling, dumping, and loading these temporary functions takes time, so it is wise to gather many arbitrary forms into functions of reasonable size. Typically, such forms can be calls to data initialization functions (such as (SETF (GET ••• ) ••. )). To have these function calls inside a function definition anyway is desirable so that you can do selective initialization from the program without having to reload the file. A-11 PERFORMANCE HINTS A.4 COMPILER REQUIREMENTS The PROCLAIM, PROVIDE, REQUIRE, and package functions like USE-PACKAGEQ and IN-PACKAGE must be used at "top level" for the compiler to recognize them. A top-level form is defined as a form without surrounding parentheses, or a form at top level within a call to either the EVAL-WHEN or PROGN special form. Uses of the D~UN macro and anonymous lambdas that would get evaluated in code get compiled as separate functions (closures if they use closed-over variables). This is true in the following call to the DEFUN macro and to the .anonymous lambda that follows. (LET ((COUNTER 0)) (DEFUN NEXT() (INCF COUNTER))) (TRY #'(LAMBDA (X) (PRINT X))) If you want functions as data objects (that is, in data structures Q where they would not be processed during normal evaluation), you must compile them explicitly. This is exemplified by the difference between the following: (LIST #'(LAMBDA() (FOO)) # ' ( LAMBDA ( ) ( BAR ) ) and 0 ' ( # ' ( LAMBDA ( ) ( FOO ) ) #'(LAMBDA() (BAR)) In the first case, the compiler recognizes the functions and creates compiled-function objects for them. In the second case, the compiler does not notice the fucntions since the entire form is quoted. If you leave the code in the list at run time, the explicit calls to the FUNCALL function on each element of the list would run the code interpretively. So, to have compiled code in the list, you must f i l l o it with compiled functions. You can do this at run time by using the COMPILE function with NIL as the first argument, or you can fill the list with compiled functions once, when loading. Or, you can compile a file, using macros that expand into definitions of functions with names created using the GENSYM function. Then, have an initialization function fill up the list with those compiled functions at load time. 0 A-12 INDEX 0 Page numbers in the Index in the form c-n (for example, 2-13) refer to a page in Part I. Page numbers in the form n (for example, 25) refer to a page in Part II. - • ARRAY-TOTAL-SIZE-LIMIT constant, 6-6 Arrays, 6-6 constants, 6-6 creating, 61 specialized, 6-6, 61 ? debugger command description, 4-13 (table), 4-10 stepper command description, 4-26 (table), 4-25 0 0 0 0 -A- -B- Abbreviating output by lines, 5-25 Abbreviating output depth, 5-24 Abbreviating output length, 5-24 Abbreviating printed output, 5-23 Active stack frame, 4-4 Alien structure facility, 1-5 ALL debugger command modifier, 4-12 with BACKTRACE command, 4-17 with BOTTOM command, 4-15 with DOWN command, 4-15 with TOP command, 4-15 with UP command, 4-16 :ALLOCATION keyword MAKE-ARRAY function, 6-15, 61 APROPOS function debugging information, 4-1 description, 1 help, 1-6 (table), 6-25 APROPOS-LIST function debugging information, 4-1 description, 3 (table), 6-25 ,ARGUMENTS debugger command modifier, 4-12 with SET command, 4-16 with SHOW command, 4-17 ARRAY-DIMENSION-LIMIT constant, 6-6 ARRAY-RANK-LIMIT constant, 6-6 BACKTRACE debugger command description, 4-17 (table), 4-10 stepper command description, 4-27 (table), 4-24 BIND-KEYBOARD-FUNCTION function description, 4 keyboard functions, 6-20 Binding stack, 80 Bits attribute, 6-5 BOTTOM debugger command description, 4-15 (table), 4-10 BREAK function, 18 binding control character to, 4 debugging information, 4-1 description, 7 invoking the break loop, 4-4 (table), 6-25 Break loop, 1-4, 4-4 to 4-7 exiting, 4-5, 7, 18 invoking, 4-4, 7 message, 4-5 prompt, 4-5 using, 4-6 variables, 4-7 *BREAK-ON-WARNINGS* variable, 4-14 defining an error handler, 3-6 WARN function, 111 Index-1 ·INDEX -cCALL debugger command modifier, 4-12 with SHOW command, 4-17 Call-out facility, 1-5 Cancel character, 8 CANCEL-CHARACTER-TAG tag description, 8 CERROR function, 109 defining an error handler, 3-7 error messages, 3-3 CHAR-BITS-LIMIT constant, 6-6 CHAR-CODE-LIMIT constant, 6-6 CHAR-FONT-LIMIT constant, 6-6 CHAR-NAME-TABLE function, 6-6 description, 9 Characters, 6-5 attributes, 6-5 comparisons, 6-5 constants, 6-6 names, 9 Code attribute, 6-5 Command levels, 90 debugger, 4-8 stepper, 4-27 tracer, 4-34 Command modifiers See Debugger COMMON LISP, 1-2 COMPILE (-c) option compiling files, 2-7 description, 2-15 modes, 2-14 optimizing compiler, 6-22 .(table), 2-12 with ERROR_ACTION option, 2-16 with INITIALIZE option, 2-17 with LISTING option, 2-19 with MACHINE_CODE option, 2-19 with NOOUTPUT_FILE option, 2-22 with NOWARNINGS option, 2-25 with OPTIMIZE option, 2-21 with OUTPUT_FILE option, 2-22 with VERBOSE option, 2-23 COMPILE function, 1-3, 11, 107 compiler restrictions, 6-21 compiling functions and macros, 2-6 COMPILE-FILE functio, 1-4 COMPILE-FILE function, 15, 16 compiler restrictions, 6-21 COMPILE-FILE function (Cont.) compiling files, 2-7 description, 12 to 14 (table), 6-25 *COMPILE-VERBOSE* variable default for :VERBOSE_k,yword, 13 description, 15 *COMPILE-WARNINGS* variable default for :WARNINGS keyword, 13 description, 16 COMPILEDP function description, 11 Compiler, 1-3, 6-21 to 6-24 optimizations, 2-21, 6-22 to 6-24, 12 fast code, 6-23 safe code, 6-23 restrictions, 6-21 COMPILE function, 6-21 COMPILE-FILE function, 6-21 Conditional new line directives, 5-8 Constructor function allocating static space, 6-15 CONTINUE debugger command description, 4-14 (table), 4-10 function description, 18 exiting the break loop, 4-5, 0 0 0 7 Control characters binding to functions, 6-20, 4 returning information about bindings, 6-20, 51 (table), 2-3 unbinding from functions, 6-20, 106 Control·stack, 4-3 debugger, 4-7 overflow, 6-16 stack frame See Stack frame storage allocation, 80 Controlling indentation, 5-13 Controlling margins, 5-4 Controlling where new lines begin, 5-11 Index-2 0 0 INDEX 0 0 0 0 0 CPU time displaying, 91 garbage collector, 48 getting, 50 <CTRL/'\> recovering from an error, 2-3 <CTRL/C> and CANCEL-CHARACTER-TAG, 8 invoking the break loop, 2-4, 4-5 <CTRL/Z> suspending a process, 2-4 :CURRENT keyword THROW-TO-COMMAND-LEVEL function, 90 Current package, 67 Current stack frame, 4-7 -D- Data representation, 6-2 to 6-7 structure, 1-1 Data types arrays, 6-6, 61 constants, 6-6 specialized, 6-6 characters, 6-5 attributes, 6-5 comparisons, 6-5 constants, 6-6 names, 9 floating-point numbers, 6-3 constants, 6-4 integers, 6-2 constants, 6-2 numbers, 6-2 package, 3 packages, 1 pathnames, 35 strings, 6-7, 61 vectors, 61 DEBUG function debugging information, 4-1 description, 19 invoking the debugger, 4-8 stepper command description, 4-26 (table), 4-24DEBUG function binding control character to, 4 :DEBUG keyword See *ERROR-ACTION* variable DEBUG-CALL function, 4-18 description, 20 :DEBUG-IF keyword TRACE macro, 4-36, 94 • *DEBUG-IO* variable debugger, 4-8 stepper, 4-20 *DEBUG-PRINT-LENGTH* variable controlling output, 4-3 description, 21 *DEBUG-PRINT-LEVEL* variable controlling output, 4-3 description, 22 Debugger, 1-4, 4-7 to 4-20 commands arguments, 4-11 entering, 4-11 descriptions, 4-13 to 4-17 modifiers (table), 4-12 (table), 4-10 controlling output, 21, 22 error handler, 3-2 to 3-4 exiting, 4-9, 4-14 invoking, 4-8, 4-26, 4-36, 19, 94 prompt, 4-8 sample sessions, 4-18 using, 4-9 Debugging facilities, 1-4 See also Break loop, Debugger, Stepper, and Tracer Debugging functions and macros (table), 4-1 Declarations, 6-23 Default directory changing, 23 DEFAULT-DIRECTORY function, 23 See also *DEFAULT-PATHNAME-DEFAULTS* variable description, 23 *DEFAULT-PATHNAME-DEFAULTS* variable default directory, 23 DIRECTORY function, 6-13, 35 filling file specification components, 12 resuming a suspended system, 87 using, 6-13 Index-3 INDEX DEFINE-ALIEN-STRUCTURE macro allocating static space, 6-15 DEFINE-FORMAT-DIRECTIVE macro description, 25 DEFINE-GENERALIZED-PRINT -FUNCTION macro, 5-21 DEFINE-GENERALIZED-PRINTFUNCTION macro description, 28 DEFINE-LIST-PRINT- FUNCTION macro, 5-19 _ DEFINE-LIST-PRINT-FUNCTION macro description, 30 Defining list-print functions, 5-19 DEFMACRO macro creating programs, 2-5 DEFUN macro creating programs, 2-5 DELETE-PACKAGE function description, 32 DESCRIBE function debugging information, 4-1 description, 33 help, 1-6 (table), 6-25 :DEVICE keyword pathname field, 6-10 :DIRECTION keyword OPEN function, 6-19 -1 directive, 5-6 -% directive, 5-11 -& directive, 5-11 . directive, 5-6 directive, 5-11 -@_ directive, 5-11 directive, 5-28 -- directive, 5-6, 5-11 Directives for handling lists, 5-16 DIRECTORY function description, 35 pathnames, 6-13 (table), 6-25 :DIRECTORY keyword pathname field, 6-10 DO-ALL-SYMBOLS macro, 1, 3 DO-SYMBOLS macro, 1, 3 Documentation string, 33 -=-A Double floating-point numbers, 6-3 DOUBLE-FLOAT-EPSILON constant, 6-4 DOUBLE-FLOAT-NEGATIVE-EPSILON constant, 6-4 DOWN debugger command description, 4-15 (table), 4-10 debugger command modifier, 4-12 with SEARCH command, 4-15 DRIBBLE function debugging information, 4-2 description, 37 (table), 6-25 :DURING keyword TRACE macro, 4-37, 95 Dynamic memory, 2-20, 80, 87 garbage collector, 6-15, 6-16 ' 0 . 0 -E- Editor creating programs, 2-5 :ELEMENT-TYPE keyword OPEN function,_ 6-19 Enabling pretty printing, 5-3 End-of-file operations, 6-18 EQ function, 6-2 EQUAL function, 6-12 ERROR debugger command description, 4-16 (table), 4-10 function, 109 defining an error handler, 3-7 error messages, 3-2 Error listing file type, 1-9 messages compiler, 16 debugger, 4-16 error handler, 75 error-handler definition, 3-6 format, 3-2 warnings, 2-25, 16 types, 3-2 to 3-5 continuable, 3-3 fatal, 3-2 Index-4 0 0 Q INDEX 0 0 0 0 0 Error types (Cont. ) warning, 3-4, 111 Error handler, 1-4, 38 binding *UNIVERSAL-ERRORHANDLER* variable, 3-7 creating, 110 debugging information, 4-1 defining, 3-5 description, 3-1 error message, 75 invoking, 111 UNIVERSAL-ERROR-HANDLER function, 109 :ERROR keyword EXIT function, 39 *ERROR-ACTION* variable, 38 See also error_action option continuable error, 3-3 defining an error handler, 3-6 description, 38 fatal error, 3-3 WARN function, 111 warning, 3-4 *ERROR-OUTPUT* variable PRINT-SIGNALED-ERROR function, 75 Error-signaling functions, 109 (table), 3-7 ERROR_ACTION option, 2-16 See also *ERROR-ACTION* variable description, 2-16 fatal error, 3-3 modes, 2-14 (table), 2-12 with INITIALIZE option, 2-17 ESCAPE key terminal input, 6-18 EVAL function, 1-1 EVALUATE debugger command description, 4-13 (table), 4-10 stepper command description, 4-26 (table), 4-24 EXIT function description, 39 exiting LISP, 2-2 :EXIT keyword See *ERROR-ACTION* variable Extensions to the FORMAT function, 5-5 to 5-17 -F- Fast-loading file, 2-7, 2-15 file type, 1-9 loading, 56 locating, 56 producing, 12, 13 File compiling, 2-6 directory name, 1-8 host name, 1-8 loading, 2-5 name, 1-7 representation, 6-8 organization, 6-19 pathname, 1-7 specification See also Pathnames, Namestrings defaults (table), 1-9 type, 1-9 File name representation See File -/FILL directive, 5-6 FINISH stepper command description, 4-27 (table), 4-25 Floating-point numbers, 6-3 constants (table), 6-4 (table), 6-3 · Font attribute, 6-5 FORMAT function, 5-5 to 5-17 FORMAT directives user defined, 5-18 FORMAT directives in VAX LISP, 5-6 Format Directives Provided with VAX LISP, 40 FORMAT function break-loop messages, 7 error messages, 3-7 warning messages, 111 Fresh line directive, 5-11 Function compiled, 11 compiling, 2-6 defining, 2-5 definition Index-5 • INDEX Function definition (Cont.) editing, 107 pretty printing, 65 implementation-dependent (table), 6-24 interpreted, 11 interrupt garbage collector, 6-20 keyboard, 6-20 creating, 4 suspended systems, 6-20 modifying, 2-6 FUNCTION debugger command modifier, 4-12 with SET command, 4-16 with SHOW command, 4-17 GENERALIZED-PRINT-FUNCTIONENABLED-P function description, 45 GET-GC-REAL-TIME function description, 46 GET-GC-RUN-TIME functio~ description, 48 GET-INTERNAL-RUN-TIME function description, 50 (table), 6-25 GET-KEYBOARD-FUNCTION function, 4 description, 51 returning information about key bindings, 6-20 Global definitions, 4-7 variables, 4-7 GOTO debugger command description, 4-15 (table) , 4 -10 -GGarbage collector, 6-14 to 6-16 available space, 6-16 changing messages, 6-16 control stack overflow, 6-16 CPU time, 48 displaying time, 91 dynamic memory, 6-15, 6-16 elapsed time, 46 failure, 6-16 frequency of use, 6-15 interrupt functions, 6-20 invoking, 43 Jrtessage, 0 0 -H- 70 See also *POST-GC-MESSAGE* variable messages, 44, 64 See also *PRE-GC-MESSAGE* variable, *POST-GC -MESSAGE* variable run-time efficiency, 6-15 static memory, 6-15, 61 suspended systems, 2-26 GC function description, 43 *GC-VERBOSE* variable changing garbage collector messages, 6-16 description, 44 Generalized print functions, 5-21 GENERALIZED-PRINT-FUNCTIONENABLED-P function, 5-21 Handling lists, 5-16 Hash table comparing keys, 55 initial size, 54 rehash size, 52 rehash threshold, 53 HASH-TABLE-REHASH-SIZE function description, 52 HASH-TABLE-REHASH-THRESHOLD function description, 53 HASH-TABLE-SIZE function description, 54 HASH-TABLE-TEST function description, 55 HELP debugger command description, 4-13 (table), 4-10 stepper command description, 4-26 (table), 4-25 Help facilities debugger, 4-13 LISP, 1-6 stepper, 4-.26 ULTRIX, 1-6 Index-6 0 0 0 INDEX HERE debugger command modifier, 4-12 with BACKTRACE command, 4-17 with SHOW command, 4-17 :HOST keyword pathname field, 6-10 -K- Keyboard functions, 6-20 creating, 4 interrupt level, 4 specifying, 5 _ passing arguments to,~ suspended systems, 6-20 -I-L- 0 0 0 0 -I directive, 5-6 :IF-DOES-NOT-EXIST keyword LOAD function, 56 OPEN function, 6-19 :IF-EXISTS keyword OPEN function, 6-19 If-needed new line directive, 5-11 Implementation notes, 6-1 to 6-25 Improperly formed argument lists, 5-28 Indentation, 5-13 preserving, 5-9 INITIALIZE (-i) option description, 2-17 loading files, 2-5 modes, 2-14 (table), 2-12 with COMPILE option, 2-15 with RESUME option, 2-23 with VERBOSE option, 2-23 Input/Output, 6-16 to 6-20 end-of-file operations, 6-18 file organization, 6-19 functions, 6-19 #\NEWLINE character, 6-17 terminal input, 6-18 terminal output, 6-18 WRITE-CHAR function, 6-20 Insignificant stack frame, 4-4 Integers, 6-2 constants, 6-2 INTERNAL-TIME-UNITS-PER-SECOND constant, 46, 48, 50 Interpreted function definition I restoring, 107 Interpreter, 1-3 creating programs, 2-5 Interrupt functions garbage collector, 6-20 Interrupt levels keyboard functions, 4 LEAST-NEGATIVE-DOUBLE-FLOAT constant, 6-4 LEAST-NEGATIVE-LONG-FLOAT constant, 6-4 LEAST-NEGATIVE-SHORT-FLOAT constant, 6-4 LEAST-NEGATIVE-SINGLE-FLOAT constant, 6-4 LEAST-POSITIVE-DOUBLE-FLOAT constant, 6-4 LEAST-POSITIVE-LONG-FLOAT constant, 6-4 LEAST-POSITIVE-SHORT-FLOAT constant, 6-4 LEAST-POSITIVE-SINGLE-FLOAT constant, 6-4 :LEVEL keyword BIND-KEYBOARD-FUNCTION function, 4 Lexical environment compiler restrictions, 6-21 Limiting output by lines, 5-4, 5-25 -/LINEAR/ directive, 5-6 :LINES keyword WRITE and WRITE-TO-STRING, 5-3 LISP exiting, 2-2, 39 implementation notes, 6-1 to 6-25 input/output See Input/Output invoking, 2-1 program, 1-1 compiling, 2-6 creating, 2-4 loading See File programming language, 1-1 prompt, 2-1 storage allocation, 1~1 Index-7 INDEX LISP storage allocation (Cont.) See also Memory ' List-print functions, 5-19 LISTING (-L) option description, 2-19 modes, 2-14 (table), 2-12 with COMPILE option, 2-15 with NOOUTPUT_FILE option, 2-22 Listing file, 2-19 producing, 12 :LISTING keyword COMPILE-FILE function, 12 LOAD function, 2-5, 2-17 converting pathnames, 6-12 description, 56 (table), 6-25 *LOAD-VERBOSE* variable load message, 56 Logical block, 5-5 Logical names translating, 59 Long floating-point numbers, 6-3 LONG-FLOAT-EPSILON constant, 6-4 LONG-FLOAT-NEGATIVE-EPSILON constant, 6-4 LONG-SITE-NAME function description, 58 (table), 6-25 -M:MACHINE-CODE keyword COMPILE-FILE function, 12 Machine-code listing, 2-19 MACHINE-INSTANCE function description, 59 (table), 6-25 MACHINE-VERSION function description, 60 (table), 6-25 MACHINE_CODE (-a) option, 2-19 modes, 2-14 (table), 2-13 with COMPILE option, 2-15 Macro compiling, 2-6 defining, 2-5 implementation-dependent (table), 6-24 modifying, 2-6 MAKE-ARRAY function allocating static space, 6-15 description, 61 (table), 6-25 MAKE-HASH-TABLE function, 52 to ~ '---"' SS MAKE-PATHNAME function-. constructing pathnames, 6-11 setting pathnames, 6-12 Memory, 80 control stack, ·4-3 dynamic, 2-20, 80, 87 garbage collector, 6-15, 6-16 read-only, 2-20, 80, 87 static, 2-20, 61, 80, 87 garbage collector, 6-15 MEMORY _(-m) option description, 2-20 garbage collector, 6-15 modes, 2-14 (table), 2-13 Miser mode, 5-5, 5-26, 72 Miser-mode new line directive, 5-11 :MISER-WIDTH keyword WRITE and WRITE-To-·sTRING, 5-3 Modifiers See Debugger Module, 78 *MODULE-DIRECTORY* variable, 78 description, 63 Modules, 63 MOST-NEGATIVE-DOUBLE-FLOAT constant, 6-4 MOST-NEGATIVE-FIXNUM constant, 6-2 MOST-NEGATIVE-LONG-FLOAT constant, 6-4 MOST-NEGATIVE-SHORT-FLOAT constant, 6-4 MOST-NEGATIVE-SINGLE-FLOAT constant, 6-4 MOST-POSITIVE-DOUBLE-FLOAT constant,. 6-4 MOST-POSITIVE-FIXNUM constant, 6-2 MOST-POSITIVE-LONG-FLOAT constant, 6-4 MOST-POSITIVE-SHORT-FLOAT constant, 6-4 MOST-POSITIVE~SINGLE-FLOAT constant, 6-4 O 0 O Index-8 0 INDEX O Multiline mode, 5-8 Multi 1 ~ r,,., n,r,flP new 1 ine di rec ti ve, 5--~ -N- OPTIMIZE declaration, 6-22 :OPTIMIZE keyword COMPILE-FILE fun~tion, 12 OPTIMIZE option descr1pt1on, 2-21 modes, 0 0 0 - n, m/TABULAP.,, directive, 5-6 -n/FILL/ directive, 5-6, 5-16 - n/LINEAR; d1 i·ecti ve, 5-6, 5-16 -n/TABULAR/ directive, 5-17 : NAME keyvmrd pathname field, 6-10 NAMESTRING function constructing namestrings, 6-12 Namestrings, 6-8, 6-12 See also File constructing, 6-12 New lines, 5-11 #\NEWLINE character description, 6-17 -nr directive, 5-6 NOLISTING option description, 2-19 NOMACHINE_CODE option description, 2-20 NOOPTIMIZE option description, 2-21 NOOUTPUT_FILE (-n) option description, 2-22 modes, 2-15 (table), 2-13 with COMPILE option, 2-15 NORMAL debugger command modifier, 4-12 with BACKTRACE command, 4-17 \IOVERBOSE option description, 2-23 NOWARNINGS (-w) option description, 2-25 modes, 2-15 (table), 2-14 Null lexical environment break loop, 4-7 compiler restrictions, 6-21 , tracer, 4-36, 94 Numbers, 6-2 -o- 0 OPEN function, 6-19 Optimization qualities See Compiler 2.-14 ort::.mizing compiler,· 6!ii-22 ttable), 2-13 with COMPILE option, 2-15 :OUTPUT-FILE keyword COMPILE-FILE function, 13 OUTPUT_FILE (-0) option description, 2-22 modes, 2-15 (table), 2-13 with COMPILE option, 2-15 OVER stepper command description, 4-28 (table), 4-25 -P- Packages, 1, 3 current, 1, 3, 67 PARSE-NAMESTRING function constructing pathnames, 6-11 setting pathnames, 6-12 PATHNAME function constructing pathnames, 6-11 Pathnames See also File constructing, 6-11 default directory, 23 description, 6-9 DIRECTORY function, 35 fields, 6-10 (table), 6-10 functions, 6-13 Per-line prefix, 5-15 Per-line prefixes preserving, 5-9 :POST-DEBUG-IF keyword TRACE macro, 4-36, 94 *POST-GC-MESSAGE* variable, 44 changing garbage collector messages, 6-16 description, 64 :POST-PRINT keyword TRACE macro, 4-36, 95 PPR INT function, 5-2 Index-9 INDEX PPRINT-DEFINITION function, 5-2 PPRINT-DEFINITION function description, 65 PPRINT-PLIST function, 5-2 PPRINT-PLIST functi0~ description, 67 :PRE-DEBUG-IF keyword TRACE macro, 4-36, 94 *PRE-GC-MESSAGE* variable, 44 changing garbage collector messages, 6-16 description, 70 :PRE-PRINT keyword TRACE macro, 4-36, 95 Prefix, 5-14 per-line, 5-15 Preserving indentation, 5-9 Preserving per-line prefixes, 5-9 Pretty printer, 1-4 controlling margins, 73 miser mode, 72 Pretty printing, 5-1 to 5-28 :PREVIOUS keyword THROW-TO-COMMAND-LEVEL function, 90 Print control variables, 5-3 :PRINT keyword LOAD function, 56 TRACE macro, 4-36, 94 *PRINT-LENGTH*, 5-24 *PRINT-LEVEL*, 5-24 *PRINT-LINES*, 5-4, 5-25 *PRINT-LINES* variable description, 71 *PRINT-MISER-WIDTH*, 5-26 variable, 5-5 *PRINT-MISER-WIDTH* variable description, 72 *PRINT-RIGHT-MARGIN*, 5-26 variable, 5-4 *PRINT-RIGHT-MARGIN* variable description, 73 PRINT-SIGNALED-ERROR function defining an error handler, 3-6 description, 75 *PRINT-SLOT-NAMES-AS-KEYWORDS* variable description, 77 PROCLAIM function, 6-22 Prompt break loopr 4-5 debugger, 4-8 stepper, 4-20 top-level, 2-1 changing, 92 vaxlisp, 2-1 Property list pretty-print, 67 0 -QQUICK debugger command modifier, 4-12 with BACKTRACE command, 4-17 QUIT debugger command, 4-9 description, 4-14 (table), 4-10 stepper command description, 4-27 exiting stepper, 4-21 (table), 4-25 0 -R- READ-CHAR function #\NEWLINE character, 6-17 terminal input, 6-18 Read-only memory, 2-20, 80, 87 Real time displaying, 91 garbage collector, 46 REDO debugger command description, 4-14 (table), 4-10 Relative tabbing, 5-16 REQUIRE function, 63 description, 78 (table), 6-25 RESUME (-r) option, 2-26, 87 description, 2-23 modes, 2-15 (table), 2-.13 with INITIALIZE option, 2-17 with MEMORY option, 2-20 RETURN debugger command description, 4-14 (table), 4-10 key as a stepper command, 4-28 Index-10 0 0 0 INDEX 0 0 RETURN key (Cont.) entering debugger command arguments, 4-11 debugger commands, 4-10 stepper commands, 4-24 terminal input, 6-18 stepper command description, 4-28 (table), 4-25 :RIGHT-MARGIN keyword WRITE and WRITE-TO-STRING, 5-3 ROOM function debugging information, 4-2 description, 80 specifying memory, 2-20 (table), 6-25 Run-time efficiency, 6-15 -s- 0 0 0 SEARCH debugger command description, 4-15 (table), 4-10 SET debugger command description, 4-16 (table), 4-10 SETF macro changing the default directory, 23 setting pathnames, 6-12 Shell commands vaxlisp, 2-1 Short floating-point numbers, 6-3 SHORT-FLOAT-EPSILON constant, 6-4 SHORT-FLOAT-NEGATIVE-EPSILON constant, 6-4 SHORT-SITE-NAME function description, 83 (table), 6-25 SHOW debugger command description, 4-17 (table), 4-11 stepper command description, 4-27 (table), 4-25 Significant stack frame, 4-4 SIGQUIT signal and CANCEL-CHARACTER-TAG, 8 Single floating-point numbers, 6-3 SINGLE-FLOAT-EPSILON constant, 6-4 SINGLE-FLOAT-NEGATIVE-EPSILON constant, 6-4 . !J Source file compiling, 12 file type, 1-9 loading, 56 locating, 56 Specialized arrays, 6-6 Stack frame, 4-3 active, 4-4 current, 4-7 insignificant, 4-4 number debugger command argument, 4-12 stepper output, 4-22 tracer output, 4-34 significant, 4-4 *STANDARD-OUTPUT* variable LOAD function, 56 PPRINT-DEFINITION function, 65 PPRINT-PLIST function, 68 :STATIC keyword See :ALLOCATION keyword Static memory, 2-20, 61, 80, 87 garbage collector, 6-15 Status return, 39 STEP debugger command description, 4-14 (table), 4-11 macro debugging information, 4-2 invoking stepper, 4-20 stepper command description, 4-28 (table), 4-25 Step macro description, 84 *STEP-ENVIRONMENT* variable, 4-28 description, 85 *STEP-FORM* variable, 4-28 description, 86 :STEP-IF keyword TRACE macro, 4-36, 95. Index-11 INDEX Stepper, 1-4, 4-20 to 4-32 commands arguments, 4-25 descriptions, 4-26 to 4-28 (table), 4-24 exiting, 4-21, 4-27 invoking, 4-14, 4-20, 4-36, 84, 95 output, 4-21 controlling, 21, 22 prompt, 4-20 sample sessions, 4-31 using, 4-24 Storage allocation, 1-1 See also Memory Streams, 87 Strings, 6-7 creating, 61 :SUCCESS keyword EXIT function, 39 Suffix, 5-14 :SUPPRESS-IF keyword TRACE macro, 4-37, 95 SUSPEND function creating suspended systems, 2-26 description, 87 Suspended systems, 87 creating, 2-26 file type, 1-9 garbage collector, 2-26 Internal time, 48 keyboard functions, 6-20 real time, 46 resuming, 2-23, 2-26 symbolic expressions, 1-1 -T- -T directive, 5-15 Tab directive, 5-15 Tabs, 5-15 -/TABULAR/ directive, 5-6 Terminal input, 6-18 *TERMINAL-IO* variable BIND-KEYBOARD-FUNCTION function, 5 end-of-file operations, 6-18 TERPRI function #\NEWLINE character, 6-17 THROW-TO-COMMAND-LEVEL function description, 90 TIME macro debugging information, 4-2 description, 91 (table), 6-25 TOP debugger command description, 4-15 (table) , 4-11. debugger command modifier, 4-12 with BACKTRACE command, 4-17 :TOP keyword THROW-TO-COMMAND-LEVEL function, 90 Top-level loop prompt, 2-1 variables, 2-2 *TOP-LEVEL-PROMPT* variable description, 92 TRACE macro debugging information, 4-2 description, 93 enabling the tracer, 4-33 options, 4-35 (table), 6-25 *TRACE-CALL* Variable description, 104 variable, 4-37 *TRACE-OUTPUT* variable stepper, 4-20 tracer, 4-32 *TRACE-VALUES* variable, 4-38 description, 105 Tracer, 1-4, 4-32 to 4-39 disabling, 4-33 enabling, 4-33, 93 options adding to output, 4-36 defining when to trace a function, 4-37 invoking the debugger, 4-36 invoking the stepper, 4-36 removing information from output, 4-37 options (table), 94 output, 4-34 controlling, 21, 22 : TYPE keyword. pathname field, 6-10 Index-12 0 0 0 0 0 INDEX 0 -uULTRIX commands vaxlisp, 1-3 ULTRIX file specification See File UNBIND-KEYBOARD-FUNCTION function, 4 description, 106 unbinding control characters, 6-20 UNCOMPILE function description, 107 retrieving interpreted definitions, 2-6 Unconditional new line directive, 0 0 0 5-11 UNDEFINE-LIST-PRINT-FUNCTION macro, 5-20 UNDEFINE-LIST-PRINT-FUNCTION macro description, 108 UNIVERSAL-ERROR-HANDLER function, 3-1 defining an error handler, 3-6 description, 109 *UNIVERSAL-ERROR-HANDLER* variable, 3-5, 109 description, 110 UNTRACE macro debugging information, 4-2 disabling the tracer, 4-33 UP debugger command description, 4-16 (table), 4-11 debugger command modifier, 4-13 SEARCH debugger command, 4-15 stepper command description, 4-28 (table), 4-25 User defined FORMAT directives, 5-18 -v- 0 Variable print control, 5-3 vaxlisp command, 1-3, 2-1 option descriptions, 2-9 to 2-25 vaxlisp command (Cont.) option modes (table), 2-14 options (table),. 2-12 Vectors creating, 61 VERBOSE (-v} option description, 2-23 loading files, 2-5 modes, 2-15 (table}, 2-13 with COMPILE option, 2-15 with INITIALIZE option, 2-17 with LISTING option, 2-19 with NOOUTPUT_FILE option, 2-22 VERBOSE debugger command modifier, 4-13 with BACKTRACE command, 4-17 :VERBOSE keyword COMPILE-FILE function, 13, 15 LOAD function, 56 :VERSION keyword pathname field, 6-10 -w-w directive, 5-6 WARN function, 109 description, 111 error messages, 3-4 (table), 6-25. . WARNING function defining an error handler, 3-7 :WARNINGS keyword COMPILE-FILE function, 13, 16 WARNINGS option modes, 2-15 (table), 2-14 with COMPILE option, 2-15 WHERE debugger command description, 4-16 (table), 4-11 :WILD keyword See :TYPE and :NAME keywords WITH-GENERALIZED-PRINT-FUNCTION macro, 5-22 WITH-GENERALIZED-PRINT-FUNCTION macro description, 112 WRITE FORMAT directive, 5-7 Index-13 INDEX WRITE function pretty-printing control keywords, 5-3 WRITE-CHAR function, 6-19, 6-20 #\NEWLINE character, 6-17 WRITE-STRING function, 6-17 WRITE-TO-STRING function pretty-printing control keywords, 5-3 0 0 0 0 0 Index-14
Home
Privacy and Data
Site structure and layout ©2025 Majenko Technologies