Implementation Notes for CLISP ============================== Last modified: 30 May 1996. This implementation is mostly compatible to the standard reference Guy L. Steele Jr.: Common Lisp - The Language (1st ed.). Digital Press 1984, 465 pages. ("CLtL1" for short) and to the older parts of Guy L. Steele Jr.: Common Lisp - The Language (2nd ed.). Digital Press 1990, 1032 pages. ("CLtL2" for short) These notes document the differences of the CLISP implementation of Common Lisp to the standard CLtL1, and some implementation details. The differences between CLtL1 and CLtL2 are made up of X3J13 votes. CLISP's position with respect to these votes is listed in cltl2.txt. CHAPTER 1: Introduction ----------------------- No notes. CHAPTER 2: Data Types --------------------- All the data types are implemented: numbers, characters, symbols, lists, arrays, hash tables, readtables, packages, pathnames, streams, random states, structures and functions. 2.1.3. ------ There are four floating point types: short-float, single-float, double-float and long-float: sign mantissa exponent short-float 1 bit 16+1 bits 8 bits single-float 1 bit 23+1 bits 8 bits CLISP uses IEEE format double-float 1 bit 52+1 bits 11 bits CLISP uses IEEE format long-float 1 bit >=64 bits 32 bits The single and double float formats are those of the IEEE standard (1981), except that CLISP does not support features like +0, -0, +inf, -inf, gradual underflow, NaN, etc. (Common Lisp does not make use of these features.) Long floats have variable mantissa length, which is a multiple of 16 (or 32, depending on the word size of the processor). The default length used when long floats are read is given by the place (LONG-FLOAT-DIGITS). It can be set by (SETF (LONG-FLOAT-DIGITS) nnn), where nnn is a positive integer. 2.1.4. ------ Complex numbers can have a real part and an imaginary part of different types. For example, (SQRT -9.0) evaluates to the number #C(0 3.0), which has a real part of exactly 0, not only 0.0 (which would mean "approximately 0"). The type specifier for this is (COMPLEX INTEGER SINGLE-FLOAT), and (COMPLEX type-of-real-part type-of-imaginary-part) in general. The type specifier (COMPLEX type) is equivalent to (COMPLEX type type). 2.2.1. ------ The characters are ordered according to the ASCII encoding. More precisely, CLISP uses the ISO Latin-1 (ISO 8859-1) character set: $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F $00 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** $10 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** $20 ! " # $ % & ' ( ) * + , - . / $30 0 1 2 3 4 5 6 7 8 9 : ; < = > ? $40 @ A B C D E F G H I J K L M N O $50 P Q R S T U V W X Y Z [ \ ] ^ _ $60 ` a b c d e f g h i j k l m n o $70 p q r s t u v w x y z { | } ~ $80 $90 $A0   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ $B0 ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ $C0 À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï $D0 Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß $E0 à á â ã ä å æ ç è é ê ë ì í î ï $F0 ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ Here ** are control characters, not graphic characters. (The characters left blank here cannot be represented in this character set). The following are standard characters: #\Space $20 #\Newline $0A The following are semi-standard characters: #\Backspace $08 #\Tab $09 #\Linefeed $0A #\Page $0C #\Return $0D #\Rubout $7F 2.2.2. ------ #\Newline is the delimiter between lines. When reading from a file, CR/LF is converted to #\Newline, and CR not followed by LF is read as #\Return. 2.2.3. ------ There are the following additional characters with names: #\Null $00 #\Bell $07 #\Escape $1B 2.2.4. ------ The code of a character is >=0, <256. CHAR-CODE-LIMIT = 256. There are fonts 0 to 15, and CHAR-FONT-LIMIT = 16. But the system itself uses only font 0. The following bits attributes are implemented: :CONTROL, :META, :SUPER, :HYPER. Therefore CHAR-BITS-LIMIT = 16. The system itself uses these bits only to mention special keys and Control/Alternate/Shift key status on return from (READ-CHAR *KEYBOARD-INPUT*). 2.5. ---- The maximum rank (number of dimensions) of an array is 65535 on 16-bit processors, 4294967295 on 32-bit processors. 2.10. ----- The CLtL2 types BROADCAST-STREAM, CONCATENATED-STREAM, ECHO-STREAM, SYNONYM-STREAM, STRING-STREAM, FILE-STREAM, TWO-WAY-STREAM are implemented. 2.13. ----- All the functions built by FUNCTION, COMPILE and the like are atoms. There are built-in functions written in C, compiled functions (both of type COMPILED-FUNCTION) and interpreted functions (of type FUNCTION). The possible function names (CLtL1 p. 59) are symbols and lambda expressions. 2.14. ----- This is the list of objects whose external representation can not be meaningfully read in: * all structures lacking a keyword constructor. * all arrays except strings, if *PRINT-ARRAY* = NIL. * # built-in function written in C * # other function written in C * # special form handler * # compiled function, if *PRINT-CLOSURE* = NIL * # interpreted function * # pointer to a stack frame * # frame pointer which has become invalid on exit from the corresponding BLOCK or TAGBODY * #<...-STREAM ...> stream * # package * # hash table, if *PRINT-ARRAY* = NIL * # readtable * # symbol-macro handler * # foreign pointer * # "value" of a symbol without value, "value" of an unsupplied optional or keyword argument * # environment marker for variables declared SPECIAL * # internal READ result for "." * # internal READ result, when the end of file is reached * # intermediate READ result for #n# * #
machine address, should not occur * # should not occur 2.15. ----- The type NUMBER is the disjoint union of the types REAL and COMPLEX. (CLtL wording: "exhaustive partition") The type REAL is the disjoint union of the types RATIONAL and FLOAT. The type RATIONAL is the disjoint union of the types INTEGER and RATIO. The type INTEGER is the disjoint union of the types FIXNUM and BIGNUM. The type FLOAT is the disjoint union of the types SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT and LONG-FLOAT. CHAPTER 3: Scope and Extent --------------------------- is implemented as described. CHAPTER 4: Type Specifiers -------------------------- 4.4. ---- The CLtL2 type specifier (EQL object) denotes the singleton set {object}. 4.5. ---- The general form of the COMPLEX type specifier is (COMPLEX type-of-real-part type-of-imaginary-part). The type specifier (COMPLEX type) is equivalent to (COMPLEX type type). 4.6. ---- The CLtL2 type specifier (REAL low high) denotes the real numbers between low and high. 4.7. ---- DEFTYPE lambda lists are subject to destructuring (nested lambda lists are allowed, as in DEFMACRO) and may contain a &WHOLE marker, but no &ENVIRONMENT marker. 4.9. ---- The possible results of TYPE-OF are: CONS SYMBOL NULL FIXNUM BIGNUM RATIO SHORT-FLOAT SINGLE-FLOAT DOUBLE-FLOAT LONG-FLOAT COMPLEX CHARACTER (ARRAY element-type dimensions), (SIMPLE-ARRAY element-type dimensions) (VECTOR T size), (SIMPLE-VECTOR size) (STRING size), (SIMPLE-STRING size) (BIT-VECTOR size), (SIMPLE-BIT-VECTOR size) FUNCTION COMPILED-FUNCTION STREAM FILE-STREAM SYNONYM-STREAM BROADCAST-STREAM CONCATENATED-STREAM TWO-WAY-STREAM ECHO-STREAM STRING-STREAM PACKAGE HASH-TABLE READTABLE PATHNAME LOGICAL-PATHNAME RANDOM-STATE BYTE LOAD-TIME-EVAL SYMBOL-MACRO FOREIGN-VARIABLE FOREIGN-FUNCTION READ-LABEL FRAME-POINTER SYSTEM-INTERNAL ADDRESS (should not occur) any other symbol (structure types or CLOS classes) a class (CLOS classes without proper name) CHAPTER 5: Program Structure ---------------------------- 5.1.3. ------ In addition to the 24 special forms listed on p. 57 (CLtL2: p. 73), the CLtL2 special forms LOCALLY, SYMBOL-MACROLET, LOAD-TIME-VALUE are implemented, and the macros PSETQ, PROG1, PROG2, WHEN, UNLESS, COND, MULTIPLE-VALUE-LIST, MULTIPLE-VALUE-BIND, MULTIPLE-VALUE-SETQ, AND, OR are implemented as special forms. Constants may not be bound dynamically or lexically. 5.2.2. ------ LAMBDA-LIST-KEYWORDS = (&OPTIONAL &REST &KEY &ALLOW-OTHER-KEYS &AUX &BODY &WHOLE &ENVIRONMENT) LAMBDA-PARAMETERS-LIMIT is 65536 on 16-bit processors, 4294967296 on 32-bit processors. 5.3. ---- DEFUN and DEFMACRO are allowed in non-toplevel positions. As an example, consider the old (CLtL1) definition of GENSYM: (let ((gensym-prefix "G") (gensym-count 1)) (defun gensym (&optional (x nil s)) (when s (cond ((stringp x) (setq gensym-prefix x)) ((integerp x) (if (minusp x) (error "~S: index ~S is negative" 'gensym x) (setq gensym-count x) )) (t (error "~S: argument ~S of wrong type" 'gensym x)) ) ) (prog1 (make-symbol (concatenate 'string gensym-prefix (write-to-string gensym-count :base 10 :radix nil) ) ) (incf gensym-count) ) ) 5.3.2. ------ (PROCLAIM '(SPECIAL var)) declarations may not be undone. The same holds for DEFVAR, DEFPARAMETER and DEFCONSTANT declarations. It is an error if a DEFCONSTANT variable is bound at the moment the DEFCONSTANT is executed, but DEFCONSTANT does not check this. Constants may not be bound dynamically or lexically. 5.3.3. ------ EVAL-WHEN also accepts the situations (NOT EVAL) and (NOT COMPILE). CHAPTER 6: Predicates --------------------- 6.2.2. ------ REALP returns T is its argument is a real number, NIL otherwise. COMPILED-FUNCTION-P returns T on built-in functions written in C, compiled functions and special form handlers. Therefore COMPILED-FUNCTION is not a subtype of FUNCTION. 6.3. ---- EQ compares characters and fixnums as EQL does. No unnecessary copies are made of characters and numbers. Nevertheless, one should use EQL. (let ((x y)) (eq x x)) always returns T, regardless of y. 6.4. ---- AND and OR are implemented as special forms and, as such, rather efficient. CHAPTER 7: Control Structure ---------------------------- 7.1.1. ------ (FUNCTION symbol) returns the local function definition established by FLET or LABELS, if it exists, otherwise the global function definition. The CLtL2 place (FDEFINITION function-name) is implemented. (SPECIAL-FORM-P symbol) returns NIL or T. If it returns T, then (SYMBOL-FUNCTION symbol) returns the (useless) special form handler. 7.1.2. ------ PSETQ is implemented as a special form and, as such, rather efficient. 7.2. ---- (SETF (SYMBOL-FUNCTION symbol) object) requires object to be either a function, a SYMBOL-FUNCTION return value or a lambda expression. A lambda expression is thereby immediately converted to a function. SETF also accepts places yielding multiple values. Additional places: * FUNCALL: (SETF (FUNCALL #'symbol ...) object) and (SETF (FUNCALL 'symbol ...) object) are equivalent to (SETF (symbol ...) object). * GET-DISPATCH-MACRO-CHARACTER: (SETF (GET-DISPATCH-MACRO-CHARACTER ...) ...) performs a SET-DISPATCH-MACRO-CHARACTER. * LONG-FLOAT-DIGITS: (SETF (LONG-FLOAT-DIGITS) digits) sets the default mantissa length of long floats to digits bits. * VALUES: (SETF (VALUES place1 ... placek) form) is approximately equivalent to (MULTIPLE-VALUE-BIND (dummy1 ... dummyk) form (SETF place1 dummy1 ... placek dummyk) (VALUES dummy1 ... dummyk) ) Example: (SETF (VALUES A B) (VALUES B A)) interchanges the values of A and B. * VALUES-LIST: (SETF (VALUES-LIST list) form) is equivalent to (VALUES-LIST (SETF list (MULTIPLE-VALUE-LIST form))) &KEY markers in DEFSETF lambda lists are supported, but the corresponding keywords must appear literally in the program text. (GET-SETF-METHOD form &optional env) and (GET-SETF-METHOD-MULTIPLE-VALUE form &optional env) receives as optional argument the environment necessary for macro expansions. In DEFINE-SETF-METHOD lambda lists, one can specify &ENVIRONMENT and a variable, which will be bound to the environment. This environment should be passed to all calls of GET-SETF-METHOD and GET-SETF-METHOD-MULTIPLE-VALUE. If this is done, even local macros will be interpreted as places correctly. 7.3. ---- CALL-ARGUMENTS-LIMIT is 65536 on 16-bit processors, 4294967296 on 32-bit processors. 7.4. ---- PROG1 and PROG2 are implemented as special forms and, as such, rather efficient. 7.5. ---- The CLtL2 special form SYMBOL-MACROLET is implemented. The macro DEFINE-SYMBOL-MACRO establishes symbol macros with global scope (as opposed to symbol macros defined with SYMBOL-MACROLET, which have local scope): (DEFINE-SYMBOL-MACRO symbol expansion). The function SYMBOL-MACRO-EXPAND tests for a symbol macro: If symbol is defined as symbol macro, (SYMBOL-MACRO-EXPAND symbol) returns two values, T and the expansion, else it returns NIL. Calling BOUNDP on a symbol defined as symbol macro returns T. Calling SYMBOL-VALUE on a symbol defined as symbol macro returns the value of the expansion. Calling SET on a symbol defined as symbol macro calls SETF on the expansion. Calling MAKUNBOUND on a symbol defined as symbol macro removes the symbol macro definition. If using the optional package MACROS3: The macros LETF and LETF* are like LET and LET*, resp., except that they can bind places, even places with multiple values. Example: (LETF (((VALUES A B) form)) ...) is equivalent to (MULTIPLE-VALUE-BIND (A B) form ...) (LETF (((FIRST L) 7)) ...) is approximately equivalent to (LET* ((#:G1 L) (#:G2 (FIRST #:G1))) (UNWIND-PROTECT (PROGN (SETF (FIRST #:G1) 7) ...) (SETF (FIRST #:G1) #:G2) ) ) 7.6. ---- WHEN, UNLESS, COND are implemented as special forms and, as such, rather efficient. 7.8.4. ------ The function MAPCAP is like MAPCAN, except that it concatenates the resulting lists with APPEND instead of NCONC: (MAPCAP fun x1 ... xn) == (apply #'append (mapcar fun x1 ... xn)) (Actually a bit more efficient that this would be.) The function MAPLAP is like MAPCON, except that it concatenates the resulting lists with APPEND instead of NCONC: (MAPLAP fun x1 ... xn) = (apply #'append (maplist fun x1 ... xn)) (Actually a bit more efficient that this would be.) 7.9.1. ------ MULTIPLE-VALUES-LIMIT = 128 MULTIPLE-VALUE-LIST, MULTIPLE-VALUE-BIND, MULTIPLE-VALUE-SETQ are implemented as special forms and, as such, rather efficient. The macro NTH-VALUE: (NTH-VALUE n form) returns the (n+1)st value (n>=0) of form. CHAPTER 8: Macros ----------------- 8.3. ---- The CLtL2 macro DESTRUCTURING-BIND is implemented. It does not perform full error checking. CHAPTER 9: Declarations ----------------------- 9.1. ---- The CLtL2 macro DECLAIM is implemented. 9.2. ---- The declarations (TYPE type var ...), (FTYPE type fun ...), (FUNCTION name arglist result-type), (OPTIMIZE (quality value) ...) are ignored by the interpreter and the compiler. The CLtL2 declaration (OPTIMIZE (DEBUG ...)) is legal. Additional declarations: * The dpANS declaration (IGNORABLE var ...) affects the variable binding for the variable var. The compiler will not warn about the variable, regardless whether it is used or not. * The declaration (COMPILE) has the effect that the current form is compiled prior to execution. Examples: (LOCALLY (DECLARE (COMPILE)) form) executes a compiled version of form. (let ((x 0)) (flet ((inc () (declare (compile)) (incf x)) (dec () (decf x))) (values #'inc #'dec) ) ) returns two functions. The first is compiled and increments x, the second is interpreted (slower) and decrements the same x. 9.3. ---- The type assertion (THE value-type form) enforces a type check in interpreted code. No type check is done in compiled code. If using the optional package MACROS3: (ETHE value-type form) enforces a type check in both interpreted and compiled code. CHAPTER 10: Symbols ------------------- No notes. CHAPTER 11: Packages -------------------- 11.6. ----- The package SYSTEM has the nicknames "SYS" and, additionally, "COMPILER". The CLtL2 packages * COMMON-LISP with nickname "CL" and * COMMON-LISP-USER with nickname "CL-USER" are implemented. The package COMMON-LISP exports only those symbols from the proposed ANSI CL draft that are actually implemented. 11.7. ----- The CLtL2 macro DEFPACKAGE is implemented. 11.8. ----- The function REQUIRE receives as optional argument either a pathname or a list of pathnames: files to be loaded if the required module is not already in memory. CHAPTER 12: Numbers ------------------- The single and double float formats are those of the IEEE standard (1981), except that CLISP does not support features like +0, -0, +inf, -inf, gradual underflow, NaN, etc. (Common Lisp does not make use of these features.) The default number of mantissa bits in long floats is given by the place (LONG-FLOAT-DIGITS). Example: (SETF (LONG-FLOAT-DIGITS) 3322) sets the default precision of long floats to 1000 decimal digits. 12.1. ----- Complex numbers can have a real part and an imaginary part of different types. If the imaginary part is EQL to 0, the number is automatically converted to a real number. (Cf. CLtL1 p. 195) This has the advantage that (let ((x (sqrt -9.0))) (* x x)) - instead of evaluting to #C(-9.0 0.0), with x = #C(0.0 3.0) - evaluates to #C(-9.0 0) = -9.0, with x = #C(0 3.0). Coercions on operations involving different types: The result of an arithmetic operation whose arguments are of different float types is rounded to the float format of the shortest (least precise) of the arguments. rational -> long float -> double float -> single float -> short float (in contrast to CLtL1 p. 195!) Rationale: See it mathematically. Add intervals: {1.0 +/- 1e-8} + {1.0 +/- 1e-16} = {2.0 +/- 1e-8} So, if we add 1.0s0 and 1.0d0, we should get 2.0s0. Shortly: Do not suggest accuracy of a result by giving it a precision that is greater than its accuracy. Example: (- (+ 1.7 pi) pi) should not return 1.700000726342836417234L0, it should return 1.7f0 (or 1.700001f0 if there were rounding errors). Experience: If in a computation using thousands of short floats, a long float (like pi) happens to be used, the long precision should not propagate throughout all the intermediate values. Otherwise, the long result would look precise, but its accuracy is only that of a short float; furthermore much computation time would be lost by calculating with long floats when only short floats would be needed. When rational numbers are to be converted to floats (due to FLOAT, COERCE, SQRT or a transcendental function), the result type is given by the variable *DEFAULT-FLOAT-FORMAT*. The macro WITHOUT-FLOATING-POINT-UNDERFLOW: (without-floating-point-underflow {form}*) executes the forms, with errors of type FLOATING-POINT-UNDERFLOW inhibited. Floating point operations will silently return zero instead of signalling an error of type FLOATING-POINT-UNDERFLOW. 12.4. ----- (LCM), called without arguments, returns 1, which is the neutral element of composition with LCM. (! n) returns the factorial of n, n a nonnegative integer. (EXQUO x y) returns the quotient x/y of two integers x,y, and checks that it is an integer. (This is more efficient than /.) (XGCD x1 ... xn) returns the values g, c1, ..., cn, where g is the greatest common divisor of the integers x1,...,xn, and c1,...,cn are integer coefficients such that g = (GCD x1 ... xn) = (+ (* c1 x1) ... (* cn xn)) 12.5.1. ------- (EXPT base exponent) is not very precise if exponent has large absolute value. (LOG number base) signals an error if base = 1. 12.5.2. ------- The value of PI is a long float with the precision given by (LONG-FLOAT-DIGITS). When this precision is changed, the value of PI is automatically recomputed. Therefore PI is a variable, not a constant. 12.6. ----- FLOAT-RADIX always returns 2. (FLOAT-DIGITS number digits) coerces `number' (a real number) to a floating point number with at least `digits' mantissa digits. The following holds: (>= (FLOAT-DIGITS (FLOAT-DIGITS number digits)) digits) 12.7. ----- BOOLE-CLR = 0 BOOLE-SET = 15 BOOLE-1 = 10 BOOLE-2 = 12 BOOLE-C1 = 5 BOOLE-C2 = 3 BOOLE-AND = 8 BOOLE-IOR = 14 BOOLE-XOR = 6 BOOLE-EQV = 9 BOOLE-NAND = 7 BOOLE-NOR = 1 BOOLE-ANDC1 = 4 BOOLE-ANDC2 = 2 BOOLE-ORC1 = 13 BOOLE-ORC2 = 11 12.10. ------ MOST-POSITIVE-FIXNUM = 2^24-1 = 16777215 MOST-NEGATIVE-FIXNUM = -2^24 = -16777216 Together with PI, the other long float constants MOST-POSITIVE-LONG-FLOAT, LEAST-POSITIVE-LONG-FLOAT, LEAST-NEGATIVE-LONG-FLOAT, MOST-NEGATIVE-LONG-FLOAT, LONG-FLOAT-EPSILON, LONG-FLOAT-NEGATIVE-EPSILON are recomputed whenever (LONG-FLOAT-DIGITS) is changed. They are variables, not constants. CHAPTER 13: Characters ---------------------- See first above: 2.2. 13.1. ----- CHAR-CODE-LIMIT = 256 CHAR-FONT-LIMIT = 16 CHAR-BITS-LIMIT = 16 13.2. ----- String-chars are those characters with font = 0 and bits = 0. The graphic characters have been described above. The standard characters are #\Newline and those graphic characters with a code between 32 and 126 (inclusive). The alphabetic characters are these string-chars: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz and the international alphabetic characters from the character set: ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜßáíóúñѪºãõØøÀÃÕ etc. The functions CHAR-EQUAL, CHAR-NOT-EQUAL, CHAR-LESSP, CHAR-GREATERP, CHAR-NOT-GREATERP, CHAR-NOT-LESSP ignore bits and font attributes of their arguments. 13.4. ----- The string chars that are not graphic chars and the space character have names: (code-char #x00) = #\Null (code-char #x01) = #\Code1 (code-char #x02) = #\Code2 (code-char #x03) = #\Code3 (code-char #x04) = #\Code4 (code-char #x05) = #\Code5 (code-char #x06) = #\Code6 (code-char #x07) = #\Bell = #\Bel (code-char #x08) = #\Backspace = #\Bs (code-char #x09) = #\Tab = #\Ht (code-char #x0A) = #\Newline = #\Linefeed = #\Lf (code-char #x0B) = #\Vt (code-char #x0C) = #\Page = #\Ff (code-char #x0D) = #\Return = #\Cr (code-char #x0E) = #\So (code-char #x0F) = #\Si (code-char #x10) = #\Code16 (code-char #x11) = #\Code17 (code-char #x12) = #\Code18 (code-char #x13) = #\Code19 (code-char #x14) = #\Code20 (code-char #x15) = #\Code21 (code-char #x16) = #\Code22 (code-char #x17) = #\Code23 (code-char #x18) = #\Code24 (code-char #x19) = #\Code25 (code-char #x1A) = #\Code26 (code-char #x1B) = #\Escape = #\Esc (code-char #x1C) = #\Code28 (code-char #x1D) = #\Code29 (code-char #x1E) = #\Code30 (code-char #x1F) = #\Code31 (code-char #x20) = #\Space (code-char #x7F) = #\Rubout (code-char #x9B) = #\Csi 13.5. ----- CHAR-CONTROL-BIT = 1 CHAR-META-BIT = 2 CHAR-SUPER-BIT = 4 CHAR-HYPER-BIT = 8 CHAPTER 14: Sequences --------------------- The CLtL2 function COMPLEMENT is implemented. 14.1. ----- The result of NREVERSE is always EQ to the argument. NREVERSE on a vector swaps pairs of elements. NREVERSE on a list swaps the first and the last element and reverses the list chaining between them. 14.2. ----- For iteration through a sequence, a macro DOSEQ, analogous to DOLIST, may be used instead of MAP : (doseq (var seqform [resultform]) {declaration}* {tag|statement}* ) The CLtL2 function MAP-INTO is implemented. 14.3. ----- REMOVE, REMOVE-IF, REMOVE-IF-NOT, REMOVE-DUPLICATES return their argument unchanged, if no element has to be removed. DELETE, DELETE-IF, DELETE-IF-NOT, DELETE-DUPLICATES destructively modify their argument: If the argument is a list, the CDR parts are modified. If the argument is a vector with fill pointer, the fill pointer is lowered and the remaining elements are compacted below the new fill pointer. 14.5. ----- SORT and STABLE-SORT have two additional keywords :START and :END : (SORT sequence predicate &key :key :start :end) (STABLE-SORT sequence predicate &key :key :start :end) SORT and STABLE-SORT are identical. They implement the mergesort algorithm. CHAPTER 15: Lists ----------------- 15.4. ----- SUBLIS and NSUBLIS apply the :KEY argument to the nodes of the cons tree and not to the keys of the alist. CHAPTER 16: Hash Tables ----------------------- 16.1. ----- MAKE-HASH-TABLE has an additional keyword :INITIAL-CONTENTS : (MAKE-HASH-TABLE &key :test :initial-contents :size :rehash-size :rehash-threshold) The :INITIAL-CONTENTS argument is an alist that is used to initialize the new hash table. The :REHASH-THRESHOLD argument is ignored. For iteration through a hash table, a macro DOHASH, analogous to DOLIST, can be used instead of MAPHASH : (dohash (key-var value-var hash-table-form [resultform]) {declaration}* {tag|statement}* ) CHAPTER 17: Arrays ------------------ 17.1. ----- MAKE-ARRAY can return specialized arrays for the element types (UNSIGNED-BYTE 2), (UNSIGNED-BYTE 4), (UNSIGNED-BYTE 8), (UNSIGNED-BYTE 16), (UNSIGNED-BYTE 32) and of course BIT and STRING-CHAR. ARRAY-RANK-LIMIT is 65536 on 16-bit processors, 4294967296 on 32-bit processors. ARRAY-DIMENSION-LIMIT = 2^24 = 16777216 ARRAY-TOTAL-SIZE-LIMIT = 2^24 = 16777216 17.6. ----- An array to which another array is displaced should not be shrunk (using ADJUST-ARRAY) in such a way that the other array points into void space. This is not checked at the time ADJUST-ARRAY is called! CHAPTER 18: Strings ------------------- 18.2. ----- String comparison is based on the function CHAR<=. Therefore diphtongs do not obey the usual national rules. Example: "o" < "oe" < "z" < "ö". CHAPTER 19: Structures ---------------------- 19.5. ----- The :PRINT-FUNCTION option should contain a lambda expression (lambda (structure stream depth) (declare (ignore depth)) ...) This lambda expression names a function whose task is to output the external representation of structure onto the stream. This may be done by outputting text onto the stream using WRITE-CHAR, WRITE-STRING, WRITE, PRIN1, PRINC, PRINT, PPRINT, FORMAT and the like. The following rules must be obeyed: * The value of *PRINT-ESCAPE* must be respected. * The value of *PRINT-PRETTY* should not and cannot be respected, since the pretty-print mechanism is not accessible from outside. * The value of *PRINT-CIRCLE* need not to be respected. This is managed by the system. (But the print-circle mechanism handles only those objects that are (direct or indirect) components of structure.) * The value of *PRINT-LEVEL* is respected by WRITE, PRIN1, PRINC, PRINT, PPRINT, FORMAT ~A, FORMAT ~S, FORMAT ~W and FORMAT ~D,~B,~O,~X,~R,~F,~E,~G,~$ with not-numerical arguments. Therefore the print-level mechanism works automatically if only these functions are used for outputting objects and if they are not called on objects with nesting level > 1. (The print-level mechanism does not recognize how many parentheses you have output. It only counts how many times it was called recursively.) * The value of *PRINT-LENGTH* must be respected, especially if you are outputting an arbitrary number of components. * The value of *PRINT-READABLY* must be respected. Remember that the values of *PRINT-ESCAPE*, *PRINT-LEVEL*, *PRINT-LENGTH* don't matter if *PRINT-READABLY* is true. The value of *PRINT-READABLY* is respected by PRINT-UNREADABLE-OBJECT, WRITE, PRIN1, PRINC, PRINT, PPRINT, FORMAT ~A, FORMAT ~S, FORMAT ~W and FORMAT ~D,~B,~O,~X,~R,~F,~E,~G,~$ with not-numerical arguments. Therefore *PRINT-READABLY* will be respected automatically if only these functions are used for outputting objects. * You need not bother about the values of *PRINT-BASE*, *PRINT-RADIX*, *PRINT-CASE*, *PRINT-GENSYM*, *PRINT-ARRAY*, *PRINT-CLOSURE*, *PRINT-RPARS*, *PRINT-INDENT-LISTS*. The :INHERIT option is exactly like :INCLUDE except that it doesn't create new accessors for the inherited slots. Use this option to avoid the problems that occur when using the same :CONC-NAME for the new and the inherited structure. CHAPTER 20: The Evaluator ------------------------- As in Scheme, the Macro (THE-ENVIRONMENT) returns the current lexical environment. This works only in interpreted code and is not compilable! (EVAL-ENV form [env]) evaluates a form in a given lexical environment, just if the form had been part of the program text that environment came from. CHAPTER 21: Streams ------------------- 21.1. ----- *TERMINAL-IO* is not the only stream that communicates directly with the user: During execution of the body of a (WITH-KEYBOARD . body) form, *KEYBOARD-INPUT* is the stream that reads the keystrokes from the keyboard. It returns every keystroke in detail, as character with the following bits: HYPER if a non-standard key. These are: function keys, cursor keypad. CHAR-CODE the Ascii code for standard keys, for non-standard keys: F1 -> #\F1, ..., F9 -> #\F9, F10 -> #\F10, Help -> #\Help, Arrow keys -> #\Up, #\Down, #\Left, #\Right. SUPER if pressed together with Shift key(s) and if the keystroke would have been an other without Shift. CONTROL if pressed together with the Control key. This keyboard input is not echoed on the screen. During execution of a (WITH-KEYBOARD . body) form, no input from *TERMINAL-IO* or any synonymous stream should be requested. 21.2. ----- The macro WITH-OUTPUT-TO-PRINTER (with-output-to-printer (var) {declaration}* {form}*) binds the variable var to an output stream that sends its output to the printer. Generic streams are user programmable streams. The programmer interface: (MAKE-GENERIC-STREAM controller) returns a generic stream. (GENERIC-STREAM-CONTROLLER stream) returns a private object to which generic stream methods dispatch. The typical usage is to retrieve the object originally provided by the user in MAKE-GENERIC-STREAM. (GENERIC-STREAM-P stream) determines whether a stream is a generic stream, returning T if it is, NIL otherwise. In order to specify the behaviour of a generic stream, the user must define CLOS methods on the following CLOS generic functions. The function GENERIC-STREAM-XYZ corresponds to the Common Lisp function XYZ. They all take a controller and some number of arguments. (GENERIC-STREAM-READ-CHAR controller) (GENERIC-STREAM-READ-BYTE controller) These generic functions should return NIL at end of file. Takes one argument, the controller object. (GENERIC-STREAM-LISTEN controller) Returns -1 for EOF, 0 for character pending, and 1 for none. Takes one argument, the controller object. (GENERIC-STREAM-WRITE-CHAR controller ch) First argument is the controller object. Second argument is the character to be written. (GENERIC-STREAM-WRITE-BYTE controller by) First argument is the controller object. Second argument is the integer to be written. (GENERIC-STREAM-WRITE-STRING controller string start len) Called with argument list (controller string start len), this function shall write (subseq (the string string) start (+ start len)) First argument is the controller object. (GENERIC-STREAM-CLEAR-INPUT controller) (GENERIC-STREAM-CLEAR-OUTPUT controller) (GENERIC-STREAM-FINISH-OUTPUT controller) (GENERIC-STREAM-FORCE-OUTPUT controller) (GENERIC-STREAM-CLOSE controller) Takes one argument, the controller object. 21.3. ----- The CLtL2 function OPEN-STREAM-P is implemented. CLOSE ignores its :ABORT argument. The CLtL2 functions BROADCAST-STREAM-STREAMS, CONCATENATED-STREAM-STREAMS, ECHO-STREAM-INPUT-STREAM, ECHO-STREAM-OUTPUT-STREAM, SYNONYM-STREAM-SYMBOL, TWO-WAY-STREAM-INPUT-STREAM, TWO-WAY-STREAM-OUTPUT-STREAM are implemented. CHAPTER 22: Input/Output ------------------------ 22.1.2. ------- A "reserved token", i.e. a token that has potential number syntax but cannot be interpreted as a number, is interpreted as symbol when being read. (CLtL1 p. 341) When a token with package markers is read, then (CLtL1 p. 343/344) no checking is done whether the package part and the symbol-name part do not have number syntax. (What's the purpose of this check?) So we consider tokens like USER:: or :1 or LISP::4711 or 21:3 as symbols. 22.1.3. ------- The backquote read macro also works when nested. Example: (eval ``(,#'(lambda () ',a) ,#'(lambda () ',b))) = (eval `(list #'(lambda () ',a) #'(lambda () ',b))) = (eval (list 'list (list 'function (list 'lambda nil (list 'quote a))) (list 'function (list 'lambda nil (list 'quote b))) ) ) Multiple backquote combinations like ,,@ or ,@,@ are not implemented. Their use would be confusing anyway. 22.1.4. ------- #\ allows inputting characters of arbitrary code: #\Code231 yields the character (code-char 231.). Additional read dispatch macros: * #Y is used to read compiled functions. * #" is used to read pathnames: #"test.lsp" is the value of (pathname "test.lsp") 22.1.5. ------- Is it impossible to get the read macro function of a dispatch macro character like #\# using GET-MACRO-CHARACTER. The CLtL2 place READTABLE-CASE is implemented. The possible values of (READTABLE-CASE readtable) are :UPCASE, :DOWNCASE and :PRESERVE. 22.1.6. ------- In absence of SYS::WRITE-FLOAT, floating point numbers are output in radix 2. If *PRINT-READABLY* is true, *READ-DEFAULT-FLOAT-FORMAT* has no influence on the way floating point numbers are printed. Pathnames are written according to the syntax #"namestring" if *PRINT-ESCAPE* /= NIL. If *PRINT-ESCAPE* = NIL, only the namestring is printed. *PRINT-CASE* controls the output not only of symbols, but also of characters and some #<...> objects. *PRINT-PRETTY* is initially = NIL but set to T in config.lsp. This makes unbuffered screen output much faster. *PRINT-ARRAY* is initially = T. An additional variable *PRINT-CLOSURE* controls whether compiled and interpreted functions (closures) are output in detailed form. If *PRINT-CLOSURE* /= NIL, compiled closures are output in #Y syntax the reader understands. *PRINT-CLOSURE* is initially = NIL. An additional variable *PRINT-RPARS* controls the output of right (closing) parentheses. If *PRINT-RPARS* /= NIL, closing parentheses which don't fit onto the same line as the the corresponding opening parenthesis are output just below their corresponding opening parenthesis, in the same column. *PRINT-RPARS* is initially = T. An additional variable *PRINT-INDENT-LISTS* controls the indentation of lists that span more than one line. It specifies by how many characters items within the list will be indented relative to the beginning of the list. *PRINT-INDENT-LISTS* is initially = 2. The CLtL2 macro WITH-STANDARD-IO-SYNTAX is implemented. 22.2.1. ------- The function READ-CHAR-SEQUENCE performs multiple READ-CHAR operations: (READ-CHAR-SEQUENCE sequence stream [:start] [:end]) fills the subsequence of sequence specified by :start and :end with characters consecutively read from stream. It returns the index of the first element of sequence that was not updated (= end or < end if the stream reached its end). This function is especially efficient if sequence is a string and stream is a file stream with element type STRING-CHAR, a pipe stream or a string input stream. 22.2.2. ------- The function READ-BYTE-SEQUENCE performs multiple READ-BYTE operations: (READ-BYTE-SEQUENCE sequence stream [:start] [:end]) fills the subsequence of sequence specified by :start and :end with integers consecutively read from stream. It returns the index of the first element of sequence that was not updated (= end or < end if the stream reached its end). This function is especially efficient if sequence is a (VECTOR (UNSIGNED-BYTE 8)) and stream is a file stream with element type (UNSIGNED-BYTE 8) or a pipe stream. 22.3.1. ------- The functions WRITE and WRITE-TO-STRING have an additional keyword :CLOSURE that can be used to bind *PRINT-CLOSURE*. The CLtL2 macro PRINT-UNREADABLE-OBJECT is implemented. The function WRITE-CHAR-SEQUENCE performs multiple WRITE-CHAR operations: (WRITE-CHAR-SEQUENCE sequence stream [:start] [:end]) outputs the characters of the subsequence of sequence specified by :start and :end to stream. It returns sequence. This function is especially efficient if sequence is a string and stream is a file stream with element type STRING-CHAR or a pipe stream. 22.3.2. ------- The function WRITE-BYTE-SEQUENCE performs multiple WRITE-BYTE operations: (WRITE-BYTE-SEQUENCE sequence stream [:start] [:end]) outputs the integers of the subsequence of sequence specified by :start and :end to stream. It returns sequence. This function is especially efficient if sequence is a (VECTOR (UNSIGNED-BYTE 8)) and stream is a file stream with element type (UNSIGNED-BYTE 8) or a pipe stream. 22.3.3. ------- The FORMAT option ~W is analogous to ~A and ~S, but avoids binding of *PRINT-ESCAPE*. (FORMAT stream "~W" object) is equivalent to (WRITE object :stream stream). FORMAT ~R and FORMAT ~:R can output only integers in the range |n| < 10^66. The output is in English, according to the American conventions, and these conventions are identical to the British conventions only in the range |n| < 10^9. FORMAT ~:@C does not output the character itself, only the instruction how to type the character. For FORMAT ~E and FORMAT ~G, the value of *READ-DEFAULT-FLOAT-FORMAT* doesn't matter if *PRINT-READABLY* is true. FORMAT ~T can determine the current column of any stream. CHAPTER 23: File System Interface --------------------------------- 23.1. ----- For most operations, pathnames denoting files and pathnames denoting directories can not be used interchangeably. For example, #"FOO/BAR" denotes the file BAR in the directory FOO, while #"FOO/BAR/" denotes the subdirectory BAR of the directory FOO. This is especially important for the functions DIRECTORY, DIR, CD, MAKE-DIR, DELETE-DIR. The minimum filename syntax that may be used portably is: "xxx" for a file with name xxx, "xxx.yy" for a file with name xxx and type yy, ".yy" for a pathname with type yy and no name specified. Hereby xxx denote 1 to 8 characters, and yy denote 1 to 3 characters, each of which being either alphanumerical or the underscore #\_. Other properties of pathname syntax vary between operating systems. 23.1.1. ------- Pathname components: HOST always NIL DEVICE NIL or a simple string DIRECTORY (startpoint . subdirs) where startpoint = :RELATIVE | :ABSOLUTE subdirs = () | (subdir . subdirs) subdir = :WILD-INFERIORS (means "**" or "...", all subdirectories) or subdir = :PARENT (means "/" instead of "subdir/") or subdir = simple string, may contain wildcard characters ? and * NAME NIL or simple string, may contain wildcard characters ? and * (may also be specified as :WILD) TYPE NIL or simple string, may contain wildcard characters ? and * (may also be specified as :WILD) VERSION always NIL (may also be specified as :WILD or :NEWEST) Constraint: startpoint = :RELATIVE only if device = NIL. If the device is specified, the pathname must be absolute! A filename from AMIGAOS is split into name and type according to the following rule: if there is no '.' in the filename, then the name is everything, type = NIL; if there is a '.', then name is the part before and type the part after the last dot. Case is ignored in the strings on comparison. No case conversions are performed. When a pathname is to be fully specified (no wildcards), that means that no :WILD, :WILD-INFERIORS is allowed, no wildcard characters are allowed in the strings, and NAME = NIL may not be allowed either. External notation: dev:sub1.typ/sub2.typ/name.typ using defaults: sub1.typ/sub2.typ/name.typ or name.typ or sub1.typ/**/sub3.typ/x*.lsp or similar. Formal specification of the external notation: ch ::= any character except ':','/' and '*','?' name ::= {ch}+ device ::= [ | ':' | name ':' ] ; empty = current device, relative to current directory ; ':' = current device, absolute (relative to root for disks) ; name ':' = specified device, absolute (relative to root for disks) subdir ::= [ | name ] ; empty means parent directory pathname ::= device { subdir '/' }* name Examples: String Device Directory our pathname ------ ------ --------- -------------- 'c:foo' 'C', device->foo "c" (:ABSOLUTE "foo") 'c:foo/' 'C', device->foo "c" (:ABSOLUTE "foo") 'c:foo/bar' 'C', device->foo->bar "c" (:ABSOLUTE "foo" "bar") 'c:/foo' 'C', device->up->foo "c" (:ABSOLUTE :PARENT "foo") 'c:' 'C', device "c" (:ABSOLUTE) ':foo' current, device->root->foo NIL (:ABSOLUTE "foo") 'foo' current, device->foo NIL (:RELATIVE "foo") '/foo' current, device->up->foo NIL (:RELATIVE :PARENT "foo") '//foo/bar' current, device->up->up->foo->bar NIL (:RELATIVE :PARENT :PARENT "foo" "bar") '' current, device NIL (:RELATIVE) Appending a '/' to a path string that is non-empty and does not end with ':' or '/' does not change its meaning. This '/' must be appended before another non-empty component can be appended. But appending a '/' to a path string that is empty or ends with ':' or '/' means going up to the parent directory! We interpret any path string that is empty or ends with ':' or '/' as pathname of a directory (with name = NIL and type = NIL). The wildcard characters: '*' matches any sequence of characters, '?' matches any one character. Due to the name/type splitting rule, there are pathnames that can't result from PARSE-NAMESTRING. To get a pathname whose type contains a dot or whose name contains a dot and whose type is NIL, MAKE-PATHNAME must be used. Example: (MAKE-PATHNAME :NAME ".profile"). 23.1.2. ------- External notation of pathnames (cf. PARSE-NAMESTRING and NAMESTRING), of course without spaces, [,],{,}: see above. NAMESTRING has an optional flag argument: (NAMESTRING pathname T) returns an external notation suitable for passing to the operating system or other programs. The function USER-HOMEDIR-PATHNAME is not implemented. 23.1.4. ------- The CLtL2 functions WILD-PATHNAME-P, PATHNAME-MATCH-P and TRANSLATE-PATHNAME are implemented. PATHNAME-MATCH-P does not interpret missing components as wild. TRANSLATE-PATHNAME has two additional keywords: (TRANSLATE-PATHNAME source from-wildname to-wildname &key :all :merge) If :ALL is specified and non-NIL, a list of all resulting pathnames, corresponding to all matches of (PATHNAME-MATCH-P source from-wildname), is returned. If :MERGE is specified and NIL, unspecified pieces of to-pathname are not replaced by corresponding pieces of source. 23.1.5. ------- The functions LOGICAL-PATHNAME, TRANSLATE-LOGICAL-PATHNAME, LOGICAL-PATHNAME-TRANSLATIONS, (SETF LOGICAL-PATHNAME-TRANSLATIONS), LOAD-LOGICAL-PATHNAME-TRANSLATIONS, COMPILE-FILE-PATHNAME are implemented. RENAME-FILE always returns a non-logical pathname as its first value. 23.1.6. ------- (PARSE-NAMESTRING string [host [defaults]]) returns a logical pathname only if host is a logical host or host is NIL and defaults is a logical pathname. To construct a logical pathname from a string, the function LOGICAL-PATHNAME can be used. (MERGE-PATHNAMES string [defaults]) returns a logical pathname only if defaults is a logical pathname. To construct a logical pathname from a string, the function LOGICAL-PATHNAME can be used. TRUENAME will not reject pathnames which are directories. PARSE-NAMESTRING will interpret a leading `.' in a namestring as part of the file name, not the file type. 23.2. ----- OPEN cannot handle files of size >= 16 MB. The file streams returned by OPEN are buffered for regular files and unbuffered for special files. 23.3. ----- PROBE-FILE may be used to check whether a directory exists. RENAME-FILE will attempt to overwrite the destination file if it already exists. FILE-AUTHOR always returns NIL. 23.4. ----- LOAD has two additional keywords :ECHO and :COMPILING. (LOAD filename &key :verbose :print :echo :if-does-not-exist :compiling) :VERBOSE T causes LOAD to emit a short message that a file is being loaded. The default is *LOAD-VERBOSE*, which is initially = T. :PRINT T causes LOAD to print the value of each form. The default is *LOAD-PRINT*, which is initially = NIL. :ECHO T causes the input from the file to be echoed to *STANDARD-OUTPUT* (normally to the screen). Should there be an error in the file, you can see at one glance where it is. The default is *LOAD-ECHO*, which is initially = NIL. :COMPILING T causes each form read to be compiled on the fly. The compiled code is executed at once and - in contrast to COMPILE-FILE - not written to a file. The CLtL2 variables *LOAD-PATHNAME* and *LOAD-TRUENAME* are implemented. The variable *LOAD-PATHS* contains a list of directories where program files are searched - additionally to the specified or current directory - by LOAD, REQUIRE, COMPILE-FILE. 23.5. ----- (DIRECTORY [pathname [:full] [:circle]]) can run in two modes: * If pathname contains no name or type component, a list of all matching directories is produced. * Otherwise a list of all matching files is returned. If the :FULL argument is /= NIL, this contains additional information: for each matching file you get a list of at least four elements (file-pathname file-truename file-write-date-as-decoded-time file-length). (DIR [pathname]) is like DIRECTORY, but displays the pathnames instead of returning them. (DIR) shows the contents of the current directory. (CD [pathname]) manages the current directory. (CD pathname) sets it, (CD) returns it. (DEFAULT-DIRECTORY) is equivalent to (CD), (SETF (DEFAULT-DIRECTORY) pathname) is equivalent to (CD pathname). (MAKE-DIR directory-pathname) creates a new subdirectory. (DELETE-DIR directory-pathname) removes an (empty) subdirectory. (EXECUTE command) executes a given command using the operating system's shell. (SHELL [command]) calls the operating system's shell. (SHELL) calls the shell for interactive use. (SHELL command) calls the shell only for execution of the one given command. CHAPTER 24: Errors ------------------ 24.1. ----- When an error occurred, you are in a break loop. You can evaluate forms as usual. The HELP command (or help key if there is one) lists the available debugging commands. CHAPTER 25: Miscellaneous Features ---------------------------------- 25.1. ----- The compiler can be called not only by the functions COMPILE, COMPILE-FILE and DISASSEMBLE, also by the declaration (COMPILE). (COMPILE-FILE input-file [:output-file] [:listing] [:warnings] [:verbose] [:print]) compiles a file to bytecode. input-file should be a pathname/string/symbol. The :output-file argument should be NIL or T or a pathname/string/symbol or an output-stream. The default is T. The :listing argument should be NIL or T or a pathname/string/symbol or an output-stream. The default is NIL. The :warnings argument specifies whether warnings should also appear on the screen. The :verbose argument specifies whether error messages should also appear on the screen. The :print argument specifies whether an indication which forms are being compiled should appear on the screen. The variables *COMPILE-WARNINGS*, *COMPILE-VERBOSE*, *COMPILE-PRINT* provide defaults for the :warnings, :verbose, :print keyword arguments, respectively. For each input file (default file type: #".lsp") the following files are generated: output file only if :output-file is not NIL default file type: #".fas" contents: can be loaded using the LOAD function. auxiliary output file only if :output-file is not NIL default file type: #".lib" contents: used by COMPILE-FILE when compiling a REQUIRE form referring to the input file. listing file only if :listing is not NIL default file type: #".lis" contents: disassembly of the output file. C output file only if :output-file is not NIL default file type: #".c" contents: foreign function interface this file is deleted if it is empty. The CLtL2 variables *COMPILE-FILE-PATHNAME* and *COMPILE-FILE-TRUENAME* are implemented. The CLtL2 special form LOAD-TIME-VALUE is implemented. (LOAD-TIME-VALUE form) is like (QUOTE #,form) except that the former can be generated by macros. The CLtL2 function FUNCTION-LAMBDA-EXPRESSION is implemented. (FUNCTION-LAMBDA-EXPRESSION function) returns information about the source of an interpreted function: lambda-expression, lexical environment, name. 25.2. ----- No on-line documentation is available for the system functions (yet). 25.3. ----- (TRACE fun ...) makes the functions fun, ... traced. Syntax of fun: Either a symbol: symbol or a list of a symbol and some keywords and arguments (which must come in pairs!): (symbol [:suppress-if form] ; no trace output as long as form is true [:step-if form] ; invokes the stepper as soon as form is true [:pre form] ; evaluates form before calling the function [:post form] ; evaluates form after return from the function [:pre-break-if form] ; goes into the break loop before calling the ; function if form is true [:post-break-if form] ; goes into the break loop after return from ; the function if form is true [:pre-print form] ; prints the values of form before calling the ; function [:post-print form] ; prints the values of form after return from ; the function [:print form] ; prints the values of form both before ; calling and after return from the function ) In all these forms you can access the function itself as *TRACE-FUNCTION*, the arguments to the function as *TRACE-ARGS*, the function/macro call as form as *TRACE-FORM*, and after return from the function the list of return values from the function call as *TRACE-VALUES*, and you can leave the function call with specified values by using RETURN. TRACE and UNTRACE are also applicable to functions (SETF symbol) and to macros, but not to locally defined functions and macros. The function INSPECT is not implemented. The function ROOM can only be called without arguments. It returns two values: the number of bytes currently occupied by Lisp objects, and the number of bytes that can be allocated before the next regular garbage collection occurs. The function ED calls the external editor specified by the variable *EDITOR* (see config.lsp). If using the optional package EDITOR: ED behaves like this only if the variable *USE-ED* is NIL. Otherwise ED uses a screen editor with multiple windows. The function UNCOMPILE does the converse of COMPILE: (UNCOMPILE function-name) reverts an interpreted function that has been entered or loaded in the same session and then compiled back to its interpreted form. 25.4.1. ------- The variable *DEFAULT-TIME-ZONE* contains the default time zone used by ENCODE-UNIVERSAL-TIME and DECODE-UNIVERSAL-TIME. It is initially set to -1 (which means 1 hour east of Greenwich, i.e. Mid European Time). The timezone in a decoded time must not necessarily be an integer, but (as float or rational number) it should be a multiple of 1/4. INTERNAL-TIME-UNITS-PER-SECOND = 50. 25.4.2. ------- The functions MACHINE-TYPE, MACHINE-VERSION, MACHINE-INSTANCE and SHORT-SITE-NAME, LONG-SITE-NAME should be defined by every user in his site-specific CONFIG.LSP file. The variable *FEATURES* initially contains the symbols CLISP ; this implementation COMMON-LISP CLTL1 INTERPRETER COMPILER LOGICAL-PATHNAMES LOOP CLOS AMIGA ; if hardware = Amiga and operating system = Exec/AmigaDOS DOS ; if hardware = PC (clone) and operating system = DOS OS/2 ; if hardware = PC (clone) and operating system = OS/2 PC386 ; if hardware = PC (clone) with a 386/486 UNIX ; if operating system = Unix ; (yes, in this case the ; hardware is irrelevant!) CHAPTER 26: Loop ---------------- The CLtL2 macros LOOP and LOOP-FINISH are implemented. CHAPTER 27: Pretty Printing --------------------------- The CLtL2 macro FORMATTER is implemented. CHAPTER 28: Common Lisp Object System ------------------------------------- To use CLOS, do (USE-PACKAGE "CLOS"). The functions SLOT-VALUE, SLOT-BOUNDP, SLOT-MAKUNBOUND, SLOT-EXISTS-P, FIND-CLASS, (SETF FIND-CLASS), CLASS-OF, CALL-NEXT-METHOD, NEXT-METHOD-P, CLASS-NAME, (SETF CLASS-NAME), NO-APPLICABLE-METHOD, NO-NEXT-METHOD, FIND-METHOD, ADD-METHOD, REMOVE-METHOD, COMPUTE-APPLICABLE-METHODS, METHOD-QUALIFIERS, FUNCTION-KEYWORDS, SLOT-MISSING, SLOT-UNBOUND, PRINT-OBJECT, DESCRIBE-OBJECT, MAKE-INSTANCE, INITIALIZE-INSTANCE, REINITIALIZE-INSTANCE, SHARED-INITIALIZE, the macros WITH-SLOTS, WITH-ACCESSORS, DEFCLASS, DEFMETHOD, DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, GENERIC-LABELS, the classes STANDARD-CLASS, STRUCTURE-CLASS, BUILT-IN-CLASS, STANDARD-OBJECT, STANDARD-GENERIC-FUNCTION, STANDARD-METHOD and all predefined classes, and the method combination STANDARD are implemented. Deviations from CLtL2 chapter 28: DEFCLASS : It *is* required that the superclasses of a class be defined before the DEFCLASS form for the class is evaluated. The REAL type is added to the predefined classes listed in table 28-1. Only STANDARD method combination is implemented. When CALL-NEXT-METHOD is called with arguments, the rule that the ordered set of applicable methods must be the same as for the original arguments is not enforced by the implementation. CALL-NEXT-METHOD and NEXT-METHOD-P are local macros, not local functions. Use #'(lambda () (call-next-method)) instead of #'call-next-method if you really need it as a function. There is a generic function NO-PRIMARY-METHOD (analogous to NO-APPLICABLE-METHOD) which is called when a generic function of the class STANDARD-GENERIC-FUNCTION is invoked and no primary method on that generic function is applicable. GENERIC-FLET and GENERIC-LABELS are implemented as macros, not as special forms. The function ENSURE-GENERIC-FUNCTION is not implemented. ADD-METHOD can put methods into other generic functions than the one the method came from. PRINT-OBJECT and DESCRIBE-OBJECT are only called on objects of type STANDARD-OBJECT. DESCRIBE-OBJECT should not call DESCRIBE recursively as this would produce more information than is likely to be useful to a human reader. DOCUMENTATION still has the CLtL1 implementation. User-defined method combination is not supported. The sections 28.1.7.3., 28.1.7.4., the macros DEFINE-METHOD-COMBINATION, CALL-METHOD and the functions INVALID-METHOD-ERROR, METHOD-COMBINATION-ERROR, METHOD-QUALIFIERS are not implemented. The special form WITH-ADDED-METHODS is not implemented. Redefining classes is not supported. The sections 28.1.10., 28.1.10.1., 28.1.10.2., 28.1.10.3., 28.1.10.4. and the function UPDATE-INSTANCE-FOR-REDEFINED-CLASS are not implemented. Changing the class of a given instance is not supported. The sections 28.1.11., 28.1.11.1., 28.1.11.2., 28.1.11.3. and the functions CHANGE-CLASS, UPDATE-INSTANCE-FOR-DIFFERENT-CLASS, MAKE-INSTANCES-OBSOLETE are not implemented. CHAPTER 29: Conditions ---------------------- 29.4.1. ------- The default condition type for conditions created by SIGNAL is SIMPLE-CONDITION, not SIMPLE-ERROR. 29.4.4. ------- The macro (MUFFLE-CERRORS {form}*) executes the forms. When a continuable error occurs, no message is printed. Instead, the CONTINUE restart is invoked. The macro (APPEASE-CERRORS {form}*) executes the forms. When a continuable error occurs, the error is printed as a warning and the CONTINUE restart is invoked. The macro (EXIT-ON-ERROR {form}*) executes the forms. When a non-continuable error occurs, the error is printed and CLISP terminates with error status. 29.4.7. ------- In RESTART-CASE clauses the argument list can also be specified after the keyword/value pairs instead of before them. The syntax therefore is (RESTART-CASE form {restart-clause}*) with restart-clause ::= (restart-name arglist {keyword value}* {form}*) | (restart-name {keyword value}* arglist {form}*) The macro WITH-RESTARTS is like RESTART-CASE, except that the forms are specified after the restart clauses instead of before them, and the restarts created are not implicitly associated to any condition. (WITH-RESTARTS ({restart-clause}*) {form}*) is therefore equivalent to (RESTART-CASE (PROGN {form}*) {restart-clause}*). 29.4.8. ------- COMPUTE-RESTARTS and FIND-RESTART behave as specified in dpANS: If the optional condition argument is not NIL, only restarts associated with that condition and restarts associated to no condition at all are considered. Therefore the effect of associating a restart to a condition is not to activate it, but to hide it from other conditions. This makes the syntax dependent implicit association performed by RESTART-CASE nearly obsolete. 29.4.9. ------- The default condition type for conditions created by WARN is SIMPLE-WARNING, not SIMPLE-ERROR. CHAPTER 90: Platform independent Extensions ------------------------------------------- 90.1. Saving an Image --------------------- The function (SAVEINITMEM [filename [:quiet] [:init-function]]) saves the running CLISP's memory to a file. The filename defaults to "lispinit.mem". If the :QUIET argument is not NIL, the startup banner and the good-bye message will be suppressed. The :INIT-FUNCTION argument specifies a function that will be executed at startup of the saved image. 90.2. Quitting Lisp ------------------- The functions (EXIT [errorp]), (QUIT [errorp]) and (BYE [errorp]) - all synonymous - terminate CLISP. If errorp is not NIL, CLISP aborts with error status, i.e. the environment is informed that the CLISP session didn't succeed. 90.3. The Language ------------------ The language CLISP uses to communicate with the user can be either ENGLISH or DEUTSCH (i.e. german) or FRANCAIS (i.e. french). The macros ENGLISH, DEUTSCH, FRANCAIS and LANGUAGE-CASE produce code that depends on the language: (ENGLISH english-form DEUTSCH deutsch-form FRANCAIS francais-form) - and all permutations of this - evaluates all of english-form, deutsch-form, francais-form in no particular order and returns the evaluation result corresponding to the user language. (LANGUAGE-CASE {clause}*) executes the clause (analogous to CASE) that corresponds to the user language. The language itself is the value of (ENGLISH 'ENGLISH DEUTSCH 'DEUTSCH FRANCAIS 'FRANCAIS). 90.4. Finalization ------------------ Calling (FINALIZE object function) has the effect that when the specified object is being garbage collected, (FUNCALL function object) will be executed. Calling (FINALIZE object function guardian) has a similar effect, but only as long as the "guardian" has not been garbage collected: When object is being garbage collected, (FUNCALL function object guardian) will be executed. If the guardian is garbage collected before object is, nothing happens. Note: The time when "object is being garbage collected" is not defined deterministically. (Actually, it possibly never occurs.) It denotes a moment at which no references to object exist from other Lisp objects. When the function is called, object (and possibly guardian) enter the "arena of live Lisp objects" again. No finalization request will be executed more than once. CHAPTER 91: The Debugger and Stepper ------------------------------------ The debugger may be invoked through the functions INVOKE-DEBUGGER, BREAK, SIGNAL, ERROR, CERROR, WARN. The stepper is invoked through the macro STEP. Debugger and stepper execute subordinate READ - EVAL - PRINT loops (called "break loops") which are analogous to the main READ - EVAL - PRINT loop except for the prompt and the set of available commands. Commands must be typed literally, without surrounding quotes or white space. Commands common to the main loop, the debugger and the stepper: Help prints a list of available commands. Commands common to the debugger and the stepper: Abort and Unwind abort to the next most recent READ - EVAL - PRINT loop. The stack is organized into frames and other stack elements. Usually every invocation of an interpreted function and every evaluation of an interpreted form corresponds to one stack frame. Special forms such as LET, LET*, UNWIND-PROTECT and CATCH produce special kinds of stack frames. In a break loop there is a current stack frame, which is initially the most recent stack frame but can be moved using the debugger commands Up and Down. Evaluation of forms in a break loop occurs in the lexical environment of the current stack frame but in the dynamic environment of the debugger's caller. This means that to inspect or modify a lexical variable all you have to do is to move to the current stack frame just below the frame that corresponds to the form or the function call that binds that variable. There is a current "stack mode" which defines in how much detail the stack is shown by the stack related debugger commands. Commands common to the debugger and the stepper: Mode-1 sets the current mode to 1: all the stack elements are considered. This mode is fine for debugging compiled functions. Mode-2 sets the current mode to 2: all the frames are considered. Mode-3 sets the current mode to 3: only lexical frames (frames that correspond to special forms that modify the lexical environment) are considered. Mode-4 sets the current mode to 4 (the default): only EVAL and APPLY frames are considered. Every evaluation of a form in the interpreter corresponds to an EVAL frame. Mode-5 sets the current mode to 5: only APPLY frames are considered. Every invocation of an interpreted function corresponds to one APPLY frame. Where shows the current stack frame. Up goes up one frame, i.e. to the caller if in mode-5 Down does down one frame, i.e. to the callee if in mode-5 Top goes to top frame, i.e. to the top-level form if in mode-4 Bottom goes to bottom (most recent) frame, i.e. most probably to the form or function that caused the debugger to be entered. Backtrace lists the stack in current mode, bottom frame first, top frame last. Backtrace-1 lists the stack in mode 1. Backtrace-2 lists the stack in mode 2. Backtrace-3 lists the stack in mode 3. Backtrace-4 lists the stack in mode 4. Backtrace-5 lists the stack in mode 5. If the current stack frame is an EVAL or APPLY frame, the following commands are available as well: Break+ sets a breakpoint in the current frame. When the corresponding form or function will be left, the debugger will be entered again, with the variable *TRACE-VALUES* containing a list of its values. Break- removes a breakpoint from the current frame. Redo re-evaluates the corresponding form or function call. This command can be used to restart parts of a computation without aborting it entirely. Return leaves the current frame. You will be prompted for the return values. Commands specific to the debugger: Continue continues evaluation of the program. Commands specific to the stepper: Step step into a form: evaluate this form in single step mode Next step over a form: evaluate this form at once Over step over this level: evaluate at once up to the next return Continue switch off single step mode, continue evaluation The stepper is usually used like this: If some form returns a strange value or results in an error, call (STEP form) and navigate using the commands Step and Next until you reach the form you regard as responsible. If you are too fast (execute Next once and get the error), there is no way back; you have to restart the entire stepper session. If you are too slow (stepped into a function or a form which certainly is OK), a couple of Next commands or one Over command will help. CHAPTER 99: Platform specific Extensions ---------------------------------------- 99.2. Random Screen Access -------------------------- (SCREEN:MAKE-WINDOW) returns a "window stream". As long as this stream is open, the terminal is in cbreak/noecho mode. *TERMINAL-IO* shouldn't be used for input or output during this time. (Use WITH-KEYBOARD and *KEYBOARD-INPUT* instead.) (SCREEN:WITH-WINDOW . body) binds SCREEN:*WINDOW* to a window stream and executes body. The stream is guaranteed to be closed when the body is left. During its execution, *TERMINAL-IO* shouldn't be used, as above. (SCREEN:WINDOW-SIZE window-stream) returns the window's size, as two values: height (= Ymax+1) and width (= Xmax+1). (SCREEN:WINDOW-CURSOR-POSITION window-stream) returns the position of the cursor in the window, as two values: line (>=0, <=Ymax, 0 means top), column (>=0, <=Xmax, 0 means left margin). (SCREEN:SET-WINDOW-CURSOR-POSITION window-stream line column) sets the position of the cursor in the window. (SCREEN:CLEAR-WINDOW window-stream) clears the window's contents and puts the cursor in the upper left corner. (SCREEN:CLEAR-WINDOW-TO-EOT window-stream) clears the window's contents from the cursor position to the end of window. (SCREEN:CLEAR-WINDOW-TO-EOL window-stream) clears the window's contents from the cursor position to the end of line. (SCREEN:DELETE-WINDOW-LINE window-stream) removes the cursor's line, moves the lines below it up by one line and clears the window's last line. (SCREEN:INSERT-WINDOW-LINE window-stream) inserts a line at the cursor's line, moving the lines below it down by one line. (SCREEN:HIGHLIGHT-ON window-stream) switches highlighted output on. (SCREEN:HIGHLIGHT-OFF window-stream) switches highlighted output off. (SCREEN:WINDOW-CURSOR-ON window-stream) makes the cursor visible, a cursor block in most implementations. (SCREEN:WINDOW-CURSOR-OFF window-stream) makes the cursor invisible, in implementations where this is possible. 99.5. ARexx ----------- CLISP comes with a small yet extensible and powerful ARexx interface. (REXX-DO-COMMAND "return address()" :STRING T :RESULT T) tells you the name of the CLISP ARexx port. The default extension for CLISP ARexx scripts is "cl". (REXX-DO-COMMAND command &KEY :string :result :token :io) -> (RC &OPTIONAL RESULT), or NIL on failure (REXX-RUN-COMMAND command &KEY :string :token) -> T, or NIL on failure (REXX-SEND-COMMAND command &KEY :string :result :token :io :async) -> arexx-msg-handle, or NIL on failure (REXX-WAIT-SENT-COMMAND arexx-msg-handle) -> (RC &OPTIONAL RESULT), or NIL on failure (REXX-LOOP) -> no return, use the exit-loop.cl ARexx script to abort the loop Command may be a string denoting a command with optional arguments or a vector of strings thus denoting an ARexx function call. The first element in the vector is the function name, the others are the up to 15 arguments. ARexx server mode: Like Ispell, Csh and SKsh, you can run it in server mode by calling (REXX-LOOP). You can then only exit with the ARexx exit-loop.cl script. Restrictions: Currently CLISP is not able to wait for input from several sources, e.g. both a console and ARexx, at the same time. 99.9. Other ----------- To have *DEBUG-IO* and *ERROR-OUTPUT* point to separate console windows (thus keeping your standard console window clean from error messages) you can use (SETQ *ERROR-OUTPUT* (SETQ *DEBUG-IO* (OPEN "CON:0/0/500/300/CLISP-Debugger/AUTO/CLOSE" :DIRECTION :IO) ) ) at startup. Authors: -------- Bruno Haible Michael Stoll Augartenstraße 40 Gallierweg 39 D - 76137 Karlsruhe D - 53117 Bonn Germany Germany Maintainer: marcus@sysc.pdx.edu haible@ma2s2.mathematik.uni-karlsruhe.de