XLISP-PLUS: Another Object-oriented Lisp Version 3.0 January 15, 1997 Tom Almy almy@teleport.com Portions of this manual and software are from XLISP which is Copyright (c) 1988, by David Michael Betz, all rights reserved. Mr. Betz grants permission for unrestricted non-commercial use. Portions of XLISP-PLUS from XLISP-STAT are Copyright (c) 1988, Luke Tierney. UNIXSTUF.C is from Winterp 1.0, Copyright 1989 Hewlett-Packard Company (by Niels Mayer). Other enhancements and bug fixes are provided without restriction by Tom Almy, Mikael Pettersson, Neal Holtz, Johnny Greenblatt, Ken Whedbee, Blake McBride, Pete Yadlowsky, and Richard Zidlicky. See source code for details. Table of Contents INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 XLISP COMMAND LOOP . . . . . . . . . . . . . . . . . . . . . . . . . . 2 BREAK COMMAND LOOP . . . . . . . . . . . . . . . . . . . . . . . . . . 4 DATA TYPES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 THE EVALUATOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 HOOK FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 LEXICAL CONVENTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 10 8 BIT ASCII CHARACTERS . . . . . . . . . . . . . . . . . . . . . . . . 12 READTABLES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 SYMBOL CASE CONTROL . . . . . . . . . . . . . . . . . . . . . . . . . . 15 PACKAGES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 LAMBDA LISTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 GENERALIZED VARIABLES . . . . . . . . . . . . . . . . . . . . . . . . . 20 OBJECTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 SYMBOLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 EVALUATION FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . 27 MULTIPLE VALUE FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . 29 SYMBOL FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 GENERALIZED VARIABLE FUNCTIONS . . . . . . . . . . . . . . . . . . . . 33 PACKAGE FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 PROPERTY LIST FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . 39 HASH TABLE FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . 40 ARRAY FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 SEQUENCE FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 42 LIST FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 DESTRUCTIVE LIST FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . 54 ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . 55 BITWISE LOGICAL FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . 60 XLISP-PLUS 3.0 Table of Contents STRING FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 CHARACTER FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 66 STRUCTURE FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 68 OBJECT FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 PREDICATE FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 72 CONTROL CONSTRUCTS . . . . . . . . . . . . . . . . . . . . . . . . . . 77 LOOPING CONSTRUCTS . . . . . . . . . . . . . . . . . . . . . . . . . . 80 THE PROGRAM FEATURE . . . . . . . . . . . . . . . . . . . . . . . . . . 81 INPUT/OUTPUT FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . 83 THE FORMAT FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . . 86 FILE I/O FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 89 STRING STREAM FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . 94 DEBUGGING AND ERROR HANDLING FUNCTIONS . . . . . . . . . . . . . . . . 95 SYSTEM FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 ADDITIONAL FUNCTIONS AND UTILITIES . . . . . . . . . . . . . . . . . . 104 COMPILATION OPTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 109 BUG FIXES AND EXTENSIONS . . . . . . . . . . . . . . . . . . . . . . . 111 EXAMPLES: FILE I/O FUNCTIONS . . . . . . . . . . . . . . . . . . . . . 121 INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 XLISP-PLUS 3.0 INTRODUCTION Page 1 INTRODUCTION XLISP-PLUS is an enhanced version of David Michael Betz's XLISP to have additional features of Common Lisp. XLISP-PLUS is distributed for the IBM- PC family and for UNIX, but can be easily ported to other platforms. Complete source code is provided (in "C") to allow easy modification and extension. Since XLISP-PLUS is based on XLISP, most XLISP programs will run on XLISP- PLUS. Since XLISP-PLUS incorporates many more features of Common Lisp, many small Common Lisp applications will run on XLISP-PLUS with little modification. See the section starting on page 111 for details of the differences between XLISP and XLISP-PLUS. Many Common Lisp functions are built into XLISP-PLUS. In addition, XLISP defines the objects 'Object' and 'Class' as primitives. 'Object' is the only class that has no superclass and hence is the root of the class heirarchy tree. 'Class' is the class of which all classes are instances (it is the only object that is an instance of itself). This document is a brief description of XLISP-PLUS. It assumes some knowledge of LISP and some understanding of the concepts of object-oriented programming. You will probably also need a copy of "Common Lisp: The Language" by Guy L. Steele, Jr., published by Digital Press to use as a reference for some of the Common Lisp functions that are described only briefly in this document. XLISP-PLUS has a number of compilation options to to eliminate groups of functions and to tailor itself to various environments. Unless otherwise indicated this manual assumes all options are enabled and the system dependent code is as complete as that provided for the MS/DOS environment. Assistance for using or porting XLISP-PLUS can be obtained on the USENET newsgroup comp.lang.lisp.x, or by writing to Tom Almy at the Internet address almy@teleport.com, http://www.teleport.com/~almy/xlisp.html. You can also reach Tom by writing to him at 17830 SW Shasta Trail, Tualatin, OR 97062, USA. XLISP-PLUS 3.0 XLISP COMMAND LOOP Page 2 XLISP COMMAND LOOP When XLISP is started, it first tries to load the workspace "xlisp.wks", or an alternative file specified with the "-wfilename" option, from the current directory. If that file doesn't exist, or the "-w" flag is in the command line, XLISP builds an initial workspace, empty except for the built-in functions and symbols. Then, providing no workspace file was loaded, XLISP attempts to load "init.lsp" from a path in XLPATH or the current directory. This file can be modified to suit the user's requirements. It contains a number of preference items. If *startup-functions* is non-nil (default is nil), it is taken as a list of functions with no arguments which are executed in sequence at this time. This allows automatically starting applications stored in workspaces. If the variable *load-file-arguments* is non-nil (default is "t"), it then loads any files named as parameters on the command line (after appending ".lsp" to their names). If the "-v" flag is in the command line, then the files are loaded verbosely. The option "-tfilename" will open a transcript file of the name "filename". At this time the top level command loop is entered. This is the function TOP-LEVEL-LOOP, by default. XLISP then issues the following prompt (unless standard input has been redirected): > This indicates that XLISP is waiting for an expression to be typed. If the current package is other than USER, the the package name is printed before the ">". When a complete expression has been entered, XLISP attempts to evaluate that expression. If the expression evaluates successfully, XLISP prints the result and then returns for another expression. The following control characters can be used while XLISP is waiting for input: Backspace delete last character Del delete last character tab tabs over (treated as space by XLISP reader) ctrl-C goto top level ctrl-G cleanup and return one level ctrl-Z end of file (returns one level or exits program) ctrl-P proceed (continue) ctrl-T print information Under MS-DOS or OS/2 (at least) the following control characters can be typed while XLISP is executing (providing standard input has not been redirected away from the console): XLISP-PLUS 3.0 XLISP COMMAND LOOP Page 3 ctrl-B BREAK -- enter break loop ctrl-S Pause until another key is struck ctrl-C go to top level ctrl-T print information Under MS-DOS if the global variable *dos-input* is set non-NIL, DOS is used to read entire input lines. Operation this way is convenient if certain DOS utilities, such as CED, are used, or if XLISP is run under an editor like EPSILON. In this case, normal command line editing is available, but the control keys will not work (in particular, ctrl-C will cause the program to exit!). Use the XLISP functions top-level, clean-up, and continue instead of ctrl-C, ctrl-G, and ctrl-P. Under MS-DOS if the global variable *dos-input* is NIL, or under OS/2 or Windows, a special internal line editor is used. In this case the last 20 lines are saved, and can be recalled and viewed using the up and down arrow keys. Duplicate lines are not saved. An additional feature is symbol name lookup. This command takes what appears to be an incomplete symbol name to the left of the cursor and prints all interned symbol names that match. The control keys for the editor are: Up Arrow Previous command in queue Down Arrow Next command in queue Left Arrow Move cursor to left Right Arrow Move cursor to right Home Move cursor to start of line End Move cursor to end of line Delete Delete character at cursor Backspace Delete character to left of cursor Escape Delete current line Tab Look up partial symbol name to left of cursor Characters are inserted at the current cursor position. Lines are limited in length to the width of the display, and invalid keystrokes cause the bell to ring. XLISP-PLUS 3.0 BREAK COMMAND LOOP Page 4 BREAK COMMAND LOOP When XLISP encounters an error while evaluating an expression, it attempts to handle the error in the following way: If the symbol '*breakenable*' is true, the message corresponding to the error is printed. If the error is correctable, the correction message is printed. If the symbol '*tracenable*' is true, a trace back is printed. The number of entries printed depends on the value of the symbol '*tracelimit*'. If this symbol is set to something other than a number, the entire trace back stack is printed. XLISP then enters a read/eval/print loop to allow the user to examine the state of the interpreter in the context of the error. This loop differs from the normal top-level read/eval/print loop in that if the user invokes the function 'continue', XLISP will continue from a correctable error. If the user invokes the function 'clean-up', XLISP will abort the break loop and return to the top level or the next lower numbered break loop. When in a break loop, XLISP prefixes the break level to the normal prompt. If the symbol '*breakenable*' is NIL, XLISP looks for a surrounding errset function. If one is found, XLISP examines the value of the print flag. If this flag is true, the error message is printed. In any case, XLISP causes the errset function call to return NIL. If there is no surrounding errset function, XLISP prints the error message and returns to the top level. If XLISP was invoked with the command line argument "-b" then XLISP assumes it is running in batch mode. In batch mode any uncaught error will cause XLISP to exit after printing the error message. XLISP-PLUS 3.0 DATA TYPES Page 5 DATA TYPES There are several different data types available to XLISP-PLUS programmers. Typical implementation limits are shown for 32 bit word systems. Values in square brackets apply to 16 bit MS-DOS and Windows implementations. All data nodes are effectively cons cells consisting of two pointers and one or two bytes of identification flags (9 or 10 bytes per cell). Node space is managed and garbage collected by XLISP. Array and string storage is either allocated by the C runtime or managed and garbaged collected by XLISP (compilation option). If C does the allocation, memory fragmentation can occur. Fragmentation can be eliminated by saving the image and restarting XLISP-PLUS. NIL Unlike the original XLISP, NIL is a symbol (although not in the *obarray*), to allowing setting its properties. lists Either NIL or a CDR-linked list of cons cells, terminated by a symbol (typically NIL). Circular lists are allowable, but can cause problems with some functions so they must be used with care. arrays The CDR field of an array points to the dynamically allocated data array, while the CAR contains the integer length of the array. Elements in the data array are pointers to other cells [Size limited to about 16360]. character strings Implemented like arrays, except string array is byte indexed and contains the actual characters. Note that unlike the underlying C, the null character (value 0) is valid. [Size limited to about 65500] symbols Implemented as a 4 element array. The elements are value cell, function cell, property list, and print name (a character string node). Print names are limited to 100 characters. There are also flags for constant and special. Values bound to special symbols (declared with DEFVAR or DEFPARAMETER) are always dynamically bound, rather than being lexically bound. fixnums (integers) Small integers (> -129 and <256) are statically allocated and are thus always EQ integers of the same value. The CAR field is used to hold the value, which is a 32 bit signed integer. bignums (integers) Big integers which don't fit in fixnums are stored in a special structure. Part of the bignum extension compilation option, when absent fixnums will overflow into flonums. Fixnums and flonums are collectively referred to as "integers". [size limit is about 65500 characters for printing or about 500000 bits for calculations]. XLISP-PLUS 3.0 DATA TYPES Page 6 ratios The CAR field is used to hold the numerator while the CDR field is used to hold the denominator. The numerator and denominator are stored as either both bignums or both fixnums. All ratios results are returned in reduced form, and are returned as integers if the denominator is 1. Part of the bignums extension. Ratios and integers are collectively referred to as rationals. characters All characters are statically allocated and are thus EQ characters of the same value. The CAR field is used to hold the value. In XLISP characters are "unsigned" and thus range in value from 0 to 255. flonums (floating point numbers) The CAR and CDR fields hold the value, which is typically a 64 bit IEEE floating point number. Flonums and rational numbers are collectively referred to as real numbers. complex numbers Part of the math extension compilation option. The CAR field is used to hold the real part while the CDR field is used to hold the imaginary part. The parts can be either both rationals (ratio or integer) or both flonums. Any function which would return an integer complex number with a zero imaginary part returns just the real integer. objects Implemented as an array of instance variable count plus one elements. The first element is the object's class, while the remaining arguments are the instance variables. streams (file) The CAR and CDR fields are used in a system dependent way as a file pointer. streams (unnamed -- string) Implemented as a tconc-style list of characters. subrs (built-in functions) The CAR field points to the actual code to execute, while the CDR field is an internal pointer to the name of the function. fsubrs (special forms) Same implementation as subrs. closures (user defined functions) Implemented as an array of 11 elements: 1. name symbol or NIL 2. 'lambda or 'macro 3. list of required arguments 4. optional arguments as list of ( ) triples. 5. &rest argument 6. &key arguments as list of ( ) quadruples. 7. &aux arguments as list of ( ) pairs. 8. function body 9. value environment (see page 96 for format) 10. function environment 11. argument list (unprocessed) structures Implemented as an array with first element being a pointer to the structure name string, and the remaining elements being the structure elements. XLISP-PLUS 3.0 DATA TYPES Page 7 hash-tables Implemented as a structure of varying length with no generalized accessing functions, but with a special print function (print functions not available for standard structures). random-states Implemented as a structure with a single element which is the random state (here a fixnum, but could change without impacting xlisp programs). packages Implemented using a structure. Packages must only be manipulated with the functions provided. XLISP-PLUS 3.0 THE EVALUATOR Page 8 THE EVALUATOR The process of evaluation in XLISP: Strings, characters, numbers of any type, objects, arrays, structures, streams, subrs, fsubrs and closures evaluate to themselves. Symbols act as variables and are evaluated by retrieving the value associated with their current binding. Lists are evaluated by examining the first element of the list and then taking one of the following actions: If it is a symbol, the functional binding of the symbol is retrieved. If it is a lambda expression, a closure is constructed for the function described by the lambda expression. If it is a subr, fsubr or closure, it stands for itself. Any other value is an error. Then, the value produced by the previous step is examined: If it is a subr or closure, the remaining list elements are evaluated and the subr or closure is applied to these evaluated expressions. If it is an fsubr, the fsubr is called with the remaining list elements as arguments (unevaluated). If it is a macro, the macro is expanded with the remaining list elements as arguments (unevaluated). The macro expansion is then evaluated in place of the original macro call. If the symbol *displace-macros* is not NIL, then the expanded macro will (destructively) replace the original macro expression. This means that the macro will only be expanded once, but the original code will be lost. The displacement will not take place unless the macro expands into a list. The standard XLISP practice is the macro will be expanded each time the expression is evaluated, which negates some of the advantages of using macros. XLISP-PLUS 3.0 HOOK FUNCTIONS Page 9 HOOK FUNCTIONS The evalhook and applyhook facility are useful for implementing debugging programs or just observing the operation of XLISP. It is possible to control evaluation of forms in any context. If the symbol '*evalhook*' is bound to a function closure, then every call of eval will call this function. The function takes two arguements, the form to be evaluated and execution environment. During the execution of this function, *evalhook* (and *applyhook*) are dynamically bound to NIL to prevent undesirable recursion. This "hook" function returns the result of the evaluation. If the symbol '*applyhook*' is bound to a function, then every function application within an eval will call this function (note that the function apply, and others which do not use eval, will not invoke the apply hook function). The function takes two arguments, the function closure and the argument list (which is already evaluated). During execution of this hook function, *applyhook* (and *evalhook*) are dynamically bound to NIL to prevent undesired recursion. This function is to return the result of the function application. Note that the hook functions cannot reset *evalhook* or *applyhook* to NIL, because upon exit these values will be reset. An excape mechanism is provided -- execution of 'top-level', or any error that causes return to the top level, will unhook the functions. Applications should bind these values either via 'progv', 'evalhook', or 'applyhook'. The functions 'evalhook' and 'applyhook' allowed for controlled application of the hook functions. The form supplied as an argument to 'evalhook', or the function application given to 'applyhook', are not hooked themselves, but any subsidiary forms and applications are. In addition, by supplying NIL values for the hook functions, 'evalhook' can be used to execute a form within a specific environment passed as an argument. An additional hook function exists for the garbage collector. If the symbol '*gc-hook*' is bound to a function, then this function is called after every garbage collection. The function has two arguments. The first is the total number of nodes, and the second is the number of nodes free. The return value is ignored. During the execution of the function, *gc-hook* is dynamically bound to NIL to prevent undesirable recursion. XLISP-PLUS 3.0 LEXICAL CONVENTIONS Page 10 LEXICAL CONVENTIONS The following conventions must be followed when entering XLISP programs: Comments in XLISP code begin with a semi-colon character and continue to the end of the line. Except when escape sequences are used, symbol names in XLISP can consist of any sequence of non-blank printable characters except the terminating macro characters: ( ) ' ` , " ; and the escape characters: \ | In addition, the first character may not be '#' (non-terminating macro character), nor may the symbol have identical syntax with a numeric literal. Uppercase and lowercase characters are not distinguished within symbol names because, by default, lowercase characters are mapped to uppercase on input. Any printing character, including whitespace, may be part of a symbol name when escape characters are used. The backslash escapes the following character, while multiple characters can be escaped by placing them between vertical bars. At all times the backslash must be used to escape either escape characters. For semantic reasons, certain chararacter sequences should/can never be used as symbols in XLISP. A single period is used to denote dotted lists. The symbol T is also reserved for use as the truth value. The symbol NIL represents an empty list. Symbols starting with a colon are keywords, and will always evaluate to themselves. When the package facility is compiled as part of XLISP, colons have a special significance. Thus colons should not be used as part of a symbol name, except for these special uses. Integer literals consist of a sequence of digits optionally beginning with a sign ('+' or '-'). Unless the bignum extension is used, the range of values an integer can represent is limited by the size of a C 'long' on the machine on which XLISP is running. The radix of the literal is determined by the value of the variable *read-base* if it has an integer value within the range 2 to 36. However the literal can end with a period '.' in which case it is treated as a decimal number. It is generally not a good idea to assign a value to *read-base* unless you are reading from a file of integers in a non-decimal radix. Use the read macros instead to specify the base explicitly. Ratio literals consist of two integer literals separated by a slash character ('/'). The second number, the denominator, must be positive. Ratios are automatically reduced to their cannonical form; if they are integral, then they are reduced to an integer. XLISP-PLUS 3.0 LEXICAL CONVENTIONS Page 11 Flonum (floating point) literals consist of a sequence of digits optionally beginning with a sign ('+' or '-') and including one or both of an embedded (not trailing) decimal point or a trailing exponent. The optional exponent is denoted by an 'E' or 'e' followed by an optional sign and one or more digits. The range of values a floating point number can represent is limited by the size of a C 'double' on most machines on which XLISP is running. Numeric literals cannot have embedded escape characters. If they do, they are treated as symbols. Thus '12\3' is a symbol even though it would appear to be identical to '123'. Conversely, symbols that could be interpreted as numeric literals in the current radix must have escape characters. Complex literals are constructed using a read-macro of the format #C(r i), where r is the real part and i is the imaginary part. The numeric fields can be any valid real number literal. If either field has a flonum literal, then both values are converted to flonums. Rational (integer or ratio) complex literals with a zero imaginary part are automatically reduced to rationals. Character literals are handled via the #\ read-macro construct: #\ == the ASCII code of the printing character #\newline == ASCII linefeed character #\space == ASCII space character #\rubout == ASCII rubout (DEL) #\C- == ASCII control character #\M- == ASCII character with msb set (Meta character) #\M-C- == ASCII control character with msb set Literal strings are sequences of characters surrounded by double quotes (the " read-macro). Within quoted strings the '\' character is used to allow non-printable characters to be included. The codes recognized are: \\ means the character '\' \n means newline \t means tab \r means return \f means form feed \nnn means the character whose octal code is nnn XLISP-PLUS 3.0 8 BIT ASCII CHARACTERS Page 12 8 BIT ASCII CHARACTERS When used in an IBM PC environment (or perhaps others), XLISP-PLUS is compiled by default to allow the full use of the IBM 8 bit ASCII character set, including all characters with diacritic marks. Note that using such characters will make programs non-portable. XLISP-PLUS can be compiled for standard 7 bit ASCII if desired for portability. When 8 bit ASCII is enabled, the following system characteristics change: Character codes 128 to 254 are marked as :constituent in the readtable. This means that any of the new characters (except for the nonprinting character 255) can be symbol constituent. Alphabetic characters which appear in both cases, such as and , are considered to be alphabetical for purposes of symbol case control, while characters such as that have no coresponding upper case are not considered to be alphabetical. The reader is extended for the character data type to allow all the additional characters (except code 255) to be entered literally, for instance "#\". These characters are also printed literally, rather than using the "M-" construct. Code 255 must still be entered as, and will be printed as, "#\M-Rubout". Likewise strings do not need and will not use the backslash escape mechanism for codes 128 to 254. The functions alphanumericp, alpha-char-p, upper-case-p, and lower-case-p perform as would be expected on the extended characters, treating the diacritic characters as their unadorned counterparts. As per the Common Lisp definition, both-case-p will only indicate T for characters available in both cases. XLISP-PLUS 3.0 READTABLES Page 13 READTABLES The behaviour of the reader is controlled by a data structure called a "readtable". The reader uses the symbol *readtable* to locate the current readtable. This table controls the interpretation of input characters -- if it is changed then the section LEXICAL CONVENTIONS may not apply. The readtable is an array with 256 entries, one for each of the extended ASCII character codes. Each entry contains one of the following values, with the initial entries assigned to the values indicated: :white-space A whitespace character - tab, cr, lf, ff, space (:tmacro . fun) terminating readmacro - ( ) " , ; ' ` (:nmacro . fun) non-terminating readmacro - # :sescape Single escape character - \ :mescape Multiple escape character - | :constituent Indicating a symbol constituent (all printing characters not listed above) NIL Indicating an invalid character (everything else) In the case of :TMACRO and :NMACRO, the "fun" component is a function. This can either be a built-in readmacro function or a lambda expression. The function takes two parameters. The first is the input stream and the second is the character that caused the invocation of the readmacro. The readmacro function should return NIL to indicate that the character should be treated as white space or a value consed with NIL to indicate that the readmacro should be treated as an occurance of the specified value. Of course, the readmacro code is free to read additional characters from the input stream. A :nmacro is a symbol constituent except as the first character of a symbol. As an example, the following read macro allows the square brackets to be used as a more visibly appealing alternative to the SEND function: (setf (aref *readtable* (char-int #\[)) ; #\[ table entry (cons :tmacro (lambda (f c &aux ex) ; second arg is not used (do () ((eq (peek-char t f) #\])) (setf ex (append ex (list (read f))))) (read-char f) ; toss the trailing #\] (cons (cons 'send ex) NIL)))) (setf (aref *readtable* (char-int #\])) (cons :tmacro (lambda (f c) (error "misplaced right bracket")))) XLISP-PLUS 3.0 READTABLES Page 14 XLISP defines several useful read macros: ' == (quote ) ` == (backquote ) , == (comma ) ,@ == (comma-at ) #' == (function ) #(...) == an array of the specified expressions #S( [ ]...) == structure of specified type and initial values #. == result of evaluating #d == a decimal number (integer or ratio) #x == a hexadecimal integer or ratio (0-9,A-F) #o == an octal integer or ratio (0-7) #b == a binary integer or ratio (0-1) #r == an integer or ratio in base , 2-36 #| |# == a comment #: == an uninterned symbol #C(r i) == a complex number #+ == conditional on feature expression true #- == conditional on feature expression false A feature expression is either a symbol or a list where the first element is AND, OR, or NOT and any remaining elements (NOT requires exactly one) are feature expressions. A symbol is true if it is a member (by test function EQ) of the list in global variable *FEATURES*. Init.lsp defines one initial feature, :XLISP, and the features :TIMES, :GENERIC, :POSFCNS (various position functions), :MATH (complex math), :BIGNUMS (bignums and ratios), :PC8 (character set), :PACKAGES, and :MULVALS depending on the coresponding feature having been compiled into the XLISP executable. Utility files supplied with XLISP-PLUS generally add new features which are EQ to the keyword made from their file names. XLISP-PLUS 3.0 SYMBOL CASE CONTROL Page 15 SYMBOL CASE CONTROL XLISP-PLUS uses two variables, *READTABLE-CASE* and *PRINT-CASE* to determine case conversion during reading and printing of symbols. *READTABLE-CASE* can have the values :UPCASE :DOWNCASE :PRESERVE or :INVERT, while *PRINT-CASE* can have the values :UPCASE :DOWNCASE or :CAPITALIZE. By default, or when other values have been specified, both are :UPCASE. When *READTABLE-CASE* is :UPCASE, all unescaped lowercase characters are converted to uppercase when read. When it is :DOWNCASE, all unescaped uppercase characters are converted to lowercase. This mode is not very useful because the predefined symbols are all uppercase and would need to be escaped to read them. When *READTABLE-CASE* is :PRESERVE, no conversion takes place. This allows case sensitive input with predefined functions in uppercase. The final choice, :INVERT, will invert the case of any symbol that is not mixed case. This provides case sensitive input while making the predefined functions and variables appear to be in lowercase. The printing of symbols involves the settings of both *READTABLE-CASE* and *PRINT-CASE*. When *READTABLE-CASE* is :UPCASE, lowercase characters are escaped (unless PRINC is used), and uppercase characters are printed in the case specified by *PRINT-CASE*. When *READTABLE-CASE* is :DOWNCASE, uppercase characters are escaped (unless PRINC is used), and lowercase are printed in the case specified by *PRINT-CASE*. The *PRINT-CASE* value of :CAPITALIZE means that the first character of the symbol, and any character in the symbol immediately following a non-alphabetical character are to be in uppercase, while all other alphabetical characters are to be in lowercase. The remaining *READTABLE-CASE* modes ignore *PRINT-CASE* and do not escape alphabetic characters. :PRESERVE never changes the case of characters while :INVERT inverts the case of any non mixed-case symbols. There are five major useful combinations of these modes: A: *READTABLE-CASE* :UPCASE *PRINT-CASE* :UPCASE "Traditional" mode. Case insensitive input; must escape to put lowercase characters in symbol names. Symbols print exactly as they are stored, with lowercase characters escaped when PRIN1 is used. B: *READTABLE-CASE* :UPCASE *PRINT-CASE* :DOWNCASE "Eyesaver" mode. Case insensitive input; must escape to put lowercase characters in symbol name. Symbols print entirely in lowercase except symbols escaped when lowercase characters present with PRIN1. C: *READTABLE-CASE* :PRESERVE "Oldfashioned case sensitive" mode. Case sensitive input. Predefined symbols must be typed in uppercase. No alpha quoting needed. Symbols print exactly as stored. XLISP-PLUS 3.0 SYMBOL CASE CONTROL Page 16 D: *READTABLE-CASE* :INVERT "Modern case sensitive" mode. Case sensitive input. Predefined symbols must be typed in lowercase. Alpha quoting should be avoided. Predefined symbols print in lower case, other symbols print as they were entered. E: *READTABLE-CASE* :UPCASE *PRINT-CASE* :CAPITALIZE Like case B, except symbol names print capitalized. As far as compatibility between these modes are concerned, data printed in mode A can be read in A, B, C, or E. Data printed in mode B can be read in A, B, D, or E. Data printed in mode C can be read in mode C, and if no lowercase symbols in modes A, B and E as well. Data printed in mode D can be read in mode D, and if no (internally) lowercase symbols in modes A, B, and E as well. Data printed in mode E can be read in modes A, B, and E. In addition, symbols containing characters requiring quoting are compatible among all modes. XLISP-PLUS 3.0 PACKAGES Page 17 PACKAGES When compiled in, XLISP-PLUS provides the "Packages" name hiding facility of Common Lisp. When in use, there are multiple object arrays (name spaces). Each package has internal and external symbols. Internal symbols can only normally be accessed while in that package, while external symbols can be imported into the current package and used as though they are members of the current package. There are three standard packages, XLISP, KEYWORD, and USER. In addition, some of the utility programs are in package TOOLS. Normally one is in package USER, which is initally empty. USER imports all external symbols from XLISP, which contains all the functions and variables described in the body of this document. Symbols which are not imported into the current package, but are declared to be external in their home package, can be referenced with the syntax "packageName:symbolName" to identify symbol s_y_m_b_o_l_N_a_m_e_ in package p_a_c_k_a_g_e_N_a_m_e_. Those symbols which are internal in their home package need the slightly more difficult syntax "packageName::symbolName". The KEYWORD package is referenced by a symbol name with a leading colon. All keywords are in this package. All keywords are automatically marked external, and are interned as constants with themselves as their values. To build an application in a package (to avoid name clashes, for instance), use MAKE-PACKAGE to create a new package (only if the package does not already exist, use FIND-PACKAGE to test first), and then preceed the application with the IN-PACKAGE command to set the package. Use the EXPORT function to indicate the symbols that will be accessable from outside the package. To use an application in a package, either use IMPORT to make specific symbols accessable as local internal symbols, use USE-PACKAGE to make them all accessable, or explicitly reference the symbols with the colon syntax. The file MAKEWKS.LSP shows how to build an initial XLISP workspace such that all the tools are accessable. For the subtleties of the package facility, read Common Lisp the Language, second edition. XLISP-PLUS 3.0 LAMBDA LISTS Page 18 LAMBDA LISTS There are several forms in XLISP that require that a "lambda list" be specified. A lambda list is a definition of the arguments accepted by a function. There are four different types of arguments. The lambda list starts with required arguments. Required arguments must be specified in every call to the function. The required arguments are followed by the &optional arguments. Optional arguments may be provided or omitted in a call. An initialization expression may be specified to provide a default value for an &optional argument if it is omitted from a call. If no initialization expression is specified, an omitted argument is initialized to NIL. It is also possible to provide the name of a 'supplied-p' variable that can be used to determine if a call provided a value for the argument or if the initialization expression was used. If specified, the supplied-p variable will be bound to T if a value was specified in the call and NIL if the default value was used. The &optional arguments are followed by the &rest argument. The &rest argument gets bound to the remainder of the argument list after the required and &optional arguments have been removed. The &rest argument is followed by the &key arguments. When a keyword argument is passed to a function, a pair of values appears in the argument list. The first expression in the pair should evaluate to a keyword symbol (a symbol that begins with a ':'). The value of the second expression is the value of the keyword argument. Like &optional arguments, &key arguments can have initialization expressions and supplied-p variables. It is possible to specify the keyword to be used in a function call. If no keyword is specified, the keyword obtained by adding a ':' to the beginning of the keyword argument symbol is used. In other words, if the keyword argument symbol is 'foo', the keyword will be ':foo'. If identical keywords occur, those after the first are ignored. Extra keywords will signal an error unless &allow-other-keys is present, in which case the extra keywords are ignored. Also, if the keyword :allow-other-keys is used in the function/macro call, and has a non-nil value, then additional keys will be ignored. The &key arguments are followed by the &aux variables. These are local variables that are bound during the evaluation of the function body. It is possible to have initialization expressions for the &aux variables. XLISP-PLUS 3.0 LAMBDA LISTS Page 19 Here is the complete syntax for lambda lists: (... [&optional [ | ( [ []])]...] [&rest ] [&key [ | ([ | ( )] [ []])] ... [&allow-other-keys]] [&aux [ | ( [])]...]) where: is a required argument symbol is an &optional argument symbol is the &rest argument symbol is a &key argument symbol is a keyword symbol (starts with ':') is an auxiliary variable symbol is an initialization expression is a supplied-p variable symbol XLISP-PLUS 3.0 GENERALIZED VARIABLES Page 20 GENERALIZED VARIABLES Several XLISP functions support the concept of generalized variables. The idea behind generalized variables is that variables have two operations, access and update. Often two separate functions exist for the access and update operations, such as SYMBOL-VALUE and SET for the dynamic symbol value, or CAR and REPLACA for the car part of a cons cell. Code can be simplified if only one such function, the access function, is necessary. The function SETF is used to update. SETF takes a "place form" argument which specifies where the data is to be stored. The place form is identical to the function used for access. Thus we can use (setf (car x) 'y) instead of (rplaca x 'y). Updates using place forms are "destructive" in that the alter the data structure rather than rebuilding. Other functions which take place forms include PSETF, GETF, REMF, PUSH, PUSHNEW, POP, INCF, and DECF. XLISP has a number of place forms pre-defined in code. In addition, the function DEFSETF can be used to define new place forms. Place forms and functions that take them as arguments must be carefully defined so that no expression is evaluated more than once, and evaluation proceeds from left to right. The result of this is that these functions tend to be slow. If multiple evaluation and execution order is not a concern, alternative simpler functions can be un-commented in COMMON.LSP and COMMON2.LSP. A place form may be one of the following: A symbol (variable name). In this case note that (setf x y) is the same as (setq x y) A function call form of one of the following functions: CAR CDR NTH AREF ELT GET GETF SYMBOL-VALUE SYMBOL-FUNCTION SYMBOL-PLIST GETHASH. The function GETF itself has a place form which must aditionally be valid. The file COMMON2.LSP define additional placeforms (using DEFSETF) for LDB MASK-FIELD FIRST REST SECOND THIRD (through TENTH) and CxR. When used as a place form, the second argument of LDB and MASK-FIELD must be place forms and the number is not destructively modified. A macro form, which is expanded and re-evaluated as a place form. (send :) to set the instance variable of an object (requires CLASSES.LSP be used). (- ) to set the element, , of structure which is of type / ( ) form name , defined with DEFSETF or manually, is used with the arguments. When used with SETF, the function stored in property *setf* of symbol is applied to ( ), or, alternatively, the function stored in property *setf-lambda* is applied then the result is evaluated in the current context. XLISP-PLUS 3.0 OBJECTS Page 21 OBJECTS Definitions: selector - a symbol used to select an appropriate method message - a selector and a list of actual arguments method - the code that implements a message Since XLISP was created to provide a simple basis for experimenting with object-oriented programming, one of the primitive data types included is 'object'. In XLISP, an object consists of a data structure containing a pointer to the object's class as well as an array containing the values of the object's instance variables. Officially, there is no way to see inside an object (look at the values of its instance variables). The only way to communicate with an object is by sending it a message. You can send a message to an object using the 'send' function. This function takes the object as its first argument, the message selector as its second argument (which must be a symbol) and the message arguments as its remaining arguments. The 'send' function determines the class of the receiving object and attempts to find a method corresponding to the message selector in the set of messages defined for that class. If the message is not found in the object's class and the class has a super-class, the search continues by looking at the messages defined for the super-class. This process continues from one super-class to the next until a method for the message is found. If no method is found, an error occurs. To perform a method lookup starting with the method's superclass rather than the object's class, use the function 'send-super'. This allows a subclass to invoke a standard method in its parent class even though it overrides that method with its own specialized version. When a method is found, the evaluator binds the receiving object to the symbol 'self' and evaluates the method using the remaining elements of the original list as arguments to the method. These arguments are always evaluated prior to being bound to their corresponding formal arguments. The result of evaluating the method becomes the result of the expression. Two objects, both classes, are predefined: Object and Class. Both Object and Class are of class Class. The superclass of Class is Object, while Object has no superclass. Typical use is to create new classes (by sending :new to Class) to represent application objects. Objects of these classes, created by sending :new to the appropriate new class, are subclasses of Object. The Object method :show can be used to view the contents of any object. XLISP-PLUS 3.0 OBJECTS Page 22 THE 'Object' CLASS Object THE TOP OF THE CLASS HEIRARCHY Messages: :show SHOW AN OBJECT'S INSTANCE VARIABLES returns the object :class RETURN THE CLASS OF AN OBJECT returns the class of the object :prin1 [] PRINT THE OBJECT T is *terminal-io*, NIL and default is *standard- output* returns the object :isnew THE DEFAULT OBJECT INITIALIZATION ROUTINE returns the object :superclass GET THE SUPERCLASS OF THE OBJECT returns NIL (Defined in classes.lsp, see :superclass below) :ismemberof CLASS MEMBERSHIP class name returns T if object member of class, else NIL (defined in classes.lsp) :iskindof CLASS MEMBERSHIP class name returns T if object member of class or subclass of class, else NIL (defined in classes.lsp) :respondsto SELECTOR KNOWLEDGE message selector returns T if object responds to message selector, else NIL. (defined in classes.lsp) :storeon READ REPRESENTATION returns a list, that when executed will create a copy of the object. Only works for members of classes created with defclass. (defined in classes.lsp) XLISP-PLUS 3.0 OBJECTS Page 23 THE 'Class' CLASS Class THE CLASS OF ALL OBJECT CLASSES (including itself) Messages: :new CREATE A NEW INSTANCE OF A CLASS returns the new class object :isnew [ []] INITIALIZE A NEW CLASS the list of instance variable symbol the list of class variable symbols the superclass (default is Object) returns the new class object :answer ADD A MESSAGE TO A CLASS the message symbol the formal argument list (lambda list) a list of executable expressions returns the object :superclass GET THE SUPERCLASS OF THE OBJECT returns the superclass (of the class) (defined in classes.lsp) :messages GET THE LIST OF MESSAGES OF THE CLASS returns association list of message selectors and closures for messages. (defined in classes.lsp) :storeon READ REPRESENTATION returns a list, that when executed will re-create the class and its methods. (defined in classes.lsp) When a new instance of a class is created by sending the message ':new' to an existing class, the message ':isnew' followed by whatever parameters were passed to the ':new' message is sent to the newly created object. Therefore, when a new class is created by sending ':new' to class 'Class' the message ':isnew' is sent to Class automatically. To create a new class, a function of the following format is used: (setq (send Class :new [ []])) When a new class is created, an optional parameter may be specified indicating the superclass of the new class. If this parameter is omitted, the new class will be a subclass of 'Object'. A class inherits all instance variables, and methods from its super-class. Only class variables of a method's class are accessable. XLISP-PLUS 3.0 OBJECTS Page 24 INSTANCE VARIABLES OF CLASS 'CLASS': MESSAGES - An association list of message names and closures implementing the messages. IVARS - List of names of instance variables. CVARS - List of names of class variables. CVAL - Array of class variable values. SUPERCLASS - The superclass of this class or NIL if no superclass (only for class OBJECT). IVARCNT - instance variables in this class (length of IVARS) IVARTOTAL - total instance variables for this class and all superclasses of this class. PNAME - printname string for this class. XLISP-PLUS 3.0 SYMBOLS Page 25 SYMBOLS All values are initially NIL unless otherwise specified. All are special variables unless indicated to be constants. NIL - represents empty list and the boolean value for "false". The value of NIL is NIL, and cannot be changed (it is a constant). (car NIL) and (cdr NIL) are also defined to be NIL. t - boolean value "true" is constant with value t. self - within a method context, the current object (see page 21), otherwise initially unbound. object - constant, value is the class 'Object.' class - constant, value is the class 'Class'. internal-time-units-per-second - integer constant to divide returned times by to get time in seconds. pi - floating point aproximation of pi (constant defined when math extension is compiled). *obarray* - the object hash table. Length of array is a compilation option. Objects are hashed using the hash function and are placed on a list in the appropriate array slot. This variable does note exist when the package feature is compiled in. *package* - the current package. Do not alter. Part of the package feature. *terminal-io* - stream bound to keyboard and display. Do not alter. *standard-input* - the standard input stream, initially stdin. If stdin is not redirected on the command line, then *terminal-io* is used so that all interactive i/o uses the same stream. *standard-output* - the standard output stream, initially stdout. If stdout is not redirected on the command line then *terminal-io* is used so that all interactive i/o uses the same stream. *error-output* - the error output stream (used by all error messages), initially same as *terminal-io*. *trace-output* - the trace output stream (used by the trace function), initially same as *terminal-io*. *debug-io* - the break loop i/o stream, initially same as *terminal-io*. System messages (other than error messages) also print out on this stream. *breakenable* - flag controlling entering break loop on errors (see page 4) *tracelist* - list of names of functions to trace, as set by trace function. *tracenable* - enable trace back printout on errors (see page 4). *tracelimit* - number of levels of trace back information (see page 4). *evalhook* - user substitute for the evaluator function (see page 9, and evalhook and applyhook functions). *applyhook* - user substitute for function application (see page 9, and evalhook and applyhook functions). *readtable* - the current readtable (see page 13). *gc-flag* - controls the printing of gc messages. When non-NIL, a message is printed after each garbage collection giving the total number of nodes and the number of nodes free. *gc-hook* - function to call after garbage collection (see page 9). XLISP-PLUS 3.0 SYMBOLS Page 26 *integer-format* - format for printing integers (when not bound to a string, defaults to "%d" or "%ld" depending on implementation). Variable not used when bignum extension installed. *float-format* - format for printing floats (when not bound to a string, defaults to "%g") *readtable-case* - symbol read and output case. See page 15 for details *read-base* - When bound to a fixnum in the range 2 through 36, determines the default radix used when reading rational numbers. Part of bignum extension. *print-base* - When bound to a fixnum in the range 2 through 36, determines the radix used when printing rational numbers with prin1 and princ. Part of bignum extension. *print-case* - symbol output case when printing. See page 15 for details *print-level* - When bound to a number, list levels beyond this value are printed as '#'. Used by all printing functions. Good precaution to avoid getting caught in circular lists. *print-length* - When bound to a number, lists longer than this value are printed as '...'. Used by all printing functions. Good precaution to avoid getting caught in circular lists. *dos-input* - When not NIL, uses dos line input function for read (see page 3). *displace-macros* - When not NIL, macros are replaced by their expansions when exectuted (see page 8). *random-state* - the default random-state used by the random function. *features* - list of features, initially (:xlisp), used for #+ and #- reader macros. *startup-functions* - list of functions to be executed when workspace started *command-line* - the xlisp command line, in the form of a list of strings, one string per argument. *load-file-arguments* - When not NIL, file arguements are loaded at startup. *top-level-loop* - Top level loop to utilize, defaults to TOP-LEVEL- LOOP. Note that this function can only be restarted by executing TOP- LEVEL, and it never exits. *read-suppress* - When not NIL, inhibits certain parts of reading. Used by the #+ and #- macroes. There are several symbols maintained by the read/eval/print loop. The symbols '+', '++', and '+++' are bound to the most recent three input expressions. The symbols '*', '**' and '***' are bound to the most recent three results. The symbol '-' is bound to the expression currently being evaluated. It becomes the value of '+' at the end of the evaluation. XLISP-PLUS 3.0 EVALUATION FUNCTIONS Page 27 EVALUATION FUNCTIONS (eval ) EVALUATE AN XLISP EXPRESSION the expression to be evaluated returns the result of evaluating the expression (apply ...) APPLY A FUNCTION TO A LIST OF ARGUMENTS the function to apply (or function symbol). May not be macro or fsubr. initial arguments, which are CONSed to... the argument list returns the result of applying the function to the arguments (funcall ...) CALL A FUNCTION WITH ARGUMENTS the function to call (or function symbol). May not be macro or fsubr. arguments to pass to the function returns the result of calling the function with the arguments (quote ) RETURN AN EXPRESSION UNEVALUATED fsubr the expression to be quoted (quoted) returns unevaluated (function ) GET THE FUNCTIONAL INTERPRETATION fsubr the symbol or lambda expression (quoted) returns the functional interpretation (complement ) MAKE A COMPLEMENTARY FUNCTION This function is intended to eliminate the need for -IF-NOT functions and :TEST-NOT keys by providing a way to make complementary functions. the function or closure (not macro or fsubr) returns a new function closure that returns NOT of the result of the original function. (identity ) RETURN THE EXPRESSION the expression returns the expression (backquote ) FILL IN A TEMPLATE fsubr. Note: an improved backquote facility, which works properly when nested, is available by loading the file backquot.lsp. the template (quoted) returns a copy of the template with comma and comma-at expressions expanded. (comma ) COMMA EXPRESSION (Never executed) As the object of a backquote expansion, the expression is evaluated and becomes an object in the enclosing list. XLISP-PLUS 3.0 EVALUATION FUNCTIONS Page 28 (comma-at ) COMMA-AT EXPRESSION (Never executed) As the object of a backquote expansion, the expression is evaluated (and must evaluate to a list) and is then spliced into the enclosing list. (lambda ...) MAKE A FUNCTION CLOSURE fsubr formal argument list (lambda list) (quoted) expressions of the function body (quoted) returns the function closure (get-lambda-expression ) GET THE LAMBDA EXPRESSION the closure returns the original lambda expression, or NIL if not a closure. Second return value is T if closure has a non-global environment, and the third return value is the name of the closure. (macroexpand
) RECURSIVELY EXPAND MACRO CALLS the form to expand returns the macro expansion (macroexpand-1 ) EXPAND A MACRO CALL the macro call form returns the macro expansion XLISP-PLUS 3.0 MULTIPLE VALUE FUNCTIONS Page 29 MULTIPLE VALUE FUNCTIONS XLISP-PLUS supports multiple return values (via a compilation option) as in Common Lisp. Note that most FSUBR control structure functions will pass back multiple return values, with the exceptions being PROG1 and PROG2. (multiple-value-bind [...]) BIND RETURN VALUES INTO LOCAL CONTEXT defined as macro in common.lsp form to be evaluated list of variables to bind to return values of vform forms evaluated sequentially, as in LET, using local bindings returns values of last form evaluated, or NIL if no forms (multiple-value-call ...) COLLECT VALUES AND APPLY FUNCTION fsubr function to apply forms, which are evaluated, with result values collected returns result of applying fun to all of the returned values of the forms (multiple-value-list ) COLLECT MULTIPLE RETURNED VALUES INTO A LIST defined as macro in common.lsp form to be evaluated returns list of returned values (multiple-value-prog1 [ ...]) RETURN VALUES OF FIRST FORM fsubr one or more forms, which are evaluated sequentially returns the result values of the first form (multiple-value-setq ) BIND RETURN VALUES TO VARIABLES defined as macro in common.lsp form to be evaluated list of variables to bind to return values of form returns (undefined, implementation dependent) (nth-value ) EXTRACT A RETURN VALUE fsubr index into return values form which gets evaluated returns the nth result value of exectuing the form (values []) RETURN MULTIPLE VALUES expression(s) to be evaluated returns each argument as a separate value (values-list ) RETURN MULTIPLE VALUES FROM LIST defined in common.lsp a list returns each list element as a separate value XLISP-PLUS 3.0 SYMBOL FUNCTIONS Page 30 SYMBOL FUNCTIONS (set ) SET THE GLOBAL VALUE OF A SYMBOL You can also use (setf (symbol-value ) ) the symbol being set the new value returns the new value (setq [ ]...) SET THE VALUE OF A SYMBOL fsubr. You can also use (setf ) the symbol being set (quoted) the new value returns the last new value or NIL if no arguments (psetq [ ]...) PARALLEL VERSION OF SETQ fsubr. All expressions are evaluated before any assignments are made. the symbol being set (quoted) the new value returns NIL (defun ...) DEFINE A FUNCTION (defmacro ...) DEFINE A MACRO fsubr symbol being defined (quoted) formal argument list (lambda list) (quoted) expressions constituting the body of the function (quoted) returns the function symbol (gensym []) GENERATE A SYMBOL string or number returns the new symbol, uninterned (intern []) MAKE AN INTERNED SYMBOL the symbol's print name string the package (defaults to current package) returns the new symbol. A second value is returned which is NIL if the symbol did not pre-exist, :internal if it is an internal symbol, :external if it is an external symbol, or :inherited if it inherited via USE-PACKAGE. (make-symbol ) MAKE AN UNINTERNED SYMBOL the symbol's print name string returns the new symbol (symbol-name ) GET THE PRINT NAME OF A SYMBOL the symbol returns the symbol's print name (symbol-value ) GET THE VALUE OF A SYMBOL May be used as a place form. the symbol returns the symbol's value XLISP-PLUS 3.0 SYMBOL FUNCTIONS Page 31 (symbol-function ) GET THE FUNCTIONAL VALUE OF A SYMBOL May be used as a place form. the symbol returns the symbol's functional value (symbol-plist ) GET THE PROPERTY LIST OF A SYMBOL May be used as a place form. the symbol returns the symbol's property list (hash ) COMPUTE THE HASH INDEX the object to hash the table size (positive fixnum less than 32768) returns the hash index (fixnum 0 to n-1) (makunbound ) MAKE A SYMBOL VALUE BE UNBOUND You cannot unbind constants. the symbol returns the symbol (fmakunbound ) MAKE A SYMBOL FUNCTION BE UNBOUND the symbol returns the symbol (unintern []) UNINTERN A SYMBOL Defined in common.lsp if package extension not compiled. the symbol the package to look in for the symbol returns t if successful, NIL if symbol not interned (defconstant []) DEFINE A CONSTANT fsubr. the symbol the value optional comment string (ignored) returns the value (defparameter []) DEFINE A PARAMETER fsubr. the symbol (will be marked "special") the value optional comment string (ignored) returns the value (defvar [ []]) DEFINE A VARIABLE fsubr. Variable only initialized if not previously defined. the symbol (will be marked "special") the initial value, or NIL if absent. optional comment string (ignored) returns the current value XLISP-PLUS 3.0 SYMBOL FUNCTIONS Page 32 (mark-as-special []) SET SPECIAL ATTRIBUTE Also see definition of PROCLAIM and DECLARE. symbol to mark non-nil to make into a constant returns nil, with symbol marked as special and possibly as a constant. (declare [ ...]) DECLARE ARGUMENT ATTRIBUTES Macro in common.lsp provided to assist in porting Common Lisp applications to XLISP-PLUS. list of local variable and attributes returns nil, produces an error message if attribute SPECIAL is used. (proclaim ) PROCLAIM GLOBAL SYMBOL ATTRIBUTES Function in common.lsp provided to assist in porting Common Lisp applications to XLISP-PLUS. a list of symbols. If the CAR of the list is SPECIAL, then the remaining symbols are marked as special variables. (copy-symbol []) MAKE A COPY OF A SYMBOL Function in common2.lsp symbol to copy if present and non-nil, copy value, function binding, and property list. returns un-interned copy of XLISP-PLUS 3.0 GENERALIZED VARIABLE FUNCTIONS Page 33 GENERALIZED VARIABLE FUNCTIONS (setf [ ]...) SET THE VALUE OF A FIELD fsubr the field specifier the new value returns the last new value, or NIL if no arguments (psetf [ ]...) PARALLEL VERSION OF SETF fsubr. All expressions are evaluated and macro place forms expanded before any assignments are made. the field specifier the new value returns NIL (defsetf ) DEFINE A SETF FIELD SPECIFIER (defsetf () ...) Defined as macro in common.lsp. Convenient, Common Lisp compatible alternative to setting *setf* or *setf-lambda* property directly. field specifier symbol (quoted) function to use (quoted symbol) which takes the same arguments as the field specifier plus an additional argument for the value. The value must be returned. formal argument list of unevaluated arguments (lambda list) (quoted) symbol bound to value to store (quoted). The last expression must an expression to evaluate in the setf context.In this respect, defsetf works like a macro definition. returns the field specifier symbol (push ) CONS TO A FIELD Defined as macro in common.lsp. Only evaluates place form arguments one time. It is recommended that *displace-macros* be non-NIL for best performance. field specifier being modified (see setf) value to cons to field returns the new value which is (CONS ) (pushnew &key :test :test-not :key) CONS NEW TO A FIELD Defined as macro in common.lsp. Only evaluates place form arguments one time. It is recommended that *displace-macros* be non-NIL for best performance. field specifier being modified (see setf) value to cons to field, if not already MEMBER of field :test the test function (defaults to eql) :test-not the test function (sense inverted) :key function to apply to test function list argument (defaults to identity) returns the new value which is (CONS ) or XLISP-PLUS 3.0 GENERALIZED VARIABLE FUNCTIONS Page 34 (pop ) REMOVE FIRST ELEMENT OF A FIELD Defined as macro in common.lsp. Only evaluates place form arguments one time. It is recommended that *displace-macros* be non-NIL for best performance. the field being modified (see setf) returns (CAR ), field changed to (CDR ) (incf []) INCREMENT A FIELD (decf []) DECREMENT A FIELD Defined as macro in common.lsp. Only evaluates place form arguments one time. It is recommended that *displace-macros* be non-NIL for best performance. field specifier being modified (see setf) Numeric value (default 1) returns the new value which is (+ ) or (- ) XLISP-PLUS 3.0 PACKAGE FUNCTIONS Page 35 PACKAGE FUNCTIONS These functions are defined when the packages extension is compiled. The argument can be either a string, symbol, or package object. The default when no package is given is the current package (as bound to *package*), unless otherwise specified in the definition. The argument may be either a single symbol or a list of symbols. In case of name conflicts, a correctable error occurs. When the packages extension is not compiled, simplified versions of apropos, apropos-list, and do-all-symbols are provided in common2.lsp. In addition, init.lsp will define dummy versions of export and in-package. (apropos []) SEARCH SYMBOLS FOR NAME MATCH (apropos-list []) Functions in common.lsp. find symbols which contain this string as substring of print name package to search, if absent, or NIL, search all packages returns apropos-list returns list of symbols, apropos prints them, along with some information, and returns nothing. (defpackage [