XEROX Common Lisp Library 2 4 1 Common Lisp Support 1 4 INTRODUCTION A taste of what's to come! Common Lisp is a dialect of Lisp, which differs in many minor and a few major details from Interlisp. It is designed to be portable and incorporates features from the Maclisp family of Lisp languages. The major differences are: lexical scoping, closures, multiple return values, and the use of packages (or multiple oblists). There are many minor differences based on stylistic issues, primary among these is the use of the SETF macro on accessor forms to place values. The languages primary goal is standardization. In August 1985, Xerox AI Systems announced the availability of Xerox Common Lisp, with a first release at the end of the second quarter of 1986. This Library Module (CML) is both a preview of what Common Lisp will be like, and also a significantly useful set of features and functionality. It represents a fairly early but well-defined point in our experimentation with Common Lisp features within Interlisp. Common Lisp (and CML) is part of the Interlisp-D environment and runs within it; the standard Interlisp-D environment tools (history, DEdit, Masterscope, etc.) all work with Common Lisp functions. Common Lisp and Interlisp functions can be freely intermixed; that is, one has available the union of all Interlisp features and Common Lisp features within a single programming environment. In the following text references to "Common Lisp" or "the Common Lisp language" mean the contents of "Common Lisp the Language", by Guy Steele. References to "CML" or "Xerox Common Lisp" mean this release or future releases of this software. USING THE CML PACKAGE The file CML.DCOM loads a number of files which implement Common Lisp features. Currently these are: CML CMLARITH CMLARRAY * CMLARRAYINSPECTOR * CMLCHARACTER CMLCOMPILE CMLEXEC CMLFLOATARRAY * CMLHELP CMLPRETTY CMLPRINT CMLSETF CMLSPECIALFORMS CMLSTRUCT CMLTYPES * Indicates that this code is documented in a separate file. Caveats This software is under intensive development. While we've managed to run some Common Lisp programs intact using it, it does not implement full Common Lisp, and the coverage is uneven. (Our strategy was to port enough to handle two small applications and to experiment with some more controversial features.) For the most part, features that are present are "fully implemented", but there are some suggestions. Because this is not a complete Common Lisp release, but rather a selection of some tested functionality from the coming release, it is important to read the documentation to be aware of limitations. Features and functions not documented should be assumed "not yet implemented". Often, specific omissions will be mentioned. CML (and Xerox Common Lisp) "look like" Interlisp-D. For those first starting with Interlisp-D with previous experience on a text-editor-based Common Lisp environment, the style and use of Common Lisp will be unfamiliar; for example, the standard way of editing Common Lisp functions is to use DEdit, the Interlisp-D structure editor. The Interlisp-D file package is used for saving and restoring definitions of functions (defined with DEFUN), macros (defined with DEFMACRO) and datatypes (defined with DEFSTRUCT.) CML has no microcode support, although Xerox Common Lisp will. Because of this, some Common Lisp features are slower than their Interlisp-D counterparts. Microcode support is required for reasonable implementation of lexical closures and multiple values, and those features are not part of CML. Common Lisp features are entering the system in three ways. Some have been added to standard Interlisp-D, rather than as part of the CML feature. For the most part, this has been limited to those features which were required by implementation of other parts of the system. For example, DEFMACRO, backquote, and many of the system-query functions are already part of standard Interlisp-D. Some features are completely implemented buut will be part of Interlisp-D in future, like the array code. Finally, some features have not yet been implemented, like multiple values, lexical scoping, closures and packages. Organization This documentation is organized in approximately the same topical order as in Common Lisp the Language. Errors Common Lisp the Language allows wide variability in the ammount of error checking which is performed by a Common Lisp implementation. There are a number of constructs which are marked "it is an error to ...." Implementations are free to either add run-time checks are not. CML (and Xerox Common Lisp) attempts to perform as much error checking as is feasible. No Common Lisp program, valid or not, should result in any kind of system failure. For the most part, CML adheres to this principle, although some errors are currently not checked; these are documented below. DATA TYPES For the most part, the data types of Common Lisp are a subset of those available within Interlisp-D. Specific correspondences are described below. This is a breif synopsis. More detailed information is availble following this section. Numbers The INTEGER types correspond as follows: Common Lisp's FIXNUM is implemented by SMALLPs, while Common Lisp's BIGNUM type is implemented by the two types FIXP and BIGNUM in Interlisp-D. The type-of function returns the Common Lisp name of the type of the object, e.g. (type-of 3) ==> FIXNUM (type-of 12312312) ==> BIGNUM (type-of 123123123123123123123123123123) ==> BIGNUM CML doesn't implement RATIO or COMPLEX (there are declarations for the types, but they are not wired into the arithmetic functions.) CML (and Xerox Common Lisp) has one implementation of FLOAT, namely SINGLE-FLOAT numbers in IEEE format. Not all Common Lisp input formats are allowed in CML (it doesn't have a full Common Lisp reader.) Temporarily, input to CMLEXEC should be in lower case. The exponent mark (E in 12.0E17) should be in upper-case. For type-in only the default floating point exponent marker is allowed: "E." "e" is not allowed. Characters CML contains a full implementation of the Common Lisp CHARACTER type. All of the various I/O formats and character functions are implemented. In CML (and Xerox Common Lisp), there are 2^16 possible character codes, in accordance with the Xerox Character Code standard. Thus, CHAR-CODE-LIMIT is 65536. Our experience with fonts in the Interlisp-D environment has shown that the single "font-bits" attribute of Common Lisp is inadequate to handle the complexity of attaching fonts to characters. Rather than trying to shoehorn a complex font system into a small packet of information, we have chosen to set CHAR-FONT-LIMIT to 1; that is, font information for characters lies. It is not part of the character code. In addition, CHAR-BITS-LIMIT is also 1; the nuance of additional shift-bits being handled by the keyboard decoding system rather than the character system. Because of this, all objects of type CHARACTER are of type STRING-CHARACTER and can occur in strings. Symbols Symbols are what Interlisp calls litatoms. Common Lisp symbols differ from Interlisp ones primarily in: the presence of a "package cell" and the multiple name spaces that packages provide, the ability to have symbols with the same characters as numbers, and some additional forms of input syntax. These features of Xerox Common Lisp are not in CML; avoid symbols with all digits, mixed case, etc. Arrays CML contains a full implementation of Common Lisp arrays, vectors and strings, including all of the array functions, displacing, and some of the more obscure features. In addition, Common Lisp arrays embed the Interlisp types STRINGP, BITMAP, and ARRAYP; that is, one may use Common Lisp array functions on an Interlisp STRINGP treating it as a SIMPLE-STRING, a BITMAP treating it as a two-dimensional array of bits, and an Interlisp-D ARRAYP, treating it as a SIMPLE-VECTOR. The array features are documented separately; see the CMLARRAY documentation. Bit vectors CML supports bit vectors now, but some bitwise operations on them, as outlined in the separate CMLARRAY document, are not yet implemented. Hash tables A hashtable associates one lisp object with another, referred to as the key and the value. This is done as a tradeoff, where more space is used to store the objects so that access time is significantly reduced. Putting a value into a hashtable is a destructive operation, ie only one object may be stored under a given key. Hashtables can fill up, and if they do, they expand their size. For more information see the section on HASHTABLES below. Read tables Readtables describe the character by character behavior of the higher level read functions as they parse streams of characters. Common Lisp style read tables are not supported at this release. Packages A pacakges is like an object list; a collections of symbols (LITATOMS). Typically the group of functions that implements a complete program (or software subsystem) will all reside inthe same package. Interlisp calls this collection a "module" (something which the "file package" maintains) They gather together related symbols and hide internal ones from other CML does not implement packages. See the section below for more information. Pathnames Are a formalized destructuring of file names into their components, like Interlisp-D's PACK and UNPACKFILENAME functions. In this release the Common Lisp style pathname functions are not supported. Streams Streams are an interface metaphor. Files and devices are characterized as producers and consumers of "streams" of data. These data may be characters, numbers of some precision, etc. While Interlisp-D supports similar facilities, the Common Lisp style is not supported at this release. Structures A structure is a way of encapsulating operations on a particular type of data, in a way that allows the representation to be changed independant of the code that uses it. Specific functions are defined to create, destroy, access, modify and print objects of these types. The Interlisp-D RECORD PACKAGE implements our structure functionality. See the section below. In future releases DEFSTRUCT will be part of the Commonloops object oriented programming facility. Functions & macros A function is anything that may be correctly given to FUNCALL or APPLY. A compiled function (Interlisp's CCODEP) is the result of compilation of a lisp expression. Currently, Common Lisp style lambda lists are implemented using the LAMBDATRAN facility. The full DEFMACRO syntax is supported directly by Interlisp-D. Unreadable data types These are data objects for which there is either no defined print representation, or which, through the use of control flags, is printed in a compact format. These are most often implemenation specific low level data types. In the current implementation these are printed inthe Common Lisp fashion, although there are no restrictions to the reader's behavior when it encounters them. SCOPE AND EXTENT Scope characterizes the places where an object may be referred to by a Lisp program. Extent is a measure of the lifetime of an object. Some examples: in Interlisp-D an argument to a function may be referred to both within the body of the function, and by any other functions that are called by it. However, that argument may not be referred to once the function is exited. This is indefinate scope, because references are not constrained to the body of the program, and dynamic extent because the argument's exists for a definate interval (until the stack frame containing it is exited). As another example, a data structure (a piece of a property list for example) usually has indefinate extent; it lasts and may be referred to until no other data structure has a pointer to it, and the garbage collector takes it. Common Lisp uses lexical scoping extensively. This is similar to languages like ALGOL and C, where the local variables of a function may only be referred to within the textual bounds of the body of the function. Declarations allow a local variable to have indefinate scope if desired. Xerox Common Lisp does not support lexical scoping with this release. Objects should be assumed to be of indefinate scope and dynamic or indefinate extent as appropriate. TYPE SPECIFIERS Common Lisp has the notion of type specifiers, which can be individual symbols or patterns made of lists of symbols. The single symbol form of type specifier is familiar: ATOM is a reasonably standard type in Lisp systems. Structures created using DEFSTRUCT cause their names to become valid type specifiers. It is interesting to note that the type of an object is not an exclusive property. Any object may have several types it is an example of. As an example of this, the set of objects of type T includes all lisp objects. On the other had, the set of type NIL has no examples. It is of course possible for a type specifier to map exclusively and exhaustively onto the data structures that implements a particular kind of object. These are implementation specific. The Common Lisp type specifiers are: ATOM BIGNUM BIT CHARACTER CONS DOUBLE-FLOAT FIXNUM FLOAT HASH-TABLE INTEGER KEYWORD LIST LONG-FLOAT MEMBER MOD NULL NUMBER SHORT-FLOAT SIGNED-BYTE SIMPLE-STRING SINGLE-FLOAT STRING STRING-CHAR SYMBOL UNSIGNED-BYTE Existing Interlisp-D datatypes are mapped onto the Common Lisp types thusly: ARRAYP ARRAY CMLARRAY ARRAY SMALLP FIXNUM FIXP BIGNUM FLOATP SINGLE-FLOAT LISTP CONS LITATOM SYMBOL STRINGP SIMPLE-STRING Type specifier predicates (SATISFIES PREDICATE) [Type Specifier] It is sometimes desirable to define a class of objects using a function. This is possible with type specifiers like . The PREDICATE must be a symbol whose global function definition accecpts a lisp object and returns non-NIL if the object is an example of the type. Type specifiers that combine There are several specifiers that act like logical functions to combine and enumerate types. (MEMBER OBJECT1 OBJECT2 ...) [Type Specifier] This defines a type which is the given specific set of objects. Inclusion is tested with EQL. (NOT TYPE) [Type Specifier] Defines the type which contains the set of all objects which are not of type TYPE. (AND TYPE1 TYPE2 ...) [Type Specifier] Defines the type which contains the intersection of the given type sets. Testing proceeds left to right and stops as soon as the object is not an example of one of the types, or finishes successfully. (OR TYPE1 TYPE2 ...) [Type Specifier] Defines the type which contains the union of the given type sets. Testing proceeds left to right and stops as soon as the object is an example of a given type, or the test runs off the end of the specifier list and fails. Type specifers that specialize Some type specifiers can be used generically, or may be made more specific in list form. VECTOR is the set of all one dimensional arrays, but vectors may be pecialized to hold elements of a particular type, or be of a particular length. A specialized type specifier can be built from the symbol VECTOR like this: (VECTOR FLOAT 10), which is any single dimensional array whose elements are all (exactly) of type FLOAT and which has exactly ten elements. Any of the latter fields may be omitted, or "wildcarded" with the symbol *. Thus, all of the following type specifiers are equivalent: VECTOR (VECTOR *) (VECTOR * *) The following type specifiers all accept wildcards and allow omission of specializing arguments as described above. (ARRAY ELEMENT-TYPE DIMENSIONS) [Type Specifier] The set of all array objects whose elements are of the type ELEMENT-TYPE and which have dimensions matching DIMENSIONS. Dimensions can be given as either: * - in which case arrays of any rank and size are accepted positive integer - arrays of only this rank are accepted list of dimensions - any of which may be given as * , and will match arrays with dimensions that match those in the list. (SIMPLE-ARRAY ELEMENT-TYPE DIMENSIONS) [Type Specifier] Exactly like ARRAY, but the array must also be a SIMPLE-ARRAY (see section above on datatypes or the array chapter). (VECTOR ELEMENT-TYPE SIZE) [Type Specifier] The set of all one dimensional arrays with elements specialized to hold ELEMENT-TYPE and which are of the SIZE length. (VECTOR ELEMENT-TYPE SIZE) is equivalent to (ARRAY ELEMENT-TYPE (SIZE)). (VECTOR STRING-CHAR) is equivalent to STRING. (SIMPLE-VECTOR SIZE) [Type Specifier] The set of all simple vectors (see section above on datatypes or the array chapter), which are by definition of ELEMENT-TYPE T, ie (VECTOR T SIZE) and "simple." (COMPLEX TYPE) [Type Specifier] True of complex numbers, ones with real and imaginary parts. (FUNCTION (ARG1-TYPE ARG2-TYPE ...) VALUE-TYPE) [Type Specifier] This is a strictly declarative type specifier. It is not used by CML. (VALUES VALUE1-TYPE VALUE2-TYPE ...) [Type Specifier] This is a strictly declarative type specifier. It is not used by CML. (RATIONAL LOW HIGH) [Type Specifier] True of numbers represented in rational form, ie, with numerator and denominator. Type specifiers that abbreviate There are type specifiers which act as abbreviations of others, and produce somewhat specialized versions of them. (INTEGER LOW HIGH) [Type Specifier] Specifies the set of integers in the range LOW to HIGH. LOW and HIGH must be either: unspecified or * - indicating no limit (+infinity or -infinity) an integer - indicates that limit inclusively a list of a single integer - indicates that limit exclusively FIXNUM is slightly different from INTEGER in that it specifes an INTEGER in an implementation dependant range (INTEGER may encompass BIGNUMs). (MOD N) [Type Specifier] The set of integers less than N. (SIGNED-BYTE S) [Type Specifier] The set of integers which are represented by a signed two's complement number of S bits (the range -2S-1 to 2S-1 - 1). If S is unspecifed or wildcarded this is the same as INTEGER. (UNSIGNED-BYTE S) [Type Specifier] The set of integers which are represented by an unsigned binary number of S bits (the range 0 to 2S - 1). If S is unspecifed or wildcarded this is the same as (INTEGER 0 *). (RATIONAL LOW HIGH) [Type Specifier] Not yet implemented. (FLOAT LOW HIGH) [Type Specifier] The set of floating point numbers between LOW and HIGH, each of which must be either: unspecified or * - indicating no limit (+infinity or -infinity) a FLOAT - indicates that limit inclusively a list of a single FLOAT - indicates that limit exclusively The following are similar, but if a float argument is given it must be of the given type. (SHORT-FLOAT LOW HIGH) [Type Specifier] (SINGLE-FLOAT LOW HIGH) [Type Specifier] (DOUBLE-FLOAT LOW HIGH) [Type Specifier] (LONG-FLOAT LOW HIGH) [Type Specifier] As for FLOAT, except that the resulting type is one of the implementation specific specializations in the noted range. Range numbers must be specified with the corresponding type of floating point number. (STRING SIZE) [Type Specifier] The type of all strings of SIZE. Equivalent to (VECTOR STRING-CHAR SIZE). (SIMPLE-STRING SIZE) [Type Specifier] As for STRING, but the vector must be SIMPLE (see the ARRAY chapter below). (BIT-VECTOR SIZE) [Type Specifier] Not yet implemented. (SIMPLE-BIT-VECTOR SIZE) [Type Specifier] Not yet implemented. (DATATYPE NAME) [Type Specifier] This is an Interlisp-D extension which is the set of objects implemented with the internal representation given by NAME. Defining new type specifiers A new type can be defined by DEFSTRUCT, or explicitly constructed with the following macro. (DEFTYPE NAME LAMBDA-LIST {DECLARATION | DOC-STRING}* {FORM}*) [Macro] Allows definition of new types. It can be thought of as a kind of macro expansion which creates the actual type defining form. NAME is the symbol to be used as the name of the new type. LAMBDA-LIST is the argument list for the macro, similar to DEFMACRO, including &OPTIONAL and &REST arguments. The default value for &OPTIONAL arguments is the symbol * instead of NIL. A nyumber of DECLARATION forms or DOC-STRINGs may be included. DOC-STRING is saved under the symbol as documenation of type TYPE. The last of the FORMs should return a form which is interpreted as the type specifier. DEFTYPE returns the name of the new type. Note: CML provides a File Package command called TYPES which saves these definitions. The documentation string is saved under NAME in the property TYPE-DOCUMENTATION. Type conversion (COERCE OBJECT RESULT-TYPE) [Function] The given OBJECT is converted into an "equivalent" representation in the type described by the type specifier RESULT-TYPE. If the conversion cannot be done an error is signalled. Note: In CML coercion is supported only from a few types into RESULT-TYPE CHARACTER, FLOAT or SIMPLE-STRING. Determining the type of an object Although an object can be a member of many type sets, it is possible to get the type specifier of just one that describes it. Testing objects against type specifiers is done with functions in the PREDICATES chapter below. (TYPE-OF OBJECT) [Function] Returns a correct type specifier that describes one of (or possibly the only) type set to which an object belongs. PROGRAM STRUCTURE The overall structure of a Common Lisp program includes: forms, some of which evaluate to themselves and are called "self evauating", variables, special forms, which don't evaluate their arguments, macros, functions, some named with symbols, and lambda expressions. In addition there are various "top-level" forms which asre used to define named functions, declare global constants and variables, and control "time of evaulation" of forms (at load, compile, etc.). Lambda expressions The basic syntax of the Common Lisp lambda expression is: (LAMBDA LAMBDA-LIST . BODY) The LAMBDA-LIST specifies the name and form of the parameters of the lambda expression. The lambda list is used to accept arguments at eval time. Common Lisp lambda lists begin as do most language's parameter accepting syntax, with symbols that require arguments to be provided (there can be zero or more of these). However, parameters inthe lambda list may be preceded by lambda keywords. These can cause arguments to be optional, gather indefinate numbers of arguments into a list, pull parameters from arguments by keyword, or even provide local variables. Lambda keywords can be followed by forms that initialize unprovided optional parameters, or set flags to indicate when they have been provided. The body of a lambda may begin with none or any number of declaration expressions and documentation strings, which are followed by zero or more forms, which are evaluated as though in a PROGN. lambda list The following is the exact syntax of the LAMBDA-LIST ({VAR}* [&OPTIONAL { VAR | (VAR [INITFORM [VARSETP]])}*] [&REST VAR] [&KEY {VAR | ({VAR | (KEYWORD VAR) } [INITFORM [VARSETP]])}* [&ALLOW-OTHER-KEYS]] [&AUX {VAR | (VAR [INITFORM])}*]) The first set of VARs are required parameters. Corresponding arguments must be provided at each evaluation. It is an error not to provide them. &OPTIONAL parameters mean that arguments may or may not be provided at an evaluation. There are three forms of optional parameter. The first occurs when only the symbol is given in the lambda arglist. In this form an argument is optional and if not provided the parameter is set to NIL. The second form is a two element list, with a symbol and an initializing form, which is evaluated to set upt he parameter if an argument is not provided. Finally a three element list may be provided, which is like the second form, but whose third element is a symbol which is set to T when the argument is provided or NIL when it is not. A &REST parameter gathers up any remaining arguments into a list and binds VAR to it. Including lambda keyword means that the function can accept an upwardly unbounded number of arguments. &KEY means that the argument list, after some point, is composed of alternating keyword and value pairs. E.g., suppose COLOR-MY-WORLD is a function with dozens of parameters, but which is typically called with only one or two of them set to a non-default value. Then you might see (COLOR-MY-WORLD SOMEBITMAP :HUE BLUE :DURATION 5HOURS) where the first argument is "required", but all the others are optional and are obtained from the appropriate pair in the real argument list; in this example, one such "keyword" argument is called HUE, and it will be set to the value of the variable BLUE; also this "coloring" will last for a DURATION of time found in the variable 5HOURS. Note that the keywords inthe argument list can be computed by forms in the arguments to the call; the consistent pairing must still be observed. As with &OPTIONAL parameters &KEY parameters may be described as two or three element lists with default initializing forms and VARSETPs. Note that CML simulates the reader syntax and self evaluation of keywords, eg, the ":" p[refixed to the keywords inthe previous example. &ALLOW-OTHER-KEYWORDS can follow &KEYparameters and signals that it is not an error to provide keywords in the argument list of this fuction which are not recognized. This is handy when used with an &REST keyword, to pass keyword args through to another function via FUNCALL for instance. &AUX allows variables to be set up exactly as per LET. lambda body The exact syntax of the body of a lambda expression is {DECLARATION | DOCUMENTATION-STRING}* {FORM}* DECLARATION may be any of the declaration forms. DOCUMENTATION-STRING is stored for retrieval. The FORMs are evaluated as though enclosed by a PROGN. Defining named functions (DEFUN NAME LAMBDA-LIST . BODY) [Macro] Creates a named function called NAME. The arguments LAMBDA-LIST and BODYare as described in the section on lambda expressions above. Definition of functions with this form is integrated with the FILE PACKAGE. It is an error to attempt to redefine a special form (although this isn't tested in CML). Note: In CML there is no BLOCK defined around the body of the function; RETURN-FROM will not work. Declaring global values and named constants (DEFVAR NAME &OPTIONAL INITIAL-VALUE DOCUMENTATION-STRING) [Function] Declares NAME to be a global variable, and if it is unbound, sets its value to INITIAL-VALUE. Note: In CML this form only supports the NAME and INITIAL-VALUE arguments. It is integrated with the FILE PACKAGE and is implemented as a function, rather than as a macro as described in Common Lisp the Language. (DEFCONSTANT VAR VAL &OPTIONAL DOCUMENTATION-STRING) [Special form] This form defines and declares a constant. Notes: In CML DEFCONSTANT is implemented as a special form, rather than as a macro as described in Common Lisp the Language. This form is integrated with the FILE PACKAGE. PREDICATES These are functions which return some value that indicates a "true" or "false" condition. The value for True is, by default, T and for False, NIL. The functions below are required to return NIL when a condition is false. However, truth is generally indicated as a "non-NIL" value, and the functions below may return a "useful value" instead of T (typically, their argument). General type predicates These predicates work with the type specifier forms outlined in the chapter on type specifiers (above). (TYPEP OBJECT TYPE-SPECIFIER) [Function] Returns T if OBJECT is of the type described by TYPE-SPECIFIER, and NIL otherwise. The TYPE-SPECIFIER must be one of the descriptive forms, not declarative. Specific data type predicates (NULL OBJECT) [Function] Returns True if its argument is NIL, False otherwise. Like NOT, but is usually applied to lists instead of truth values. (SYMBOLP OBJECT) [Function] Returns True if OBJECT is a symbol (Interlisp-D LITATOM). (ATOM OBJECT) [Function] Returns True if OBJECT is not a cons cell, False if it is. Note that (ATOM '()) = T because () = NIL Warning: the actual name of this function is CL:ATOM to avoid conflict with the Interlisp-D definition. Faking of packages may make this distinction automatically at read time in some environments (such as a CMLEXEC window, see below). (CONSP OBJECT) [Function] Returns True if OBJECT is a cons cell, False otherwise. NIL is not a cons cell. (LISTP OBJECT) [Function] True only if OBJECT is a cons cell or NIL. (NUMBERP OBJECT) [Function] Returns True if OBJECT is a number in any representation. (INTEGERP OBJECT) [Function] Returns True if object is any kind of integer number (FIXNUM or BIGNUM). (RATIONALP OBJECT) [Function] Returns True if OBJECT is a rational number. Note: although the rational datatype exists in CML it is not hooked into the arithmetic functions. (FLOATP OBJECT) [Function] Returns True if OBJECT is a number in any floating point representation (COMPLEXP OBJECT) [Function] Returns True if OBJECT is a complex number. Note: although the complex datatype exists in CML it is not hooked into the arithmetic functions. (CHARACTERP OBJECT) [Function] Returns True if OBJECT is a character object. (STRINGP OBJECT) [Function] Returns True if OBJECT is a vector whose elements are of type STRING-CHAR. (BIT-VECTOR-P OBJECT) [Function] True of vectors with element type BIT. (VECTORP OBJECT) [Function] True if its argument is any kind of one dimensional array. This includes Interlisp-D ARRAYPs and STRINGPs. (SIMPLE-VECTOR-P OBJECT) [Function] True if its argument is a "simple" vector with element type T (a simple general vector). (SIMPLE-STRING-P OBJECT) [Function] Returns True if OBJECT is a "simple" vector whose elements are of type STRING-CHAR. (SIMPLE-BIT-VECTOR-P OBJECT) [Function] True of bit vectors which are "simple" (see dataypes section or array chapter). (ARRAYP OBJECT) [Function] Returns True if OBJECT is an array of any kind. Note that strings and bitmaps (of the Interlisp-D variety) are considered to be arrays. Equality predicates Common Lisp has a spectrum of equality tests that run from most specific to most general (even matching characters of different case at the general end). (EQ X Y) [Function] This is the fastest and most specific equality test. It will return True if the same object implements X and Y, which is usually when they point at the same memory address. In portable programs, use of EQ is fraught with non-obvious pitfalls (See Common Lisp the Language for some examples). (EQL X Y) [Function] This equality predicate additionally returns True if X and Y are either equal numbers in the same representation (eg, 1.0 SINGLE-FLOAT and 1.0 DOUBLE-FLOAT would not be EQL), or are character objects that represent the same character. (EQUAL X Y) [Function] In addition to the above returns True when the objects have the same structure and whose elements are EQL. Warning: the actual name of this function is CL:EQUAL to avoid conflict with the Interlisp-D definition. Faking of packages may make this distinction automatically at read time in some environments (such as a CMLEXEC window, see below). (EQUALP X Y) [Function] In addition to the above case is ignored in characters and numbers are compared for value (representation being ignored). Logical operators (NOT EXPR) [Function] Returns T if EXPR evaluates to T, NIL otherwise. (AND EXPR1 EXPR2 ...) [Special form] Evaluates the EXPRs left to right. If at any time in that evaluation an EXPR returns NIL evaluation stops and the form returns NIL. If all EXPRs return non-NIL values the entire form returns T. Note: in CML this is a special form and not a Macro. (OR EXPR1 EXPR2 ...) [Special form] Evaluates the EXPRs left to right. If at any time in that evaluation an EXPR returns T evaluation stops and the form returns T. If all EXPRs return NIL values the entire form returns NIL. Note: in CML this is a special form and not a Macro. CONTROL STRUCTURE Reference (QUOTE EXPR) [Special form] Returns its argument unevaluated. Indicates a constant value and keeps an object from being evaluated. (FUNCTION FN) [Special form] Indicates that its argument is to be considered a form that represents an executable function. If FN is a symbol, its function binding is retrieved. If it is a lambda expression, it is returned unevaluated. The compiler will, however, compile such forms when indicated with FUNCTION. Note: in CML, FUNCTION does not create lexical closures. (SYMBOL-VALUE SYMBOL) [Function] Returns the current binding of the value of the symbol. (SYMBOL-FUNCTION SYMBOL) [Function] Returns the function definition which this symbol currently has bound to it. (BOUNDP SYMBOL) [Function] Returns True if SYMBOL has a value bound to it, false otherwise. (FBOUNDP SYMBOL) [Function] Returns True if SYMBOL has a function, macro or special form definitinon. Otherwise it returns false. (SPECIAL-FORM-P SYMBOL) [Function] Returns True if SYMBOL has a functional definition as a special form (doeds not evaluate its arguments). Assignment (SETQ { VAR FORM }* ) [Special form] Assign one or more variables to have some values. Assignment takes place left to right, and thus a later FORM may depend on an earilier VAR. Note: The real name of this is CL:SETQ to avoid conflict with Interlisp's own SETQ. (PSETQ { VAR FORM }* ) [Macro] Assign one or more variables to have some values, with the binding taking place after all the FORMs have been evaluated. The VAR are quoted. Because the binding occurs "in parallel" later FORMs may not depend on earlier VAR bindings. Example: (PSETQ A (MUMBLE X) B A) will assign to A the value of (MUMBLE X) and assign to B the value which A has before the call to PSETQ. (SET { PLACE-EXPR NEWVALUE }* ) [Function] Assign a variable, named by a computed symbol, to have a value. Note: currently we use Interlisp's own SET, which allows only one VAR FORM pair. Generalized variables For any storage location there are generally two operations, access and modify. Normally these operations are given separate names, like CAR and RPLACA. However, its clear we would have fewer names to remember if we had an "inverse" function, one which turned an access form and value into a form that set the storage to that value. This is what SETF does (SETF { PLACE NEWVALUE }* ) [Macro) Given a place specifier PLACE (an access form like CAR, GETPROP or AREF) the macro SETF will produce an appropriate form to set the value of that location. SETF returns the last NEWVALUE. Note: This facility duplicates the Interlisp CHANGE function and is implemented as an interface to it. Also, only one PLACE NEWVALUE pair is allowed in CML. In CML place specifiers can be one of the following "function calls:" CAR CDR (and all abbreviations up to 4 long, eg CDDDDR) AREF ARG BIT CHAR FILL-POINTER GET SBIT SCHAR SVREF SYMBOL-FUNCTION SYMBOL-PLIST SYMBOL-VALUE Only these and specifiers made with DEFINE-MODIFY-MACRO can be used. (DEFINE-MODIFY-MACRO NAME LAMBDA-LIST FUNCTION [DOC-STRING]) [Macro] DEFINE-MODIFY-MACRO creates a macro definition to read, modify and write a place specifier. The LAMBDA-LIST should specify any arguments after the first (which is always a place specifier). LAMBDA-LIST may only have &KEY and &REST lambda keywords in it. The FUNCTION is applied to (in order) the old value in the place specifier plus any other arguments given in the LAMBDA-LIST. The resulting value is stored back into the place specifier. Example: (DEFINE-MODIFY-MACRO INCR (&OPTIONAL (DELTA 1)) +) The modifier macro might look like this (DEFMACRO INCR (PLACE (&OPTIONAL (DELTA 1)) (BQUOTE (SETF , PLACE (+ , PLACE , DELTA)))) Thus, for the form (INCR COUNT 5) The resulting macro expansion would be (SETF COUNT (+ COUNT 5)) (DEFSETF DEFSETF-FORM) [Macro] DEFSETF-FORM is either: ACCESS-FN UPDATE-FN [DOC-STRING] or ACCESS-FN LAMBDA-LIST (STORE-VARIABLE) DEFSETF-BODY DEFSETF-BODY is defined as for LAMBDA-BODY (see above under "Lambda lists"). Inthe simple form, the name of an access function is given, the one for which the settor is to be defined. The update function is the one invoked by SETF, with the new value appended to the end of the arguments normally passed to the update function. Documentation may optionally be attached with the DOC-STRING. As an example if there were two functions defined thus (TAKE WHO INDEX) (GIVE WHO INDEX VALUE) a suitable call to make SETF work for GIVE would be (DEFSETF TAKE GIVE "Hand WHO a value") This presumes that GIVE returns VALUE as required by the definition of SETF. The second format is more complex but versatile. Again, the ACCESS-FN is the existing function for accessing the place. LAMBDA-LIST is applied to the arguments of the place specifier, binding any desired pieces of it. It may contain only &OPTIONAL &REST and &KEY lambda list keywords. STORE-VARIABLE is a symbol which will contain the new value that SETF received. DEFSETF-BODY is then evaluated with LAMBDA-LIST and the STORE-VARIABLE containing the arguments and new value repsectively. It is then the job of the DEFSETF-BODY to create a form that will set the location. The DEFSETF-BODY form need not worry about order of evaluation or multiple evaluations, as its parameter are actually bound to temporary symbols which will have the appropriate forms in them. An example might be a function that had to test a lock on a location before writing to it. Given functions called (ASYNCH-READ MEMORY INDEX) (ASYNCH-WRITE MEMORY INDEX VALUE) a suitable definition (assuming the existance of a LOCK function) would be (DEFSETF ASYNCH-READ (MEMORY INDEX &OPTIONAL (TIMEOUT 10)) (NEW-VALUE) "Obtain lock before writing to indexed location" (BQUOTE (WITH-LOCK (, MEMORY , INDEX , TIMEOUT) (ASYNCH-WRITE , MEMORY , INDEX , NEW-VALUE) ))) Note that this example doesn't need to address the problem of the argument forms getting evaluated more than once, as that's all taken care of by DEFSETF.. Function invocation (APPLY FN ARG &REST MORE-ARGS) [Function] Invoke a function on a set of args. The last of the args (that is, the last of all of them, not just MORE-ARGS) is presumed to be a list and is appended to all the preceding arguments. The elements of this list are then passed to the function FN as arguments. Note: In CML this function is called CL:APPLY to avoid conflict with Interlisp's APPLY. ( FUNCALL FN &REST ARGUMENTS) [Function] Call the function FN with the elements of the list ARGUMENTS as its arguments. FUNCTION is handy because, being a function itself, it evaluates the FN argument to produce the object to be called. Simple sequencing (PROGN &REST FORMS) [Special form] (PROG1 FORM1 &REST FORMS) [Macro] (PROG2 FORM1 FORM2 &REST FORMS) [Macro] These function as in Interlisp-D, except that PROG1 and PROG2 are implemented with NLAMBDAs rather than MACROs. Establishing new variable bindings (LET BINDING-FORMS &REST BODY-FORMS) [Special form] LET is an alternative to LAMBDA, which puts the bindings "up front" like PROG does. Each of the BINDING-FORMS looks like either ( VAR) or (VAR VALUE) If no value is given for a variable it is initialized to NIL. All values are first computed (left to right) and then assigned, effectively occurring "in parallel." The BODY-FORMS are as for lambda expressions (see above). An example: (LET ((X (MUMBLE)) (Y (GRUMBLE))) (DO.FIRST.THING) (DO.LAST.THING)) would be like ((LAMBDA (X Y) (DO.FIRST.THING) (DO.LAST.THING)) (MUMBLE) (GRUMBLE)) Note: in CML this is implemented as a macro instead of as a special form. (LET* BINDING-FORMS &REST BODY-FORMS) [Special form] LET* is similar to LET, but the bindings happen sequentially rather than in parallel. E.g. (LET* ((X (MUMBLE)) (Y (GRUMBLE))) (DO.FIRST.THING) (DO.LAST.THING)) would be like ((LAMBDA (X) ((LAMBDA (Y) (DO.FIRST.THING) (DO.LAST.THING)) (GRUMBLE)) (MUMBLE)) Note: in CML this is implemented as a macro instead of as a special form. (PROGV VAR-LIST VAL-LIST &REST FORMS) [Special form] PROGV provides a means for lambda-binding a list of variables like PROGN except that the first two items in the "arglist" are evaluated to obtain a list of variable names and a list of values; then the variables are bound (as SPECVARS) to the corresponding values, and the forms in the body executed, with the value of the last one being the return value of the PROGV. This functions exists primarily as an aid in writing Lisp-like interpreters in Lisp. Note: in CML this is implemented as a macro instead of as a special form. Conditionals (IF TEST THEN &OPTIONAL ELSE) [Special form] Similar to COND and friends. If TEST evaluates non-NIL then THEN is evaluated, else (if provided) ELSE. Only one of either THEN or ELSE are evaluated and IF returns whatever that form does. Note: Called CL:IF and implemented as a macro. (WHEN TEST &REST FORMS) [Special form] In Common Lisp this is not a looping construct! TEST is evaluated. If the result is non-NIL then the FORMS are evaluated (left to right) and the value of the last one is returned, otherwise NIL is returned. Note: called CL:WHEN and implemented as a macro. (UNLESS TEST &REST FORMS) [Special form] In Common Lisp this is not a looping construct! TEST is evaluated. If the result is NIL then the FORMS are evaluated (left to right) and the value of the last one is returned, otherwise NIL is returned. Note: called CL:UNLESS and implemented as a macro. (COND &REST CONDITIONAL-FORMS) [Macro] This is the classical COND form, as described inthe Interlisp Refernce manual. Note: In CML this is implemented as a special form. (CASE KEYFORM &REST KEYED-CLAUSES) [Macro] Selects a set of forms to evaluated based on a key. The KEYFORM is evaluated and compared to the keys in the KEYED-CLAUSES left to right (and to keys within KEYLISTs). A single KEYED-CLAUSE is (KEY . FORMS) or (KEYLIST . FORMS) The KEYs are not evaluated. It is an error for a KEY to appear more than once in the whole expression. This means that the KEYED-CLAUSES (aside from the optional default clause, see below) are order independant. The first one to match selects those FORMS to be evaluated, value of the last of which is returned (or NIL if there were no FORMS). If the value of the KEYFORM does not match any of the given KEYs NIL is returned. The last of the KEYED-CLAUSES may have a KEY of either T or OTHERWISE. If none of the other keys matches then the FORMS following this one are evaluated. This default clause may only appear as the last of the clauses. (TYPECASE OBJECT-EXPR &REST TYPE-CLAUSES) [Macro] Selects a set of forms to evaluate based on the type of an object. OBJECT-EXPR is evaluated to produce an object of some type and it is tested against each of the TYPE-CLAUSES left to right, until one matches. A single TYPE-CLAUSE is (TYPESPEC . FORMS) None of the TYPESPECs are evaluated. The first one to match selects the corresponding FORMS, which are evaluated left to right and return the value of the last (or NIL if there were no FORMS). The TYPESPEC in an earlier TYPE-CLAUSE may shadow a later one, ie the TYPESPECs are allowed to overlap in selecting objects. Like CASE, there can be a T or OTHERWISE clause which will always succeed in being selected. Iteration (DO VAR-SET-STEP-FORMS END-FORM &REST PROGBODY) [Macro] (DO* VAR-SET-STEP-FORMS END-FORM &REST PROGBODY) [Macro] These are the primary Common Lisp iteration forms. DO binds in parallel and DO* binds sequentially. The zero or more VAR-SET-STEP-FORMS indicate the names of local variables, how they are to be initialized, and how they are to be reset at each iteration. The syntax of one VAR-SET-STEP-FORM is either (VAR) or (VAR INIT-FORM) or (VAR INIT-FORM STEP-FORM) VAR is an (unevaluated) symbol that names the local variable. If an INIT-FORM is not given then VAR is initialized to NIL. The END-FORM has a conditional test that terminates the iteration and may include zero or more result expressions, which are evaluated left to right and the last of whose values is returned. Its syntax is (STOP-TEST-EXPR . RESULT-EXPRS) STOP-TEST-EXPR halts the loop and begins evaluated the RESULT-EXPRS if non-NIL. If no RESULT-EXPRS are given, then DO returns NIL, otherwise it returns the value of the last RESULT-EXPR to be evaluated. The PROGBODY list is as described below in PROG. Note: these functions are called CL:DO and CL:DO* to avoid conflict with Interlisp-D's built in iteration operators. (DOLIST ( VAR LISTFORM [RESULTFORM] ) &REST PROGBODY) [Macro] This is a simple function to iterate a local variable bound to the successive elements of a list over a body of forms. VAR is the symbol (unevaluated) naming the local variable. LISTFORM is evaluated to produce the list of values. The optional single RESULTFORM may compute a value to return, otherwise NIL is returned. PROGBODY is described below under PROG. (DOTIMES ( VAR COUNTFORM [RESULTFORM] ) &REST PROGBODY) [Macro] Iterates a local variable through the range of integers from zero (inclusive) to the result of COUNTFORM (exclusive). If COUNTFORM is less than or equal to zero the PROGBODY forms are not evaluated. VAR is the symbol (unevaluated) naming the local variable. The optional single RESULTFORM may compute a value to return, otherwise NIL is returned. PROGBODY is described below under PROG. Mapping (MAPCAR FN &REST ARG-MAPLISTS) [Function] FN is a function of "n" arguments. The length of ARG-MAPLISTS must be equal to "n." The function is called with corresponding elements of the ARG-MAPLISTS until one or all of the lists end. Note: in CML this is called CL:MAPCAR to avoid conflict with the existing Interlisp-D function name. The "Program Feature" (TAGBODY &REST TAGBODY) [Special form] Not implemented yet. The syntax of a TAGBODY is a list of zero or more elements each of which may be either a symbol, which is a tag or label, or a list, which is an expression to be evaluated. (PROG BINDING-FORMS &REST PROGBODY) [Special form] The classical PROG. As documented inthe Interlisp-D manual. The form of the PROGBODY is zero or more declaration forms appended to a TAGBODY. (PROG* BINDING-FORMS &REST PROGBODY) [Special form] PROG* is the similar extension to PROG, namely the bindings happen "sequentially" rather than in parallel. Note: implemented as a MACRO in CML. (GO TAG) [Special form] The classical GO. As documented inthe Interlisp-D manual. Dynamic non-local exits (CATCH TAG &REST FORMS) [Special form] CATCH provides a return point for a non-lexically initiated exit from its scope. It sets up a dynamic scoping for TAG. (THROW TAG VALUE) [Function] If at any time during the execution of any of the FORMS of a CATCH there is a call to THROW, then the CATCH will be exited with VALUE as its value; but if no such THROW is executed, then the normal return value of FORMS will be the value of the CATCH. The forms are evaluated as though they were in a PROGN. Both CATCH and THROW "evaluate their arguments", but CATCH does so in a way that the first argument, the tag, is available during the evaluation of the second argument. (*CATCH TAG &REST FORMS) [Special form] (*THROW TAG VALUE) [Function] *CATCH and *THROW are provided for compatiblity with MacLisp and FranzLisp. (UNWINDPROTECT FORM-TO-EVAL &REST CLEANUP-FORMS) [Special form] UNWINDPROTECT is very similar to Interlisp-D's RESETLST or RESETSAVE. It will evaluate FORM-TO-EVAL, and upon exit will execute all the remaining CLEANUP-FORMS. "Exiting" also means an aborting due to RESET (or HARDRESET) or any error. Unfortunately, the Interlisp RETFROM and RETTO do not currently execute the RESETSAVE forms under a RESETLST when RETFROM'ing a frame higher in the stack than the one with the RESETLST in it; this has the effect that a THROW to a frame higher than an UNWINDPROTECT will currently not actually do its cleanup forms. MACROS The defmacro form is provided (it is now a part of Interlisp-D) specifies how it accepts arguments in a similar manner to Common Lisp lambdas. One interesting difference is that computed keywords are meaningless in a form to be macro expanded. The following documentation is based on that in the Interlisp Reference Manual. Macros defined with the function DEFMACRO are much like "computed" macros (see the Interlisp Reference manual section under Macros), in that they are defined with a form that is evaluated, and the result of the evaluation is used (evaluated or compiled) in place of the macro call. However, DEFMACRO macros support complex argument lists with optional arguments, default values, and keyword arguments. In addition, argument list destructuring is supported. (DEFMACRO NAME ARGS FORM) [Special form] Defines NAME as a macro with the arguments ARGS and the definition form FORM (NAME, ARGS, and FORM are unevaluated). If an expression starting with NAME is evaluated or compiled, arguments are bound according to ARGS, FORM is evaluated, and the value of FORM is evaluated or compiled instead. The interpretation of ARGS is described below. Note: Unlike the function DEFMACRO in Common Lisp, this function currently does not remove any function definition for NAME. ARGS is a list that defines how the argument list passed to the macro NAME is interpreted. Specifically, ARGS defines a set of variables that are set to various arguments in the macro call (unevaluated), that FORM can reference to construct the macro form. In the simplest case, ARGS is a simple list of variable names that are set to the corresponding elements of the macro call (unevaluated). For example, given: (DEFMACRO FOO (A B) (LIST 'PLUS A B B)) The macro call (FOO X (BAR Y Z)) will expand to (PLUS X (BAR Y Z) (BAR Y Z)) The list ARGS can include any of a number of special "&-keywords" (beginning with the character "&") that are used to set variables to particular items from the macro call form, as follows: &OPTIONAL - Used to define optional arguments, possibly with default values. Each element on ARGS after &OPTIONAL until the next &-keyword or the end of the list defines an optional argument, which can either be a symbol or a list, interpreted as follows: VAR - If an optional argument is specified as a litatom, that variable is set to the corresponding element of the macro call (unevaluated). (VAR DEFAULT) - If an optional argument is specified as a two element list, VAR is the variable to be set, and DEFAULT is a form that is evaluated and used as the default if there is no corresponding element in the macro call. (VAR DEFAULT VARSETP) - If an optional argument is specified as a three element list, VAR and DEFAULT are the variable to be set and the default form, and VARSETP is a variable that is set to T if the optional argument is given in the macro call, NIL otherwise. This can be used to determine whether the argument was not given, or whether it was specified with the default value. For example, after (DEFMACRO FOO (&OPTIONAL A (B 5) (C 6 CSET)) FORM) expanding the macro call (FOO) would cause FORM to be evaluated with A set to NIL, B set to 5, C set to 6, and CSET set to NIL. (FOO 4 5 6) would be the same, except that A would be set to 4 and CSET would be set to T. &REST or &BODY - Used to get a list of all additional arguments from the macro call. Either &REST or &BODY should be followed by a single litatom, which is set to a list of all arguments to the macro after the position of the &-keyword. For example, given (DEFMACRO FOO (A B &REST C) FORM) expanding the macro call (FOO 1 2 3 4 5) would cause FORM to be evaluated with A set to 1, B set to 2, and C set to (3 4 5). Note: If the macro calling form contains keyword arguments (see&KEY below) these are included in the &REST list. &KEY - Used to define keyword arguments, that are specified in the macro call by including a "keyword" (a litatom starting with the character ":") followed by a value. Each element on ARGS after &KEY until the next &-keyword or the end of the list defines a keyword argument, which can either be a litatom or a list, interpreted as follows: VAR (VAR) ((KEYWORD VAR)) - If a keyword argument is specified by a single litatom VAR, or a one-element list containing VAR, it is set to the value of a keyword argument, where the keyword used is created by adding the character ":" to the front of VAR. If a keyword argument is specified by a single-element list containing a two-element list, KEYWORD is interpreted as the keyword (which should start with the letter ":"), and VAR is the variable to set. (VAR DEFAULT) ((KEYWORD VAR) DEFAULT) (VAR DEFAULT VARSETP) ((KEYWORD VAR) DEFAULT VARSETP) - If a keyword argument is specified by a two or three-element list, the first element of the list specifies the keyword and variable to set as above. Similar to &OPTIONAL (above), the second element DEFAULT is a form that is evaluated and used as the default if there is no corresponding element in the macro call, and the third element VARSETP is a variable that is set to T if the optional argument is given in the macro call, NIL otherwise. For example, the form (DEFMACRO FOO (&KEY A (B 5 BSET) ((:BAR C) 6 CSET)) FORM) Defines a macro with keys :A, :B (defaulting to 5), and :BAR. Expanding the macro call (FOO :BAR 2 :A 1) would cause FORM to be evaluated with A set to 1, B set to 5, BSET set to NIL, C set to 2, and CSET set to T. &ALLOW-OTHER-KEYS - It is an error for any keywords to be suplied in a macro call that are not defined as keywords in the macro argument list, unless either the &-keyword &ALLOW-OTHER-KEYS appears in ARGS, or the keyword :ALLOW-OTHER-KEYS (with a non-NIL value) appears in the macro call. &AUX - Used to bind and initialize auxiliary varables, using a syntax similar to LET . Any elements after &AUX should be either litatoms or lists, interpreted as follows: VAR - Single litatoms are interpreted as auxiliary variables that are initially bound to NIL. (VAR EXP) - If an auxiliary variable is specified as a two element list, VAR is a variable initially bound to the result of evaluating the form EXP. For example, given (DEFMACRO FOO (A B &AUX C (D 5)) FORM) C will be bound to NIL and D to 5 when FORM is evaluated. &WHOLE - Used to get the whole macro calling form. Should be the first element of ARGS, and should be followed by a single litatom, which is set to the entire macro calling form. Other &-keywords or arguments can follow. For example, given (DEFMACRO FOO (&WHOLE X A B) FORM) Expanding the macro call (FOO 1 2) would cause FORM to be evaluated with X set to (FOO 1 2), A set to 1, and B set to 2. DEFMACRO also supports argument list "destructuring," a facility for accessing the structure of individual arguments to a macro. Any place in an argument list where a litatom is expected, an argument list (in the form described above) can appear instead. Such an embedded argument list is used to match the corresponding parts of that particular argument, which should be a list structure in the same form. In the simplest case, where the embedded argument list does not include &-keywords, this provides a simple way of picking apart list structures passed as arguments to a macro. For example, given (DEFMACRO FOO (A (B (C . D)) E) FORM) Expanding the macro call (FOO 1 (2 (3 4 5)) 6) would cause FORM to be evaluated with with A set to 1, B set to 2, C set to 3, D set to (4 5), and E set to 6. Note that the embedded argument list (B (C . D)) has an embedded argument list (C . D). Also notice that if an argument list ends in a dotted pair, that the final litatom matches the rest of the arguments in the macro call. An embedded argument list can also include &-keywords, for interpreting parts of embedded list structures as if they appeared in a top-level macro call. For example, given (DEFMACRO FOO (A (B &OPTIONAL (C 6)) D) FORM) Expanding the macro call (FOO 1 (2) 3) would cause FORM to be evaluated with with A set to 1, B set to 2, C set to 6 (because of the default value), and D set to 3. Warning: Embedded argument lists can only appear in positions in an argument list where a list is otherwise not accepted. In the above example, it would not be possible to specify an embedded argument list after the&OPTIONAL keyword, because it would be interpreted as an optional argument specification (with variable name, default value, set variable). However, it would be possible to specify an embedded argument list as the first element of an optional argument specification list, as so: (DEFMACRO FOO (A (B &OPTIONAL ((X (Y) Z) '(1 (2) 3))) D) FORM) In this case, X, Y, and Z default to 1, 2, and 3, respectively. Note that the "default" value has to be an appropriate list structure. Also, in this case either the whole structure (X (Y) Z) can be supplied, or it can be defaulted (i.e. is not possible to specify X while letting Y default). DECLARATIONS Currently the only declaration of interest is one for array types: (DECLARE (TYPE (ARRAY FLOAT (* * *)))) This will cause the compiler to compile AREF and SETF forms in a much more optimized fashion. Caution must be used, as the resulting code will only work for datatype ARRAY and only for the specific element type declared. Type declaration for forms (THE TYPE-SPEC FORM) [Special form] The TYPE-SPEC is not evaluated. Declares that the result of evaulating FORM will be of the given type. It is an error if this is not so. Note: In CML this functions as a type check and will signal an error. SYMBOLS Symbols are objects that name things in Lisp environments. They hold three pieces of information: a name, a package cell (not implemented in CML), and a property list. In CML, these are simply LITATOMs. Naming restrictions apply as for Interlisp-D (but see in the Miscellaneous chapter the section on the Common Lisp exec windows). As in Interlisp-D, symbols may have both macro definitions and function definitions, be careful. Some restriction of this feature to meet the standard will be made in the release of Xerox Common Lisp. Property list (GET SYMBOL PROP &OPTIONAL DEFAULT-VALUE) [Function] Get a property from a symbol. Note: in CML this uses Interlisp-D's GETPROP function; the optional DEFAULT-VALUE arg is not implemented. (SETF (GET SYMBOL PROP) VALUE) [Form] Set a symbol's property to a value. (REMPROP SYMBOL PROP) [Function] Remove a property from a symbol. (SYMBOL-PLIST SYMBOL) [Function] Return the symbol's entire property list. (SETF (SYMBOL-PLIST SYMBOL) NEW-PLIST) [Form] Set a symbol's property list. PACKAGES The primary mechanism for distinguishing Common Lisp and Interlisp constructs will be the "package" system (not to be confused with the Interlisp-D file package.) Common Lisp specifies that symbols (atoms in Interlisp terminology) are actually stored in independent "packages." Each package independently hashes the characters of the name into a unique atom. Thus, it is possible to have two different symbols with the same characters in their name. Whenever one is reading in symbols, there is one package which is the "current" package. To look up symbols in a different package, one must supply a package prefix. Interlisp will reside in a single package, the Interlisp package (abbreviated IL). When the current package is IL, Common Lisp names which conflict with Interlisp ones will appear with a Common Lisp package prefix (e.g., CL:DO for Common Lisp's DO macro, CL:* for Common Lisp's multiply.) Most notably, the difference between function call semantics in Interlisp and Common Lisp is denoted distinguishing between IL:LAMBDA and CL:LAMBDA. Interlisp's LAMBDA will continue to mean that all arguments are optional and default to NIL, extra arguments are discarded, and that variables by default are dynamically visible. Common Lisp's LAMBDA, on the other hand, implies that lambda list keywords like &KEY and &OPTIONAL are allowed, arguments are required unless otherwise noted, and that variables by default are lexically bound. Both systems can be freely intermixed, of course. Thus, packages in Xerox Common Lisp are "faked" by CML. CML doesn't have packages, even though Xerox Common Lisp will. Instead, those Common Lisp features whose implementation would conflict with an Interlisp feature by the same name are merely named by a symbol which starts with CL:. The CMLEXEC package allows one to open up a window in which all type-in is translated as if there were packages (see below under MISC). NUMBERS The file CMLARITH contains some basic arithmetic features from Common Lisp. In order to implement these it is necessary to modify the behavior of the CLISP package, thus, loading this package may break the loading of files containing some kinds of CLISP forms. In the actual release we expect to have file load environments which will take care of this. CMLARITH also implements the RATIO and COMPLEX datatypes, although in CML these are not hooked into the arithmetic functions. Predicates on numbers (ZEROP NUMBER) [Function] NUMBER must be of type number. Returns True if NUMBER is any kind of zero, False otherwise. (PLUSP NUMBER) [Function] NUMBER must be a non-complex number. Returns True if NUMBER is greater than zero, False otherwise. (MINUSP NUMBER) [Function] NUMBER must be a non-complex number. Returns True if NUMBER is less than zero, False otherwise. (ODDP NUMBER) [Function] NUMBER must be an integer. Returns True if NUMBER can't be evenly divided by two, False otherwise. (EVENP NUMBER) [Function] NUMBER must be an integer. Returns True if NUMBER is evenly divisible by two, False otherwise. Comparisons on numbers These functions must only be called with arguments that are numbers. They will work with sequences containing mixed types of numbers. (= NUMBER &REST NUMBERS) [Function] (/= NUMBER &REST NUMBERS) [Function] (< NUMBER &REST NUMBERS) [Function] (> NUMBER &REST NUMBERS) [Function] (<= NUMBER &REST NUMBERS) [Function] (>= NUMBER &REST NUMBERS) [Function] These functions test sequences of numbers. If more than two arguments are given testing is done by overlapping pairs, ie = means all equal, > means increasing, etc. (MAX NUMBER &REST NUMBERS) [Function] (MIN NUMBER &REST NUMBERS) [Function] These functions return either the minimum or maximum value found in a sequence of numbers. Arithmetic operations These functions must only be called with arguments that are numbers. They will work with sequences containing mixed types of numbers. (+ NUMBER &REST NUMBERS) [Function] (- NUMBER &REST NUMBERS) [Function] (* NUMBER &REST NUMBERS) [Function] (/ NUMBER &REST NUMBERS) [Function] Generic arithmetic. Will coerce to apprpriate enclosing type if neccessary. (1+ NUMBER) [Function] Return the number incremented by one. (1- NUMBER) [Function] Return the number decremented by one. (INCF PLACE &OPTIONAL (INCREMENT 1)) [Macro] Increment the number at PLACE by the number INCREMENT, storing the result back into PLACE. (DECF PLACE &OPTIONAL (DECREMENT -1)) [Macro] Decrement the number at PLACE by the number DECREMENT, storing the result back into PLACE. (CONJUGATE NUMBER) [Function] Returns the complex conjugate of NUMBER. The conjugate of a non-complex number is itself. (GCD &REST INTEGERS) [Function] Returns the greatest common divisor of the INTEGERS. Note: this function only accepts 2 args in CML. (LCM INTEGER &REST INTEGERS) [Function] Not yet implemented. Exponential and logorithmic functions (EXP NUMBER) [Function] Returns epsilon raised to the power of NUMBER. (EXPT BASE-NUMBER POWER-NUMBER) [Function] Returns BASE-NUMBER raised to the POWER-NUMBER. (LOG NUMBER &OPTIONAL BASE) [Function] Returns the logarithm of NUMBER in BASE. Note: in CML there is no BASE argument permitted; this function returns only natural (base epsilon) logarithms. (SQRT NUMBER) [Function] Returns the square root of NUMBER. (ISQRT NUMBER) [Function] Not yet implemented. Trignometric and related functions (ABS NUMBER) [Function] Returns the absolute value of NUMBER. (PHASE NUMBER) [Function] Returns the angle of a polar representation of a complex number's parts, with the imaginary part as y and real part as x. If NUMBER is not a complex number, then a float in the same format is returned. (SIGNUM NUMBER) [Function] Returns -1.0, 0 or 1.0 if the NUMBER is negative, zero or positive respectively. (SIN RADIANS) [Function] (COS RADIANS) [Function] (TAN RADIANS) [Function] Standard trigonometric functions. Arguments in radians. Note: these all have CL: names to avoid conflist with Interlisp functions, which take args in degrees. PI [Constant] The value PI in as precise a float as the implementation allows. Type conversions and number component extractions (FLOAT NUMBER &OPTIONAL OTHER) [Function] Convert any number to a float. OTHER is not implemented. Logical operations on numbers These operations all requires integers and treat their arguments as signed two's complement numbers. (LOGIOR &REST INTEGERS) [Function] Returns the bit-wise inclusive-or of the INTEGERS. Given no arguments this function returns zero. (LOGXOR &REST INTEGERS) [Function] Returns the bit-wise exclusive-or of the INTEGERS. Given no arguments this function returns zero. (LOGAND &REST INTEGERS) [Function] Returns the bit-wise logical-and of the INTEGERS. Given no arguments this function returns negative one. (LOGEQV &REST INTEGERS) [Function] Returns the bit-wise logical-equivalence (exclusive nor) of the INTEGERS. Given no arguments this function returns negative one. (LOGNAND INTEGER1 INTEGER2) [Function] (LOGNOR INTEGER1 INTEGER2) [Function] (LOGANDC1 INTEGER1 INTEGER2) [Function] (LOGANDC2 INTEGER1 INTEGER2) [Function] (LOGORC1 INTEGER1 INTEGER2) [Function] (LOGORC2 INTEGER1 INTEGER2) [Function] Logical bit-wise operations on two arguments (these don't associate neatly): NAND (not of and) NOR (not of or) AND complement of first argument with (plain) second AND (plain) first argument with complement of second OR complement of first argument with (plain) second OR (plain) first argument with complement of second (BOOLE OP INTEGER1 INTEGER2) [Function] BOOLE-CLR [Constant] BOOLE-SET [Constant] BOOLE-1 [Constant] BOOLE-2 [Constant] BOOLE-C1 [Constant] BOOLE-C2 [Constant] BOOLE-AND [Constant] BOOLE-IOR [Constant] BOOLE-XOR [Constant] BOOLE-EQV [Constant] BOOLE-NAND [Constant] BOOLE-NOR [Constant] BOOLE-ANDC1 [Constant] BOOLE-ANDC2 [Constant] BOOLE-ORC1 [Constant] BOOLE-ORC2 [Constant] As above, but with the selection of operation given as a constant. BOOLE-CLR returns zero, BOOLE-SET returns negative one, BOOLE-1 returns the first argument, BOOLE-2 the second, with the rest similar to the LOG... functions above. (LOGNOT INTEGER) [Function] Returns the logical not of its argument (inverts all bits). (LOGTEST INTEGER1 INTEGER2) [Function] Returns true if any bits in INTEGER2, masked by those in INTEGER1, are set. (LOGBITP INDEX INTEGER) [Function] True if the INDEXth bit of INTEGER is set (0 index is least significant position). (ASH INTEGER COUNT) [Function] Arithmetic shift left of INTEGER by COUNT positions (or right if COUNT is negative). Left shift moves in zeroes from the right, right shift propogates the sign bit toward the left. (INTEGER-LENGTH INTEGER) [Function] If INTEGER is positive INTEGER-LENGTH returns the number of bits required to hold it in unsigned form. If INTEGER is negative it returns one less than the number of bits needed to hold it in signed two's complement form. Byte manipulation functions These functions operate on continuous fields of bits in an integer of arbitrary width referred to as a "byte." (BYTE SIZE POSITION) [Function] Creates a specifier for the byte beginning at POSITION (0 is the index of the low order bit) and continuing for SIZE bits in width. Note: in CML this exists as a Macro. (BYTE-SIZE BYTESPEC) [Function] (BYTE-POSITION BYTESPEC) [Function] Return the components of a byte specifier. (LDB BYTESPEC INTEGER) [Function] "Load byte." Returns the byte specified by BYTESPEC from INTEGER (right justified). Note: in CML this exists as a Macro. (LDB-TEST BYTESPEC INTEGER) [Function] Returns True if the byte specified by BYTESPEC in INTEGER is non-zero. (MASK-FIELD BYTESPEC INTEGER) [Function] Like ldb ("load byte") this returns the byte specified by BYTESPEC in INTEGER, however the byte is returned "in place., ie as though the BYTESPEC were a mask filled with ones, which INTEGER was ANDed with. (DPB NEWBYTE BYTESPEC INTEGER) [Function] Returns INTEGER with NEWBYTE's low order bits (width specified by BYTESPEC) replacing the field specified by BYTESPEC. Note: in CML this exists as a Macro. (DEPOSIT-FIELD NEWBYTE BYTESPEC INTEGER) [Function] Returns INTEGER with its BYTESPEC field replaced by the BYTESPEC field of NEWBYTE. CHARACTERS All of the functions in this chapter of Common Lisp the Language are implemented. All of the various I/O formats are implemented (character syntax). In CML (and Xerox Common Lisp), there are 2^16 possible character codes, in accordance with the Xerox Character Code standard. Thus, CHAR-CODE-LIMIT is 65536. Our experience with fonts in the Interlisp-D environment has shown that the single "font-bits" attribute of Common Lisp is inadequate to handle the complexity of attaching fonts to characters. Rather than trying to shoehorn a complex font system into a small packet of information, we have chosen to set CHAR-FONT-LIMIT to 1; that is, font information for characters "lies." It is not part of the character code. In addition, CHAR-BITS-LIMIT is also 1; the nuance of additional shift-bits being handled by the keyboard decoding system rather than the character system. Because of this, all objects of type CHARACTER are of type STRING-CHARACTER and can occur in strings. These limits are implicitly allowed by the Common Lisp standard. Attributes CHAR-CODE-LIMIT [Constant] The upper (exclusive) bound for integers describing a character's code attribute. In CML and Xerox Common Lisp this is 65536. CHAR-FONT-LIMIT [Constant] The upper (exclusive) bound for integers describing a character's font attribute. In CML and Xerox Common Lisp this is 1 (indicating, by the standard, that this is not supported). CHAR-BITS-LIMIT [Constant] The upper (exclusive) bound for integers describing a character's bits attribute. In CML and Xerox Common Lisp this is 1 (indicating, by the standard, that this is not supported). Predicates (STANDARD-CHAR-P CHAR) [Function] Any character with non-zero bits or font attributes is non-standard. This function returns True if the character CHAR is of type STANDARD-CHAR. (GRAPHIC-CHAR-P CHAR) [Function] Returns True if the character CHAR is a printing character, ie has a graphic representation. (STRING-CHAR-P CHAR) [Function] Returns True if the character CHAR is of type STRING-CHAR and may be stored into strings. (ALPHA-CHAR-P CHAR) [Function] Returns True if the character CHAR is an alphabetic character (A - Z or a- z). (UPPER-CASE-P CHAR) [Function] Returns True if the character CHAR is an uppercase alphabetic character (A - Z). (LOWER-CASE-P CHAR) [Function] Returns True if the character CHAR is a lowercase alphabetic character (a - z). (BOTH-CASE-P CHAR) [Function] Returns True if the character CHAR is an alphabetic character (of either case) and has a corresponding character in the other case, ie it can be converted to the other case. (DIGIT-CHAR-P CHAR &OPTIONAL (RADIX 10)) [Function] Returns True if the character CHAR is a numeric digit inthe given radix RADIX. (ALPHANUMERICP CHAR) [Function] Returns True if the character CHAR is either an alphabetic character (either case) or a numeric digit. (CHAR= CHAR &RESTCHARS) [Function] (CHAR/= CHAR &RESTCHARS) [Function] (CHAR< CHAR &RESTCHARS) [Function] (CHAR> CHAR &RESTCHARS) [Function] (CHAR>= CHAR &RESTCHARS) [Function] (CHAR<= CHAR &RESTCHARS) [Function] Analogous to the numeric testing functions. Returns true if the corresponding function is true for all overlapping pairs of characters in the total sequence. For example, for CHAR= returns true if all the characters are the same, CHAR/=, all different, CHAR<, in descending order. Common Lisp guaruntees that : A < B < ... < Z a < b < ... < z 0 < 1 < ... < 9 and that both of the following will hold: either 9 < A or Z < 0 either 9 < a or z < 0 (CHAR-EQUAL CHAR &REST CHARS) [Function] (CHAR-NOT-EQUAL CHAR &REST CHARS) [Function] (CHAR-LESSP CHAR &REST CHARS) [Function] (CHAR-GREATERP CHAR &REST CHARS) [Function] (CHAR-NOT-GREATERP CHAR &REST CHARS) [Function] (CHAR-NOT-LESSP CHAR &REST CHARS) [Function] These are exactly like the functions CHAR=, CHAR/=, CHAR<, etc. except that case is ignored. Construction and selection (CHAR-CODE CHAR) [Function] Returns the code attribute of the character CHAR. This will always be a positive integer less than CHAR-CODE-LIMIT. (CHAR-BITS CHAR) [Function] Returns the bits attribute of the character CHAR. This will always be zero in Xerox Common Lisp. (CHAR-FONT CHAR) [Function] Returns the font attribute of the character CHAR. This will always be zero in Xerox Common Lisp. (CODE-CHAR CODE &OPTIONAL (BITS 0) (FONT 0)) [Function] If the current implementation limits allow, using the positive integer CODE create and return a character object with the attributes given, otherwise return NIL. (MAKE-CHAR CHAR &OPTIONAL (BITS 0) (FONT 0)) [Function] If the current implementation limits allow, using the existing character CHAR create and return a character object with the attributes given, otherwise return NIL. Character conversions (CHARACTER OBJECT) [Function] Coerces its argument into an object of type CHARACTER if possible. Usually useful for converting single character atoms to characters. Note: the actual name of this function is CL:CHARACTER to avoid conflict with the Interlisp-D function . (CHAR-UPCASE CHAR) [Function] (CHAR-DOWNCASE CHAR) [Function] If the character CHAR is BOTH-CASE-P and of either upper or lower case, then the character of opposite case is returned, otherwise CHAR is returned unchanged. (DIGIT-CHAR WEIGHT &OPTIONAL (RADIX 10) (FONT 0)) [Function] Converts an integer WEIGHT into the corresponding character that prints a number of that "weight" in radix RADIX and returns it, unless there can be no corresponding character, in which case NIL is returned. As long as RADIX < 36 and WEIGHT is a positive integer less than radix DIGIT-CHAR will not return NIL (CHAR-INT CHAR) [Function] Returns a positive integer encoding the complete character CHAR, including font and bits attributes. Note that (because font and bits will always be zero in Xerox Common Lisp) this is the same as CHAR-CODE. (INT-CHAR INTEGER) [Function] Convert a positive integer encoding a complete character, including font and bits attributes, into an object of type CHARACTER. If this is not possible INT-CHAR returns False. (CHAR-NAME CHAR) [Function] If the character CHAR is a named character, returns a string which holds its name, otherwise returns NIL. See the chapter below called I/O for a list of character names and corresponding codes. (NAME-CHAR NAME) [Function] If the object NAME is coercable into a string that holds the name of a character, then that corresponding character is returned, otherwise NIL. See the chapter below called I/O for a list of character names and corresponding codes. Character control bit functions These features are unimplemented in Xerox Common Lisp; a separate keyhandler facility does this. SEQUENCES CML contains no sequence functions. LISTS Some of Interlisp-D's list manipulation functions are Common Lisp compatible. The Common Lisp specific list functions are not implemented in the CML release. (LIST* VALUE1 VALUE2 ... VALUEN VALUE-LIST) [Function] LIST* is similar to LIST except that the last argument is the final CDR of the resultant list rather than the last element. For example (LIST 'A 'B 'C) -> (A B C) (LIST* 'A 'B 'C) -> (A B . C) HASH TABLES A hashtable associates one lisp object with another, referred to as the key and the value. This is done as a tradeoff, where more space is used to store the objects so that access time is significantly reduced. Putting a value into a hashtable is a destructive operation, ie only one object may be stored under a given key. A second call to PUTHASH with the same key will lose any previously associated value. When an object is placed into a hashtable an operation (called hashing) turns the key into an index in the table. When the index is performed the key given must be matched against any existing key at that index in the table. In order to effieciently utilize space the "hashing" operation should spread out the keys evenly, thus its desirable to have a hashing operation that suits the type of key you're using. There are three kinds of hashtable, based on the equality test used to compare keys. These are: equal, eql, and eq. While the Interlisp-D hash array facilities are functionally equivalent to Common Lisp there is no interface using their names. ARRAYS A complete description of the Common Lisp array facility can be found in the CMLARRAY Package's documentation. STRINGS Implemented with the Interlisp STRINGP datatype. The comparison functions of this chapter are unimplemented. STRUCTURES Structures are a way of creating new types of data objects with named fields, special print action, etc. (DEFSTRUCT NAME-AND-OPTIONS [ DOC-STRING ] {SLOT-DESCRIPTIONS }+ ) [Macro] Note: Implemented as a special form in CML. DEFSTRUCT act as an interface to the Interlisp record package. Structures defined with it are understood as datatype records by all of Interlisp-D's program analysis tools (eg, Masterscope). Creates a new type of data object. Defines a constructor function which will create an instance of this object and allows setting of slots using keyword args named by the slot names. It defines slot accessor functions (by default named by: structure-name dash slot-name). Defines a new type, named by the structure name, and a predicate to test whether an object is is an instance of this type (by default named by: structure-name dash "P"). Defines a copier function, which will duplicate all the fields of an instance of this type into a new instance (named by default by: structure-name dash "COPIER"). Other options are described below. NAME-AND-OPTIONS is of the form NAME or ( NAME . OPTIONS) NAME must be a symbol. OPTIONS is a list whose elements can be :CONC-NAME PREFIX This is a name that is prefixed to slot names to created the access functions. It defaults to NAME followed by a dash. If NIL is given the slot accessor functions are placed directly under the symbols that name the slots. :CONSTRUCTOR SYMBOL or (:CONSTRUCTOR SYMBOL ARGLIST) If this option isn't specified, or SYMBOL is not given, then the default constructor function is placed under the symbol created by prefixing "MAKE-" onto the structure name. If SYMBOL is given as NIL this structure has no constructor function. If SYMBOL is a SYMBOL then the default constructor function is placed into its function cell (gives a name to the structure's constructor function). :COPIER SYMBOL If this option isn't specified, or SYMBOL is not given, then the default copier function is placed under the symbol created by prefixing "COPY-" onto the structure name. If SYMBOL is given as NIL this structure has no copier function. If SYMBOL is a SYMBOL then the default copier function is placed into its function cell (gives a name to the structure's copier function). :PREDICATE SYMBOL If this option isn't specified, or SYMBOL is not given, then the default predicate function is placed under the symbol created by affixing "-P" onto the structure name. If SYMBOL is given as NIL this structure has no predicate fucntion. If SYMBOL is a SYMBOL then the default predicate function is placed into its function cell (gives a name to the structure's predicate function). :INCLUDE NAME or (:INCLUDE NAME . SLOT-DESCRIPTIONS) Note: CML does not implement this option. This option is not implemented in CML. It will be part of the release of Common Loops. :PRINT-FUNCTION FUNCTION-BODY Should only be specified if :TYPE is not given. FUNCTION-BODY is a form suitable to be passed into FUNCTION (like a lambda). It should be a function of three arguments: STRUCTURE, STREAM, and PRINT-DEPTH. It should print STRUCTURE onto STREAM observing the print control variables (see the I/O chapter) specifically comparing PRINT-DEPTH against *PRINT-LEVEL*. :TYPE TYPE Note: CML does not implement this option. This is the TYPE of the overall structure. If not specified, or if TYPE is not specified it defaults to creating a brand new dataype. If TYPE is given it must be one of VECTOR (VECTOR ELEMENT-TYPE) A vector with element type of either T (if none is given) or the specified type is used to implement the structure. If the structure is :NAMED (the dfault the NAME symbol will be its zero'eth element. The first slot is at index 1. Slots are stored in successive locations. LIST A list is used to implement this type of structure. If the structure is :NAMED then the name symbol is inthe list's CAR, followed by the slots, otherwise the slots begin in the car. Slots are stored inthe CARs of successive cons cells. :NAMED Takes no argument. If it is present in the options list it means that the structure has its name encoded in all instances (either by implicit datatype or explicitly with a symbol at the head of the list or vector). If :type is not specified the structure will be be :NAMED by default (by implicit dataype). This is really only useful with :TYPE to say the symbol should be the first element of the sequence holding the slots. :INITIAL-OFFSET POSITIVE-INTEGER Note: CML does not implement this option. This option may only be specified if :TYPE is as well. If POSITIVE-INTEGER is specified and non-NIL it must be a positive integer. This is the position to begin allocation and references within this structure. It allows a "free" area at the front of structures to hold other information. DOC-STRING is an optional string used to document the purpose of the data structure. SLOT-DESCRIPTIONS is a list of one or more descriptions of the slots this data structure is to have. Each of these is of the form SLOT-NAME or (SLOT-NAME DEFAULT-VALUE &KEY SLOT-OPTIONS) The SLOT-NAME must be a symbol. The DEFAULT-VALUE is put in the slot by the default constructor function whenever a new instance of this structure is made. Note: CML does not implement slot options. The SLOT-OPTIONS are :TYPE TYPESPEC This specifies theat the type of any data placed into this slot must be of the type given by TYPESPEC. :READ-ONLY PRED-VALUE This slot is "read only" and may never be altered by SETF. THE EVALUATOR CML contains no Common Lisp specific evaulation mechanism. The LAMBDATRAN package is used to implement translation of Common Lisp lambdas to an appropriate Interlisp lambda expression. STREAMS *STANDARD-OUTPUT* [Variable] The standard output stream. (WRITE-STRING STRING &OPTIONAL (STREAM *STANDARD-OUTPUT*) &KEY (START 0) (END (LENGTH STRING)) [Function] Writes some or all characters of a string onto a stream. INPUT/OUTPUT While CML contains no Common Lisp specific reader there are a number of handy features implemented with Interlisp facilities. What the READ function understands All of these presume use of the CMLRDTBL. Numbers may be read-in using the standard Common Lisp radix notation: #8r1010 Characters and their associated hash sign typein format are supported: #\NAME NAME can be either a single glyph, or a symbol which names a character. The following named characters are availible in CML PAGE, FORM, FF 12 DEL, RUBOUT 127 NULL 0 ESCAPE, ESC 27 BELL 7 TAB 9 BS 8 NEWLINE 13 TENEXEOL 31 SPACE, SP 32 LINEFEED, LF 10 RETURN, CR 13 INFINITY 8551 RIGHTPAREN 41 BACKSPACE ^H PI GREEK-163 EOL 13 All symbols have a print name and property list. Various character quoting conventions are outlined to allow symbols with "interesting" print names. Arrays Vectors Bit vectors - See the CMLARRAY Package's documentation for a description of these formats output . Structures - have a default type-in format #S(STRUCNAME FIELD1 VALUE1 FIELD2 VALUE2 ...) Controlling the print function *PRINT-LEVEL* [Variable] *PRINT-LENGTH* [Variable] *PRINT-ARRAY* [Variable] Please see the CMLARRAY Package's documentation for a description of these control variables. *PRINT-STRUCTURE* [Variable] If non-NIL, structures defined with DEFSTRUCT will be printed using their print function (the standard #S(...) format or a user defined one). If NIL, the "internal object" representation is used. What the print function produces Characters - are printed as #\NAME Where NAME may be either a symbol or a single glyph. Arrays Vectors Bit vectors - See the CMLARRAY Package's documentation for a description of these formats output . Streams - are printed in a re-readble format using #. to activate a call to the the stream producing function. Structures - Structures - have a default type-in format #S(STRUCNAME FIELD1 VALUE1 FIELD2 VALUE2 ...) Internal objects - # For example # FILE SYSTEM INTERFACE There is no Common Lisp specific file system interface in CML. ERRORS In CML, there is no Common Lisp specific error system. However, there are plans in the Common Lisp community to design a more versatile system than the one outlined in Common Lisp the Language. Specialized error signalling forms and macros (CHECK-TYPE PLACE TYPESPEC &OPTIONAL STRING) [Macro] This macro expands to a form which tests the type of the object at PLACE against TYPESPEC. If PLACE is not of type TYPESPEC then STRING is printed and an error signalled in such a way that the value at PLACE might be modified. When execution continues we return to the top of the CHECK-TYPE form and test they new value once more, etc. When the type test holds True execution continues normally. MISCELLANEOUS The Compiler, package CMLCOMPILE (COMPILE-FILE FILENAME &KEY OUTPUT-FILE SAVE-EXPRS COMPILER-OUTPUT PROCESS-ENTIRE-FILE LAP REDEFINE) [Function] This function compiles FILENAME. Reads expressions from FILENAME, compiles them, and writes the compiled version onto an output file which defaults to the same name (and directory) of FILENAME. It integrates compliation of Common Lisp functions with the Interlisp File Package. Unlike TCOMPL, the compiled versions of expressions on FILENAME are copied to the destination file in the same order they appear on the source file. In addition, it is possible to specify alternative compile-methods for new kinds of forms, by giving them a COMPILE.FILE.EXPRESSION property. Any declarations, macros, constants, etc. encountered during processing of the file are "undone" on completion. COMPILER-OUTPUT - a stream. All compiler warning messages are printed on stream. Defaults to T. (This is the same as COUTFILE.) LAP - if T, intermediate compiler code is printed on the COMPILER-OUTPUT file. Defaults to NIL. REDEFINE - if T, functions will be redefined as they are compiled. Default is NIL. Note that the "redefinition" happens all at once at the end of compilation, rather than as the file is being processed. SAVE-EXPRS - if NIL, when redefining, the old expr definitions will get thrown away. Defaults to T. COMPILED-FILE filename - Normally, the compiled code will get put on a file of the same name (and directory) as the source FILENAME, but with extension set to COMPILE.EXT. If this argument is supplied, its used as the name of the output file instead. Listing? ST is the same as :REDEFINE T. Listing? F is the same as the default. Listing? STF is the same as (REDEFINE: T :SAVE-EXPRS T). adding new compile "methods" COMPILE-FILE looks at the CAR of each expression on the file, and looks for a COMPILE.FILE.EXPRESSION property. If it finds one, it applies the value to arguments (EXPRESSION OUTPUTFILE RDTBL). The default COMPILE.FILE.EXPRESSION is PRINT, i.e., to copy the input file to the output compiled file. DECLARE: (and an attempt to implement EVAL.WHEN) are handled specially; the system comes with a COMPILE-FILE-EXPRESSION for DEFINEQ (to compile the code) and * (to ignore the comments). (this is primarily inspired by desire to handle DEFUNs on files directly for CommonLoops.) incompatibilities There are some incompatibilities with BCOMPL, BRECOMPILE, TCOMPL, RECOMPILE (which will remain): 1) Block compilation is not supported. No plans offhand. No RECOMPILE-FILE (yet, but plans). 2) Files that put their compiler declarations (macros etc) at the end will have to be rearranged. I'm hoping to have a MAKEFILE option do that. Source code pretty printer, package CMLPRETTY A special set of functions for neatly printing Common Lisp packages to a file or a printer. These functions may eventually become a way of print ing files for transport to other systems. (LISTFILES1 FILE PRINT-OPTIONS) [Function] If FILE is a File package file as created by MAKEFILE we call PPLISTFILE with TO-STREAM and TYPE set to NIL, otherwise we SEND.FILE.TO.PRINTER with the specified PRINT-OPTIONS. (PPLISTFILE FILE TO-STREAM TYPE PRINT-OPTIONS) [Function] List a file in "pretty format." FILE is the name of the file to be fprinted. TO-STREAM is where to print it, and defaults to your "default printer." TYPE optionally specifies the type of the printer (such as INTERPRESS). PRINT-OPTIONS are as for the function SEND.FILE.TO.PRINTER. You may define your own formatting for a given form. Forms are named by the symbol that appears at their head. Print format functions should be placed under the PRINT-TO-FILE proerty of that symbol. Formatter functions should accept one argument, a list which is the tail of the form they are to format. They should call NEWPRINTDEF to recurse processing more lists of forms. (NEWPRINTDEF EXPR LEFT FORMFLG TAILFLG FNSLST FILE) [Function] A plug compatible redefinition of the function PRINTDEF for the CMLPRETTY package (see the Interlisp Refernce Manual for its definition). The default print formatter functions are PRINT.* PRINT.DECLARE: PRINT.DEFINEQ PRINT.DEFUN PRINT.FILECREATED PRINT.VAR The following symbols, denoting forms, have their PRINT-TO-FILE property initially set * ACCESSFN ACCESSFNS ARRAYBLOCK ARRAYRECORD ASSOCRECORD ATOMRECORD BLOCKRECORD CACCESSFNS DATATYPE DECLARE: DEFINEQ DEFMACRO DEFSTRUCT DEFUN FILECREATED HASHLINK HASHRECORD PROGN PROPRECORD PUTPROPS RECORD RPAQ RPAQ? RPAQQ SYNONYM TYPERECORD Source text browser, package CMLSHOW This package implements a facility for displaying named objects from Common Lisp files ina window. CMLWINDOW [Variable] Either NIL or an object of type WINDOW. This is where the text of the object is displayed. CMLPATH [Variable] Holds the file name defaults for the directory containing the sources you wish to work on. (MAKECMLINDEX PATTERN) [Function] Creates a new hashfile named hashfile (which is CML.HASH right now) and searches all the files named by the pattern. Searches the file(s) for forms beginning with "(def", puts the following symbol and its start position in the file into the hashfile. (CMLSHOW NAME &OPTIONAL TO) [Function] Pulls the definition under name from the hashfile (which is CML.HASH right now) and displays it. If to is provided it is a stream to print the definition onto instead of the CMLWINDOW Common Lisp executive window, package CMLEXEC This package loads LISTEN and then changes the background "Lisp Listener" to have two subitems, Interlisp and Common Lisp. The executive you get in Common Lisp mode uses the Common Lisp reader (defines TTYINREAD to be CMLREAD) which translates symbols if needed (prefixing "CL:") and uses the CMLRDTBL, which doesn't recognize angle brackets and reads the hashmacro syntax correctly. It is thus possible to type or shift-select DEFUNs from Common Lisp source text directly into it. CMLPROMPT [Variable] The prompt string used inthe Common Lisp executive window, initially "*". (CMLREAD FILE RDTBL) [Function] Common Lisp reader function. WIll translate incoming symbols to the associated Common Lisp specific function names if necccessary. / /$$ / *H,$$ &$H / ,HH ,HH&$$ /H &$$&& &8&8B PAGEHEADING RUNNINGHEAD MODERN MODERN ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) MODERNMODERN  HELVETICA MODERN TERMINAL MODERN MODERN MODERNLOGOMODERN     HRULE.GETFNMODERN   HRULE.GETFNMODERN   HRULE.GETFNMODERN    HRULE.GETFNMODERN   HRULE.GETFNMODERN               f                 <        )  j   N     %           4  l  8   ?          /        :    A   m  N   z  L     g                 I  y    j       7    %   M              v       ]    _    M             Q   t     < $ & ; 9 2 G     u     H       .        =      G     G     R   s     +                 Q    :    J   <           *       Z   !  !          %     L            s     \        8     J o  %       ^ <  > $  "     t         :     {   *                              ~  y  K q   ;      #  7   7       &     /        !     c  ,      O   )  }       +  d 2   z    h     0  8      z     $     0            <         $    I      c     2       b          5    '    l    Y     >    P     s         F   k    |            7 @ 4  5      7 < 2  5       h    c   9   8    M     +     R     T      k    T     ^  =      i     A  Q   g         y    F   E       a T ; e @   3 (  c    '                $  0   7   4  ' (  = 4  C   Q 3   s  = L          f    X       Y .            p  #     a          ,   T   Y J     `  X    J        J       !  "   7  /    0 2 e 1    0 . e 3    O 5     9 / #           + H r S  !     G d     E V -       C ^    /  _          w            C           *  M    %  u       x 9 B <        _  #  M <        0 R $  e              N 1      k  %    ;       s     2 J Q        L      X /       F  !              3 <   :   x   B  d ,     (       T \        @  m     B  6     -    Q   O        D  s        : # ~ ^ M     d    4 X   ^  !    [  = D     ! '   S       F  ^      A   (    n    9 &   C  '         ; ?  F     p          D       $     !    *          9  W      e  ~      * '    0 (    0 %    & 2    & .                        [              M    &    &                    ! 4    5  1       &    '                 p           #         e   G     -      9  g   A  2          e    ) 2    ) 2    ( :    @ :               M     ^     <             1        p     a l    o     . :   %     +     ,    %     &       :  < %         & #   %             (              r      ;     8     -     /     .           &      E                   0  *  ,               ]      , E    , 2    , 2  )  G X  )  I X       i      n        Q l  F    ;                 a   $          |    :         o    n   i                 !    _ }      #  A      #  <     #  ?     ,  X     1 0   +  D C   1        +  ;    I  r         k  +        ]     ;           j  9   ~  #  *  F   G   y    r  ,      L ^    !      +  r  p  9               ?      .     C     C     !              x W  7   p   `   d      +   [    a  ]   .       H  B        ! * @ E  /            *  M  W   %  d    \    [          .      J      hf z