
Copyright © 1992-2008 Bruno Haible
Copyright © 1998-2008 Sam Steingold
Legal Status of the CLISP Implementation Notes
These notes are dually licensed under GNU GFDL and GNU GPL. This means that you can redistribute this document under either of these two licenses, at your choice.
These notes are covered by the GNU GFDL. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License (GFDL), either version 1.2 of the License, or (at your option) any later version published by the Free Software Foundation (FSF); with no Invariant Sections, with no Front-Cover Text, and with no Back-Cover Texts. A copy of the license is included in Appendix B, GNU Free Documentation License.
These notes are covered by the GNU GPL. This document documents free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL), either version 2 of the License, or (at your option) any later version published by the Free Software Foundation (FSF). A copy of the license is included in Appendix C, GNU General Public License.
Abstract
This document describes the GNU CLISP - an implementation of the [ANSI CL standard].
See the section called “Bugs” for instructions on how to report bugs (both in these notes and in CLISP itself).
See Q: A.1.1.5 for information on CLISP support.
Table of Contents
STREAM-ELEMENT-TYPEEXT:MAKE-STREAMFILE-POSITIONEXT:ELASTIC-NEWLINEOPENCLOSEOPEN-STREAM-PBROADCAST-STREAMEXT:MAKE-BUFFERED-INPUT-STREAM
and
EXT:MAKE-BUFFERED-OUTPUT-STREAM
WRITE & WRITE-TO-STRINGPRINT-UNREADABLE-OBJECTList of Figures
List of Tables
EVAL/APPLYTYPECODESHEAPCODESList of Examples
TRACEEXT:FILL-STREAM usagegethostname from CLISPREGEXP:MATCHREGEXP:REGEXP-QUOTEThese notes discuss the CLISP implementation of Common Lisp by and . The current maintainers are and .
This implementation is mostly conforming to the [ANSI CL standard] available on-line as the [Common Lisp HyperSpec] (but the printed ANSI document remains the authoritative source of information). [ANSI CL standard] supersedes the earlier specifications [CLtL1] and [CLtL2].
The first part of these notes, Part I, “Chapters or the Common Lisp HyperSpec”, is indexed in parallel to the [Common Lisp HyperSpec] and documents how CLISP implements the [ANSI CL standard].
The second part, Part II, “Common Portable Extensions”, documents the
common extensions to the [ANSI CL standard], specifically Meta-Object Protocol and “GRAY”
STREAMs.
The third part, Part III, “Extensions Specific to CLISP”, documents the CLISP-specific extensions, e.g., Section 32.4, “Socket Streams”.
The fourth part, Part IV, “Internals of the CLISP Implementation”, is intended mostly
for developers as it documents the CLISP internals, e.g., garbage-collection,
adding new built-ins, and the bytecodes generated by the compiler
(i.e., what is printed by DISASSEMBLE).
The following is the mark-up notations used in this document:
Table 1. Mark-up conventions
| Object Kind | Example |
|---|---|
| Function | CAR |
| Variable | CUSTOM:*LOAD-PATHS* |
| Formal Argument | x |
| Keyword | :EOF |
| Number | 0 |
| Character | #\Newline |
| Class, type | REGEXP:MATCH |
| Format instruction | ~A |
| Standard lambda list keyword | &KEY |
| Declaration | FTYPE |
| Package | “COMMON-LISP-USER” |
| Real file | config.lisp |
| Abstract file | #P".c" |
| Code (you are likely to type it) | ( |
| Data (CLISP is likely to print it) | #(1 2 3) |
| Program listing |
(defun cycle-length (n |
| Bytecode instruction | (STOREV |
| First mention of an entity | firstterm |
| External module | libsvm, bindings/glibc |
| Command line argument | -x |
Table of Contents
STREAM-ELEMENT-TYPEEXT:MAKE-STREAMFILE-POSITIONEXT:ELASTIC-NEWLINEOPENCLOSEOPEN-STREAM-PBROADCAST-STREAMEXT:MAKE-BUFFERED-INPUT-STREAM
and
EXT:MAKE-BUFFERED-OUTPUT-STREAM
WRITE & WRITE-TO-STRINGPRINT-UNREADABLE-OBJECTTable of Contents
The final delimiter of an interactive stream:
This final delimiter is never actually seen by programs; no need to
test for #\^D or #\^Z - use
READ-CHAR-NO-HANG to check for end-of-stream.
Calling CLEAR-INPUT on the stream removes the end-of-stream state,
thus making it available for further input.
A newline character can be entered by the user by pressing the Enter key.
Safety settings are ignored by the interpreted code;
therefore where the standard uses the phrase “should signal an
error”, an ERROR is SIGNALed.
See Section 3.3.4, “Declaration SAFETY” for the safety of compiled code.
All 978 symbols in the “COMMON-LISP” package specified by the [ANSI CL standard] are implemented.
Table of Contents
The standard characters are #\Newline and the
graphic characters
with a CODE-CHAR between 32 and 126 (inclusive).
The requirement of step 4 that a “reader
macro function may return zero values or one value”
is enforced. You can use the function VALUES to control the
number of values returned.
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.
When a token with package markers is read, then no checking is
done whether the SYMBOL-PACKAGE part and the SYMBOL-NAME part do
not have number syntax. (What would the purpose of this check be?)
So we consider tokens like USER:: or :1 or
LISP::4711 or 21:3 as symbols.
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)))))
Reader macros are also defined for the following:
Additional reader macros
FUNCTION objects and input STREAM's EXT:ENCODINGs
PATHNAME: #"test.lisp"
is the value of (PATHNAME "test.lisp")#\Code allows input of characters of arbitrary code:
e.g., #\Code231 reads as the character
(.CODE-CHAR 231)
This is the list of objects whose external representation cannot be meaningfully read in:
Unreadable objects
#<type ...>STRUCTURE-OBJECTs lacking a keyword
constructor#<ARRAY type
dimensions>ARRAYs except STRINGs, if
*PRINT-ARRAY* is NIL#<SYSTEM-FUNCTION name>#<ADD-ON-SYSTEM-FUNCTION
name>#<SPECIAL-OPERATOR
name>#<COMPILED-CLOSURE
name>CUSTOM:*PRINT-CLOSURE* is NIL
#<CLOSURE name ...>#<FRAME-POINTER #x...>#<DISABLED POINTER>BLOCK or TAGBODY#<...STREAM...>STREAM#<PACKAGE name>PACKAGE#<HASH-TABLE #x...>HASH-TABLE, if *PRINT-ARRAY* is NIL
#<READTABLE #x...>READTABLE#<SYMBOL-MACRO form>SYMBOL-MACRO handler#<MACRO function>DEFMACRO and friends)
#<FFI:FOREIGN-POINTER
#x...>#<FFI:FOREIGN-ADDRESS
#x...>#<FFI:FOREIGN-VARIABLE name
#x...>#<FFI:FOREIGN-FUNCTION name
#x...>#<UNBOUND>#<SPECIAL REFERENCE>SPECIAL
#<DOT>READ result for “.”
#<END OF FILE>READ result, when the end-of-stream is reached
#<READ-LABEL ...>READ result for #n#
#<ADDRESS #x...>#<SYSTEM-POINTER #x...>Table of Contents
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).
Table 3.1. Function call limits
CALL-ARGUMENTS-LIMIT | 212=4096 |
MULTIPLE-VALUES-LIMIT | 27=128 |
LAMBDA-PARAMETERS-LIMIT | 212=4096 |
Macro EXT:THE-ENVIRONMENT. As in Scheme, the macro (
returns the current lexical environment. This works only in interpreted code and
is not compilable!EXT:THE-ENVIRONMENT)
Function (EXT:EVAL-ENV
. evaluates a form in a given lexical environment, just as if the
form had been a part of the program that the form &OPTIONAL environment)environment came from.
DEFINE-SYMBOL-MACROThe macro DEFINE-SYMBOL-MACRO establishes SYMBOL-MACROs with
global scope (as opposed to SYMBOL-MACROs defined with
SYMBOL-MACROLET, which have local scope).
The function
EXT:SYMBOL-MACRO-EXPAND
tests for a SYMBOL-MACRO: If symbol is defined as a SYMBOL-MACRO
in the global environment, ( returns two
values, EXT:SYMBOL-MACRO-EXPAND symbol)T and the expansion; otherwise it returns NIL.
EXT:SYMBOL-MACRO-EXPAND is a special case of MACROEXPAND-1. MACROEXPAND-1
can also test whether a symbol is defined as a SYMBOL-MACRO in lexical environments
other than the global environment.
“Undefined variables”, i.e. variables which are
referenced outside any lexical binding for a variable of the same name
and which are not declared SPECIAL, are treated like dynamic variables
in the global environment. The compiler SIGNALs a WARNING when it
encounters an undefined variable.
Lists of the form (( are also
treated as function forms. This makes the syntax
SETF symbol) ...)( consistent with the syntax
function-name arguments ...)(.
It implements the item 7 of the [ANSI CL standard] issue FUNCTION-NAME:LARGE and the
definition of function forms,
and is consistent with the use of function names elsewhere in Common Lisp.
FUNCALL #'function-name arguments ...)
EVAL-WHENEVAL-WHEN also accepts the situations (NOT EVAL)
and (NOT COMPILE).
The situations EVAL,
LOAD and COMPILE are
deprecated by the [ANSI CL standard], and they are not equivalent to the new
standard situations :EXECUTE,
:LOAD-TOPLEVEL
and :COMPILE-TOPLEVEL in that they ignore the
top-level form versus non-top-level form distinction.
THEThe special form ( is
similar to THE value-type form)CHECK-TYPE but does a type check only in interpreted
code (no type check is done in compiled code - but see the EXT:ETHE
macro) and does not allow interactive error correction by the user.
Constant LAMBDA-LIST-KEYWORDS. (&OPTIONAL &REST &KEY &ALLOW-OTHER-KEYS
&AUX &BODY &WHOLE &ENVIRONMENT)
SYMBOL-FUNCTION(
requires SETF (SYMBOL-FUNCTION symbol) object)object to be either a FUNCTION, a SYMBOL-FUNCTION
return value, or a lambda expression. The lambda expression is thereby
immediately converted to a FUNCTION.
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))))
See also Section 3.2.2.2, “Minimal Compilation ”.
Function EXT:ARGLIST. Function ( returns the lambda list of
the function or macro that EXT:ARGLIST name)name names and SIGNALs an ERROR if name is
not FBOUNDP. It also SIGNALs an ERROR when the macro lambda list is not
available due to the compiler optimization settings
(see Section 3.3.6, “Declaration SPACE”).
Variable CUSTOM:*SUPPRESS-CHECK-REDEFINITION*. When CUSTOM:*SUPPRESS-CHECK-REDEFINITION* is NIL,
CLISP issues a WARNING when a function (macro, variable, class,
etc) is redefined in a different file than its original definition.
It is not a good idea to set this variable to T.
Variable CUSTOM:*DEFUN-ACCEPT-SPECIALIZED-LAMBDA-LIST*. When CUSTOM:*DEFUN-ACCEPT-SPECIALIZED-LAMBDA-LIST* is
non-NIL, DEFUN accepts specialized lambda lists, converting type-parameter
associations to type declarations:
(defun f ((x list) (y integer)) ...)
is equivalent to
(defun f (x y) (declare (type list x) (type integer y)) ...)
This extension is disabled by -ansi and by setting CUSTOM:*ANSI* to T,
but can be re-enabled by setting CUSTOM:*DEFUN-ACCEPT-SPECIALIZED-LAMBDA-LIST* explicitly.
Compiler macros are expanded in the compiled code only, and ignored by the interpreter.
When a DEFUN form is EVALuated, the macros used there are
expanded, so they must be already defined, and their (re)definition
does not affect functions which are already defined.
This means that even the interpreted code is minimally compiled in CLISP.
Non-conforming code that does not follow the rule
“Special proclamations for dynamic variables must be made in the compilation environment.”
can produce quite unexpected results, e.g., observable differences between compiled and interpreted programs:
(defun adder-c (value) (declare ((COMPILE))) (lambda (x) (+ x value))) ⇒ADDER-C; compiled function;valueis lexical (defun adder-i (value) (lambda (x) (+ x value))) ⇒ADDER-I; interpreted function;valueis lexical (setq add-c-10 (adder-c 10)) ⇒ADD-C-10; compiled function (setq add-i-10 (adder-i 10)) ⇒ADD-I-10; interpreted function (funcall add-c-10 32) ⇒42; as expected (funcall add-i-10 32) ⇒42; as expected (defvar value 12) ⇒VALUE; affectsADDER-IandADD-I-10but notADDER-CandADD-C-10(funcall add-c-10 32) ⇒42; as before (funcall add-i-10 32) ⇒44;valueis now dynamic!
Non-conformance. The code shown above has a SPECIAL proclamation (by DEFVAR)
for the variable value in the execution environment
(before the last two FUNCALLs)
but not in the compilation environment: at the moment
the ADDER-I function is defined,
value is not known to be a SPECIAL variable.
Therefore the code is not conforming.
The function ADD-C-10 was compiled before
value was declared SPECIAL, so the symbol value was
eliminated from its code and the SPECIAL declaration did
not affect the return value (i.e., (funcall
add-c-10 32) always returned 42).
On the opposite, function ADDER-I was not
compiled, so ADD-I-10
was interpreted.
Whenever ADD-I-10 is executed, its definition is
interpreted all over again. Before DEFVAR, value is evaluated as
a lexical (because is is not declared SPECIAL yet), but after
DEFVAR, we see a globally SPECIAL symbol value which
can have only a global SYMBOL-VALUE (not a local binding), and thus
we are compelled to evaluate it to 12.
This behavior was implemented intentionally to ease interactive
development, because usually
the ADDER-I above would be followed by a
(forgotten) DEFVAR.
When a user compiles a program, the compiler is allowed to
remember the information whether a variable was SPECIAL or not,
because that allows the compiler to generate more efficient code,
but in interpreted code, when the user changes the state of a variable,
he does not want to re-evaluate all DEFUNs that use the variable.
[ANSI CL standard] gives the implementation freedom regarding interpreted evaluation, how much it wants to remember / cache, and how much it wants to re-evaluate according the current environment, if it has changed. CLISP implements ad-hoc look-up for variables (but not for macros, see Section 3.2.2.2, “Minimal Compilation ”).
Hash tables are externalizable objects.
The declarations (,
TYPE type variable ...)(,
are ignored by both the interpreter and the compiler.FTYPE type function ...)
SPECIALDeclaration EXT:NOTSPECIAL. Declarations (
and PROCLAIM '(SPECIAL variable))DEFCONSTANT are undone by the ( declaration. This declaration can be used only in
global PROCLAIM '(EXT:NOTSPECIAL
variable))PROCLAIM and DECLAIM forms, not in local DECLARE forms.
You cannot expect miracles: functions compiled before
the EXT:NOTSPECIAL proclamation was issued will still be treating variable as
special even after the EXT:NOTSPECIAL proclamation. See also
Section 3.2.2.3, “Semantic Constraints
”.
Function EXT:SPECIAL-VARIABLE-P. You can use the function ( to check whether the symbol is a
special variable. EXT:SPECIAL-VARIABLE-P symbol
&OPTIONAL environment)environment of NIL or omitted means use the global environment.
You can also obtain the current lexical environment using the macro
EXT:THE-ENVIRONMENT (interpreted code only).
This function will always return T for global special
variables and constant variables.
EXT:CONSTANT-NOTINLINEConstants defined by DEFCONSTANT but proclaimed EXT:CONSTANT-NOTINLINE
will not be inlined by the compiler. This is useful for variables
which remain constant within an a single Lisp process but may vary
between processes and machines (such as endianness or word size) thus
they should be written to #P".fas"s as symbols, not values.
CONSTANTPFunction CONSTANTP fully complies with [ANSI CL standard].
Additionally, some non-trivial forms are identified as constants, e.g.,
( returns CONSTANTP '(+ 1 2 3))T.
Since DEFCONSTANT initial value forms are not
evaluated at compile time, CONSTANTP will not report T of their
name within the same compilation unit for the null lexical environment.
This is consistent and matches questionable code using the pattern
(.
Use IF (CONSTANTP form) (EVAL form))EVAL-WHEN if you need recognition and the value during
compile-time. See also Section 31.11.5, “Macro EXT:COMPILE-TIME-VALUE”.
SAFETYDeclaration (
results in “safe” compiled code: function calls are never
eliminated. This guarantees the semantics described in
[sec_3-5].
OPTIMIZE (SAFETY 3))
(COMPILE)The declaration (COMPILE) has the effect that the current
form is compiled prior to execution. Examples:
(LOCALLY(DECLARE(compile))form)
executes the compiled version of form.
(LET((x 0)) (FLET((inc () (DECLARE(compile)) (INCFx)) (dec () (DECFx))) (VALUES#'inc #'dec)))
returns two functions. The first is compiled and increments x, the
second is interpreted (slower) and decrements the same x.
SPACEThe declaration determines what metadata is recorded in the function object:
The initial value of an &AUX variable in a boa lambda list is
the value of the corresponding slot's initial form.
Table of Contents
The general form of the COMPLEX type specifier is (.
The type specifier COMPLEX type-of-real-part
type-of-imaginary-part)(
is equivalent to COMPLEX type)(.COMPLEX type
type)
DEFTYPE lambda lists are subject to destructuring (nested lambda lists
are allowed, as in DEFMACRO) and may contain a &WHOLE marker,
but not an &ENVIRONMENT marker.
Function (. If EXT:TYPE-EXPAND
type &OPTIONAL once-p)type is a user-defined type specifier this will expand it
recursively until it is no longer a user-defined type
(unless once-p is supplied and non-NIL).
Two values are returned - the expansion and an indicator (T or NIL)
of whether the original type was a user-defined type specifier.
The possible results of TYPE-OF
CONSSYMBOL, NULL, BOOLEAN,
KEYWORDBIT, (INTEGER 0
#.MOST-POSITIVE-FIXNUM),
(INTEGER
#.MOST-NEGATIVE-FIXNUM (0)),
(INTEGER
(#.MOST-POSITIVE-FIXNUM)),
(INTEGER *
(#.MOST-NEGATIVE-FIXNUM))RATIONAL, SHORT-FLOAT, SINGLE-FLOAT,
DOUBLE-FLOAT, LONG-FLOAT, COMPLEXCHARACTER, BASE-CHAR,
STANDARD-CHAR(ARRAY element-type
dimensions), (SIMPLE-ARRAY
element-type dimensions)(VECTOR T
size), (SIMPLE-VECTOR
size)(STRING
size), (SIMPLE-STRING
size)(BASE-STRING
size), (SIMPLE-BASE-STRING
size)(BIT-VECTOR
size), (SIMPLE-BIT-VECTOR
size)FUNCTION, COMPILED-FUNCTION,
STANDARD-GENERIC-FUNCTIONSTREAM, FILE-STREAM, SYNONYM-STREAM,
BROADCAST-STREAM, CONCATENATED-STREAM, TWO-WAY-STREAM,
ECHO-STREAM, STRING-STREAMPACKAGE, HASH-TABLE, READTABLE, PATHNAME,
LOGICAL-PATHNAME, RANDOM-STATE, BYTESPECIAL-OPERATOR,
LOAD-TIME-EVAL, SYMBOL-MACRO,
GLOBAL-SYMBOL-MACRO, EXT:ENCODING,
FFI:FOREIGN-POINTER, FFI:FOREIGN-ADDRESS, FFI:FOREIGN-VARIABLE,
FFI:FOREIGN-FUNCTIONEXT:WEAK-POINTER, EXT:WEAK-LIST, EXT:WEAK-AND-RELATION,
EXT:WEAK-OR-RELATION, EXT:WEAK-MAPPING, EXT:WEAK-AND-MAPPING,
EXT:WEAK-OR-MAPPING, EXT:WEAK-ALIST,
READ-LABEL,
FRAME-POINTER,
SYSTEM-INTERNALADDRESS (should not
occur)SYMBOL (structure types or CLOS
classes)Function COERCE. FIXNUM is not a character
designator in [ANSI CL standard], although CODE-CHAR provides an
obvious venue to COERCE a FIXNUM to a CHARACTER.
When CUSTOM:*COERCE-FIXNUM-CHAR-ANSI* is NIL, CLISP COERCEs FIXNUMs to
CHARACTERs via CODE-CHAR.
When CUSTOM:*COERCE-FIXNUM-CHAR-ANSI* is non-NIL, FIXNUMs cannot be
COERCEd to CHARACTERs.
The CLOS symbols are EXPORTed from the package “CLOS”.
“COMMON-LISP” uses (as in USE-PACKAGE) “CLOS” and EXT:RE-EXPORTs the
[ANSI CL standard] standard exported symbols (the CLISP extensions, e.g.,
those described in Chapter 29, Meta-Object Protocol, are not EXT:RE-EXPORTed).
Since the default :USE argument
to MAKE-PACKAGE is “COMMON-LISP”, the standard CLOS symbols are normally
visible in all user-defined packages.
If you do not want them (for example, if you want to use the
PCL
implementation of CLOS instead of the native one), do the following:
(DEFPACKAGE"CL-NO-CLOS" (:use "CL")) (DO-EXTERNAL-SYMBOLS(symbol“COMMON-LISP”) (SHADOWsymbol"CL-NO-CLOS")) (DO-SYMBOLS(symbol"CL-NO-CLOS") (EXPORTsymbol"CL-NO-CLOS")) (IN-PACKAGE"CL-NO-CLOS") (LOAD"pcl") ; or whatever (DEFPACKAGE"MY-USER" (:use "CL-NO-CLOS")) (IN-PACKAGE"MY-USER") ;; your code which uses PCL goes here
DEFCLASS supports the option :METACLASS STRUCTURE-CLASS.
This option is necessary in order to define a subclass of a
DEFSTRUCT-defined structure type using DEFCLASS instead of
DEFSTRUCT.
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 enforced by the implementation only in
interpreted code.
CLOS:GENERIC-FLET and
CLOS:GENERIC-LABELS
are implemented as macros, not as special operators (as permitted by
[sec_3-1-2-1-2-2]).
They are not imported into the packages “COMMON-LISP-USER” and “COMMON-LISP” because
of the [ANSI CL standard] issue GENERIC-FLET-POORLY-DESIGNED:DELETE.
PRINT-OBJECT is only called on objects of type
STANDARD-OBJECT and STRUCTURE-OBJECT.
It is not called on other objects, like CONSes
and NUMBERs, due to the performance concerns.
Among those classes listed in Figure
4-8, only the following are instances of BUILT-IN-CLASS:
TCHARACTERNUMBER, COMPLEX, REAL, FLOAT,
RATIONAL, RATIO, INTEGERSEQUENCEARRAY, VECTOR, BIT-VECTOR,
STRINGLIST, CONSSYMBOL, NULLFUNCTIONHASH-TABLEPACKAGEPATHNAME, LOGICAL-PATHNAMERANDOM-STATEREADTABLESTREAM, BROADCAST-STREAM,
CONCATENATED-STREAM, ECHO-STREAM, STRING-STREAM,
FILE-STREAM, SYNONYM-STREAM, TWO-WAY-STREAM
DEFCLASS supports the :METACLASS option. Possible values are
STANDARD-CLASS (the default), STRUCTURE-CLASS (which creates
structure classes, like DEFSTRUCT does), and user-defined
meta-classes (see Section 29.3.6.7, “Generic Function CLOS:VALIDATE-SUPERCLASS”).
It is not required that the superclasses of a class are
defined before the DEFCLASS form for the class is evaluated.
Use Meta-Object Protocol generic functions CLOS:CLASS-FINALIZED-P to check whether the
class has been finalized and thus its instances can be created,
and CLOS:FINALIZE-INHERITANCE to force class finalization.
See also Section 29.3.1, “Macro DEFCLASS”.
Trivial changes, e.g., those that can occur when doubly loading
the same code, do not require updating the instances.
These are the changes that do not modify the set of local slots
accessible in instances, e.g., changes to slot options :INITFORM,
:DOCUMENTATION, and changes to class options
:DEFAULT-INITARGS, :DOCUMENTATION.
The instances are updated when they are first accessed, not at
the time when the class is redefined or MAKE-INSTANCES-OBSOLETE is
called. When the class has been redefined several times since the
instance was last accessed, UPDATE-INSTANCE-FOR-REDEFINED-CLASS is
still called just once.
Table of Contents
&KEY markers in DEFSETF lambda lists are supported, but the
corresponding keywords must appear literally in the program text.
An attempt to modify read-only data SIGNALs an ERROR.
Program text and quoted constants loaded from files are considered
read-only data. This check is only performed for strings, not for
conses, other kinds of arrays, and user-defined data types.
(,
GET-SETF-EXPANSION form &OPTIONAL environment)(EXT:GET-SETF-METHOD , and
form &OPTIONAL environment)(EXT:GET-SETF-METHOD-MULTIPLE-VALUE receive as optional argument form &OPTIONAL
environment)environment the environment
necessary for macro expansions. In DEFINE-SETF-EXPANDER
and EXT: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-EXPANSION, EXT:GET-SETF-METHOD and
EXT:GET-SETF-METHOD-MULTIPLE-VALUE. If this is
done, even local macros will be interpreted as places correctly.
Additional places:
FUNCALL(SETF (FUNCALL #'symbol ...)
object) and
(SETF (FUNCALL 'symbol ...) object)
are equivalent to (SETF (symbol ...) object).
PROGN(SETF (PROGN form ... place)
object)LOCALLY(SETF (LOCALLY declaration ...
form ... place) object)
IF(SETF (IF condition
place1
place2)
object)GET-DISPATCH-MACRO-CHARACTER(SETF (GET-DISPATCH-MACRO-CHARACTER ...)
...) calls SET-DISPATCH-MACRO-CHARACTER.
EXT:LONG-FLOAT-DIGITS:(SETF (EXT:LONG-FLOAT-DIGITS) digits) sets the
default mantissa length of LONG-FLOATs to digits bits.
VALUES-LIST(
is equivalent to SETF (VALUES-LIST list) form)(.VALUES-LIST (SETF list
(MULTIPLE-VALUE-LIST form)))
FUNCTION-LAMBDA-EXPRESSIONThe name of a FFI:FOREIGN-FUNCTION is a string
(the name of the underlying C function), not a lisp function name.
DESTRUCTURING-BINDThis macro does not perform full error checking.
PROG1, PROG2, AND,
OR, PSETQ, WHEN, UNLESS, COND, CASE, MULTIPLE-VALUE-LIST,
MULTIPLE-VALUE-BIND, MULTIPLE-VALUE-SETQThese macros are implemented as special operators (as permitted by [sec_3-1-2-1-2-2]) and, as such, are rather efficient.
DEFCONSTANTThe initial value is not evaluated at compile time,
just like with DEFVAR and DEFPARAMETER.
Use EVAL-WHEN if you need the value at compile time.
constant variables may not be bound dynamically or lexically.
See also Section 3.3.2, “Declaration EXT:CONSTANT-NOTINLINE”.
If you need to undo the effects of a DEFCONSTANT form,
PROCLAIM the symbol SPECIAL (to turn the constant variable into a dynamic variable),
and then PROCLAIM it EXT:NOTSPECIAL (to turn the dynamic variable into a lexical variable).
If you follow the usual variable naming convention
(*FOO* for DEFVAR and DEFPARAMETER,
+BAR+ for DEFCONSTANT, ZOT
for LET/LET*), you will save yourself a lot of trouble.
See also Q: A.4.14.
CUSTOM:*SUPPRESS-SIMILAR-CONSTANT-REDEFINITION-WARNING*If the variable being defined by DEFCONSTANT is already bound to
a value which is not EQL to the new value, a WARNING is issued.
If, however, the new value is visually similar
(prints to the same string, as is commonly the case when re-loading files)
to the old one, the warning can be suppressed by setting
CUSTOM:*SUPPRESS-SIMILAR-CONSTANT-REDEFINITION-WARNING* to a non-NIL value.
The initial value of CUSTOM:*SUPPRESS-SIMILAR-CONSTANT-REDEFINITION-WARNING* is
NIL.
EXT:FCASEThis macro allows specifying the test for CASE, e.g.,
(fcase string= (subseq foo 0 (position #\Space foo))
("first" 1)
(("second" "two") 2)
(("true" "yes") t)
(otherwise nil))
is the same as
(let ((var (subseq foo 0 (position #\Space foo))))
(cond ((string= var "first") 1)
((or (string= var "second") (string= var "two")) 2)
((or (string= var "true") (string= var "yes")) t)
(t nil)))
If you use a built-in HASH-TABLE test (see Section 18.4, “Function HASH-TABLE-TEST”)
as the test (e.g., EQUAL instead of STRING= above, but not a test
defined using EXT:DEFINE-HASH-TABLE-TEST), the compiler will be able to optimize the
EXT:FCASE form better than the corresponding COND form.
This function checks that exactly one of its arguments is non-NIL
and, if this is the case, returns its value and index in the argument
list as multiple values, otherwise returns NIL.
EQEQ compares CHARACTERs and FIXNUMs as EQL does.
No unnecessary copies are made of CHARACTERs and NUMBERs.
Nevertheless, one should use EQL as it is more portable across Common Lisp
implementations.
( always
returns LET ((x y)) (EQ x x))T for any Lisp object y.
See also Equality of foreign values.
FUNCTION( returns the local function
definition established by FUNCTION symbol)FLET or LABELS, if it exists, otherwise
the global function definition.
( returns SPECIAL-OPERATOR-P symbol)NIL or
T. If it returns T, then ( returns the (useless) special operator handler.SYMBOL-FUNCTION
symbol)
Table of Contents
The standard is unambiguous in that the iteration variables do
still exist in the
FINALLY
clause, but not as to what values these variables might have.
Therefore the code which relies on the values of such variables, e.g.,
(loop for x on y finally (return x))
is inherently non-portable across Common Lisp implementations, and should be avoided.
There have been some tightening in the LOOP syntax between
[CLtL2] and [ANSI CL standard], e.g., the following form is legal in the
former but not the latter:
(loop initially for i from 1 to 5 do (print i) finally return i)
When CUSTOM:*LOOP-ANSI* is NIL, such forms are still
accepted in CLISP but elicit a warning at macro-expansion time.
When CUSTOM:*LOOP-ANSI* is non-NIL, an ERROR is SIGNALed.
Table of Contents
Generic function
CLOS:NO-PRIMARY-METHOD
(similar to NO-APPLICABLE-METHOD) is called when there is an
applicable method but no applicable primary
method.
The default methods for CLOS:NO-PRIMARY-METHOD, NO-APPLICABLE-METHOD and
NO-NEXT-METHOD SIGNAL an ERROR of type
CLOS:METHOD-CALL-ERROR
.
You can find out more information about the error using functions
CLOS:METHOD-CALL-ERROR-GENERIC-FUNCTION,
CLOS:METHOD-CALL-ERROR-ARGUMENT-LIST, and
(only for NO-NEXT-METHOD)
CLOS:METHOD-CALL-ERROR-METHOD.
Moreover, when the generic function has only one dispatching
argument, (i.e., such an argument that not all the
corresponding parameter specializers are T), an ERROR of type
CLOS:METHOD-CALL-TYPE-ERROR
is SIGNALed, additionally making TYPE-ERROR-DATUM and
TYPE-ERROR-EXPECTED-TYPE available.
Table of Contents
DEFSTRUCTThe :PRINT-FUNCTION option should contain a lambda expression
(
This lambda expression names a LAMBDA (object stream depth) (declare (ignore depth)) ...)FUNCTION whose task is to output the
external representation of the STRUCTURE-OBJECT object onto the
STREAM 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:
*PRINT-ESCAPE* must be
respected.*PRINT-PRETTY* is up to you.
*PRINT-CIRCLE* need not be
respected. This is managed by the system. (But the print-circle
mechanism handles only those objects that are direct or indirect
components of the structure.)*PRINT-LEVEL* is respected by
WRITE, PRIN1, PRINC, PRINT, PPRINT, FORMAT instructions
~A, ~S, ~W, and FORMAT instructions
~R, ~D, ~B, ~O, ~X, ~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.)*PRINT-LENGTH* must be respected,
especially if you are outputting an arbitrary number of components.
*PRINT-READABLY* must be
respected. Remember that the values of *PRINT-ESCAPE*,
*PRINT-LEVEL*, *PRINT-LENGTH* are ignored if
*PRINT-READABLY* is true. The value of *PRINT-READABLY* is
respected by PRINT-UNREADABLE-OBJECT, WRITE, PRIN1, PRINC,
PRINT, PPRINT, FORMAT instructions ~A, ~S,
~W, and FORMAT instructions ~R, ~D,
~B, ~O, ~X, ~F, ~E,
~G, ~$ with not-numerical arguments. Therefore
*PRINT-READABLY* will be respected automatically if only these
functions are used for printing objects.*PRINT-BASE*, *PRINT-RADIX*, *PRINT-CASE*,
*PRINT-GENSYM*, *PRINT-ARRAY*, CUSTOM:*PRINT-CLOSURE*,
CUSTOM:*PRINT-RPARS*, CUSTOM:*PRINT-INDENT-LISTS*.The :INHERIT option is exactly like :INCLUDE except that it
does not create new accessors for the inherited slots (this is a
CLISP extension).
The following functions accept a structure name as the only argument.
If DEFSTRUCT was given the :TYPE option (i.e., DEFSTRUCT did
not define a new type), then (
fails (and the regular CLOS Meta-Object Protocol is not applicable), but these
functions still work.FIND-CLASS name)
EXT:STRUCTURE-SLOTSLIST of effective slot definition metaobjects.
EXT:STRUCTURE-DIRECT-SLOTSLIST of direct slot definition metaobjects.
EXT:STRUCTURE-KEYWORD-CONSTRUCTORSYMBOL) of the keyword
constructor function for the structure, or NIL if the structure has
no keyword constructor.EXT:STRUCTURE-BOA-CONSTRUCTORSLIST of names (SYMBOLs)
of BOA constructors for the structure.EXT:STRUCTURE-COPIERSYMBOL) of the copier for the
structure.EXT:STRUCTURE-PREDICATESYMBOL) of the predicate for
the structure.Table of Contents
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.
The error message prefix for the first line is “*** - ”.
All subsequent lines are indented by 6 characters.
Long lines are broken on whitespace
(see Section 30.8, “Class EXT:FILL-STREAM”).
Contrary to the recommendation of the standard, CLISP usually
does print the name of the containing function to simplify debugging
in batch mode, see EXT:EXIT-ON-ERROR.
Macro RESTART-CASE. In (,
the argument list can also be specified after the keyword/value pairs
instead of before them, i.e., each RESTART-CASE form {restart-clause}*)restart-clause can be either
(
or restart-name EXT:*ARGS*
{keyword-value-pair}* {form}*)(.
restart-name
{keyword-value-pair}* EXT:*ARGS* {form}*)
Macro EXT:WITH-RESTARTS. The macro EXT: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 with any CONDITION.
( is
therefore equivalent to EXT:WITH-RESTARTS ({restart-clause}*) {form}*)(.RESTART-CASE (PROGN {form}*)
{restart-clause}*)
Function COMPUTE-RESTARTS. COMPUTE-RESTARTS and FIND-RESTART behave as specified in
[ANSI CL standard]: If the optional condition argument is non-NIL,
only RESTARTs associated with that CONDITION
and RESTARTs associated with 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.
Macro EXT:MUFFLE-CERRORS. The macro (
executes the EXT:MUFFLE-CERRORS {form}*)forms; when a continuable ERROR occurs whose CONTINUE RESTART
can be invoked non-interactively (this includes all continuable ERRORs signaled
by the function CERROR), no message is printed, instead, the CONTINUE
RESTART is invoked.
Macro EXT:APPEASE-CERRORS. The macro (
executes the EXT:APPEASE-CERRORS {form}*)forms; when a continuable ERROR occurs whose CONTINUE RESTART
can be invoked non-interactively (this includes all continuable ERRORs SIGNALed
by the function CERROR), it is reported as a WARNING, and the
CONTINUE RESTART is invoked.
Macro EXT:ABORT-ON-ERROR. The macro (
executes the EXT:ABORT-ON-ERROR {form}*)forms; when an ERROR occurs, or when a Control+C
interrupt occurs, the error message is printed and the ABORT
RESTART is invoked.
Macro EXT:EXIT-ON-ERROR. The macro (
executes the EXT:EXIT-ON-ERROR {form}*)forms; when an ERROR occurs, or when a Control+C
interrupt occurs, the error message is printed and CLISP terminates
with an error status.
Variable CUSTOM:*REPORT-ERROR-PRINT-BACKTRACE*. When this variable is non-NIL the error message printed by
EXT:ABORT-ON-ERROR and EXT:EXIT-ON-ERROR includes the backtrace (stack).
Function EXT:SET-GLOBAL-HANDLER. The function (
establishes a global handler for the EXT:SET-GLOBAL-HANDLER condition handler)condition.
The handler should be FUNCALLable (a
SYMBOL or a FUNCTION). If it returns, the next applicable
handler is invoked, so if you do not want to land in the debugger,
it should not return.
E.g., the option -on-error abort and the macro
EXT:ABORT-ON-ERROR are implemented by installing the following handler:
(defun sys::abortonerror (condition) (sys::report-error condition) (INVOKE-RESTART(FIND-RESTART'ABORTcondition)))
When handler is NIL, the handler
for condition is removed and returned.
When condition is also NIL, all global handlers are removed and returned
as a LIST, which can then be passed to EXT:SET-GLOBAL-HANDLER as the
first argument and the handlers re-established.
Macro EXT:WITHOUT-GLOBAL-HANDLERS. The macro ( removes all global handlers, executes EXT:WITHOUT-GLOBAL-HANDLERS &BODY
body)body, and
then restores the handlers.
No notes.
Table of Contents
The [ANSI CL standard] packages present in CLISP
MAKE-PACKAGEThe default value of the :USE argument is
(“COMMON-LISP”).
MAKE-PACKAGE accepts additional keyword arguments
:CASE-SENSITIVE and :CASE-INVERTED (but not :MODERN!)
DEFPACKAGEDEFPACKAGE accepts additional options :CASE-SENSITIVE,
:CASE-INVERTED, and :MODERN.
When the package being defined already exists, it is modified as follows (and in this order):
:CASE-SENSITIVE(SETF EXT:PACKAGE-CASE-SENSITIVE-P)
(with a warning):CASE-INVERTED(SETF EXT:PACKAGE-CASE-INVERTED-P)
(with a warning):MODERNif “COMMON-LISP” is being used, it is un-used and
“CS-COMMON-LISP” is used instead; also, “CS-COMMON-LISP” is used instead of “COMMON-LISP”
throughout the DEFPACKAGE form, e.g.,
(DEFPACKAGE"FOO" (:MODERNT) (:USE"COMMON-LISP" "EXT"))
is equivalent to
(DEFPACKAGE"FOO" (:CASE-SENSITIVET) (:CASE-INVERTEDT) (:USE"CS-COMMON-LISP" "EXT"))
:NICKNAMESRENAME-PACKAGE
:DOCUMENTATION(SETF
DOCUMENTATION):SHADOWSHADOW
:SHADOWING-IMPORT-FROMSHADOWING-IMPORT
:USEUSE-PACKAGE and UNUSE-PACKAGE
:IMPORT-FROMIMPORT
:INTERNINTERN (but not UNINTERN)
:EXPORTINTERN and EXPORT (but not
UNEXPORT):SIZEEXT:RE-EXPORTThe function ( re-EXT:RE-EXPORT FROM-PACK
TO-PACK)EXPORTs all external
SYMBOLs from FROM-PACK also from
TO-PACK, provided it already uses
FROM-PACK; and SIGNALs an ERROR otherwise.
EXT:PACKAGE-CASE-INVERTED-PReturns T if the argument is a
case-inverted package.
This function is SETFable, although it is probably not a good idea
to change the case-inverted status of an existing package.
EXT:PACKAGE-CASE-SENSITIVE-PReturns T if the argument is a
case-sensitive package.
This function is SETFable, although it is probably not a good idea
to change the case-sensitive status of an existing package.
Function EXT:PACKAGE-LOCK.
Packages can be “locked”.
When a package is locked, attempts to change its symbol table or
redefine functions which its symbols name result in a continuable ERROR
(continuing overrides locking for this operation).
When CUSTOM:*SUPPRESS-CHECK-REDEFINITION* is T (not a good idea!), the ERROR
is not SIGNALed for redefine operations.
Function (
returns the generalized boolean indicating whether the EXT:PACKAGE-LOCK package)package is locked.
A package (or a list thereof) can be locked using (.
CLISP locks its system packages (specified in the variable
SETF
(EXT:PACKAGE-LOCK package-or-list) T)CUSTOM:*SYSTEM-PACKAGE-LIST*).
Macro EXT:WITHOUT-PACKAGE-LOCK. If you want to evaluate some forms with certain packages unlocked,
you can use
EXT:WITHOUT-PACKAGE-LOCK
:
(EXT:WITHOUT-PACKAGE-LOCK (“COMMON-LISP” “EXT” “CLOS”)
(defun restart () ...))
or
(EXT:WITHOUT-PACKAGE-LOCK (“COMMON-LISP”) (trace read-line))
(
temporarily unlocks all packages in EXT:WITHOUT-PACKAGE-LOCK () ...)CUSTOM:*SYSTEM-PACKAGE-LIST*.
Variable CUSTOM:*SYSTEM-PACKAGE-LIST*. This variable specifies the default packages to be locked by EXT:SAVEINITMEM
and unlocked by EXT:WITHOUT-PACKAGE-LOCK as a list of package names.
You may add names to this list, e.g., a module will add its package,
but you should not remove CLISP internal packages from this list.
Discussion - see also the USENET posting by . This should prevent you from accidentally hosing yourself with
(DEFSTRUCT instance ...)
and allow enforcing modularity.
Note that you will also get the continuable ERROR when you try to
assign (with SETQ, PSETQ, etc.) a value to an internal special
variable living in a locked package and not accessible in your current
*PACKAGE*, but only in the interpreted code and during compilation.
There is no check for package locks in compiled code because of the
performance considerations.
The “COMMON-LISP-USER” package uses the “COMMON-LISP” and “EXT” packages.
The following additional packages exist:
Implementation-Defined Packages
EXPORTs all CLOS-specific symbols, including some
additional symbols.
EXPORTed symbols. It defines many system internals.
EXT:RE-EXPORTs
all the external symbols in all CLISP extensions, so a simple
(USE-PACKAGE "EXT") is enough to
make all the extensions available in the current package.
This package uses packages (in addition to “COMMON-LISP”):
“POSIX”, “SOCKET”, “GSTREAM”, “GRAY”,
“I18N”, “CUSTOM”.EXPORTs some character sets, for use with
EXT:MAKE-ENCODING and as :EXTERNAL-FORMAT argument.
All pre-existing packages except “COMMON-LISP-USER” belong to the implementation, in the sense that the programs that do not follow [sec_11-1-2-1-2] (“Constraints on the ‘COMMON-LISP’ Package for Conforming Programs”) cause undefined behavior.
CLISP supports programs written with case sensitive symbols. For
example, with case sensitive symbols, the symbols cdr
(the function equivalent to REST) and the symbol CDR
(a user-defined type denoting a Call Data Record) are different and unrelated.
There are some incompatibilities between programs assuming case
sensitive symbols and programs assuming the [ANSI CL standard] case insensitive symbols.
For example, (eq 'KB 'Kb) evaluates to false in a case
sensitive world and to true in a case insensitive world. However, unlike some
commercial Common Lisp implementations, CLISP allows both kinds of programs to
coexist in the same process and interoperate with each other. Example:
OLD.lisp(IN-PACKAGE"OLD") (DEFUNFOO () ...)
modern.lisp
(in-package "NEW")
(defun bar () (old:foo))
(symbol-name 'bar) ; ⇒ "bar"
This is achieved through specification of the symbol case policy at the package level. A modern package is one that is declared to be both case-sensitive and case-inverted and which use the symbols from the “CS-COMMON-LISP” package.
A case-sensitive package
is one whose DEFPACKAGE declaration (or MAKE-PACKAGE
creation form) has the option (.
In a case-sensitive package, the reader does not uppercase the
symbol name before calling :CASE-SENSITIVE T)INTERN. Similarly, the printer, when
printing the SYMBOL-NAME part of a SYMBOL (i.e. the part after
the package markers), behaves as if the readtable's case were set
to :PRESERVE.
See also Section 11.1.5, “Function EXT:PACKAGE-CASE-SENSITIVE-P”.
A case-inverted package
is one whose DEFPACKAGE declaration (or MAKE-PACKAGE
creation form) has the option (.
In the context of a case-inverted package, symbol names are
case-inverted: upper case characters are mapped to lower case, lower
case characters are mapped to upper case, and other characters are left
untouched. Every symbol thus conceptually has two symbol names: an
old-world symbol name and a modern-world symbol name, which is the
case-inverted old-world name. The first symbol name is returned by the
function :CASE-INVERTED T)SYMBOL-NAME, the modern one by the
function cs-cl:symbol-name. The internal
functions for creating or looking up symbols in a package, which
traditionally took a string argument, now conceptually take two string
arguments: old-style-string and inverted-string. Actually, a function
like INTERN takes the old-style-string as argument and computes the
inverted-string from it; whereas the
function cs-cl:intern takes the inverted-string as
argument and computes the old-style-string from it.
See also Section 11.1.4, “Function EXT:PACKAGE-CASE-INVERTED-P”.
For a few built-in functions, a variant for the case-inverted world is defined in the “CS-COMMON-LISP” package, which has the nickname “CS-CL”:
cs-cl:symbol-namecs-cl:interncs-cl:find-symbolcs-cl:symbol-name.cs-cl:shadowcs-cl:find-all-symbolscs-cl:string=cs-cl:string/=cs-cl:string<cs-cl:string>cs-cl:string<=cs-cl:string>=cs-cl:string-trimcs-cl:string-left-trimcs-cl:string-right-trimSYMBOL to a STRING and therefore
exist in a variant that uses cs-cl:symbol-name
instead of SYMBOL-NAME.cs-cl:make-packagePACKAGE.
A package “CS-COMMON-LISP-USER” is provided for the user to modify and work in. It plays the same role as “COMMON-LISP-USER”, but for the case-sensitive world.
The handling of package names is unchanged. Package names are
still usually uppercase. The package names are also subject to
(.READTABLE-CASE *READTABLE*)
Note that gensyms and keywords are still treated traditionally: even in a case-sensitive package,
(STRING='#:FooBar '#:foobar) ⇒(TEQ':KeyWord ':keyword) ⇒T
We believe this has a limited negative impact for the moment, but can be changed some time in the future.
The following practices will pose no problems when migrating to a modern case-sensitive world:
(STRING= (SYMBOL-NAME x) (SYMBOL-NAME y)).
The following practices will not work in a case-sensitive world or can give problems:
SYMBOL-NAME return values with EQ.
(SYMBOL-NAME x) with
(cs-cl:symbol-name y).CLISP supports a command-line option -modern that
sets the *PACKAGE* initially to the “CS-COMMON-LISP-USER” package, and
*PRINT-CASE* to :DOWNCASE.
For packages to be located in the “modern”
(case-sensitive) world, you need to augment their DEFPACKAGE
declaration by adding the option (,
see Section 11.1.2, “Macro :MODERN T)DEFPACKAGE”.
Table of Contents
The type NUMBER is the disjoint union of the types
REAL and COMPLEX (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.
Function EXT:! ( returns the
factorial of EXT:! n)n, n being a nonnegative INTEGER.
Function EXT:EXQUO. ( returns
the integer quotient EXT:EXQUO x y)x/y of two integers
x,y, and SIGNALs an ERROR when the quotient is not
integer. (This is more efficient than /.)
Function EXT:XGCD. (
returns the values EXT:XGCD x1 ... xn)l, k1, ..., kn, where l is the
greatest common divisor of the integers x1, ..., xn, and
k1, ..., kn are the integer coefficients such that
l= (GCDx1...xn) = (+ (*k1x1) ... (*knxn))
Function EXT:MOD-EXPT. (
is equivalent to EXT:MOD-EXPT k l m)(
except it is more efficient for very large arguments.MOD (EXPT k l) m)
DECODE-FLOATFLOAT-RADIX always returns 2.
( coerces
FLOAT-DIGITS number digits)number (a REAL) to a floating point number with at least
digits mantissa digits. The following always evaluates to T:
(>=(FLOAT-DIGITS(FLOAT-DIGITSnumberdigits))digits)
Byte specifiers are objects of built-in type BYTE,
not INTEGERs.
Function EXPT. (
is not very precise if EXPT base exponent)exponent has a large
absolute value.
Function LOG. ( LOG number base)SIGNALs an ERROR if
.base = 1
Constant PI. The value of PI is a LONG-FLOAT with the precision given
by (. When this precision is changed, the value of EXT:LONG-FLOAT-DIGITS)PI is
automatically recomputed. Therefore PI is not a constant variable.
Function UPGRADED-COMPLEX-PART-TYPE. When the argument is not a recognizable subtype or REAL,
UPGRADED-COMPLEX-PART-TYPE SIGNALs an ERROR, otherwise it
returns its argument (even though a COMPLEX number in CLISP can
always have REALPART and IMAGPART of any type) because it allows
the most precise type inference.
Variable CUSTOM:*DEFAULT-FLOAT-FORMAT*. 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 CUSTOM:*DEFAULT-FLOAT-FORMAT*.
See also *READ-DEFAULT-FLOAT-FORMAT*.
Macro EXT:WITHOUT-FLOATING-POINT-UNDERFLOW. The macro ( executes the
EXT:WITHOUT-FLOATING-POINT-UNDERFLOW {form}*)forms, with errors of type FLOATING-POINT-UNDERFLOW inhibited.
Floating point operations will silently return zero instead of
SIGNALing an ERROR of type FLOATING-POINT-UNDERFLOW.
Condition FLOATING-POINT-INVALID-OPERATION. This CONDITION is never SIGNALed by CLISP.
Condition FLOATING-POINT-INEXACT. This CONDITION is never SIGNALed by CLISP.
Table 12.2. Fixnum limits
| CPU type | 32-bit CPU | 64-bit CPU |
|---|---|---|
MOST-POSITIVE-FIXNUM | 224-1 = 16777215 | 248-1 = 281474976710655 |
MOST-NEGATIVE-FIXNUM | -224 = -16777216 | -248 = -281474976710656 |
BIGNUMs are limited in size. Their maximum size is
32*(216-2)=2097088 bits.
The largest representable BIGNUM is therefore
22097088-1.
Together with PI, the other LONG-FLOAT constants
are recomputed whenever ( is EXT:LONG-FLOAT-DIGITS)SETFed.
They are not constant variables.
When a mathematical function may return an exact (RATIONAL) or
inexact (FLOAT) result, it always returns the exact result.
There are four floating point types: SHORT-FLOAT,
SINGLE-FLOAT, DOUBLE-FLOAT and LONG-FLOAT:
| type | sign | mantissa | exponent | comment |
|---|---|---|---|---|
SHORT-FLOAT | 1 bit | 16+1 bits | 8 bits | immediate |
SINGLE-FLOAT | 1 bit | 23+1 bits | 8 bits | IEEE 754 |
DOUBLE-FLOAT | 1 bit | 52+1 bits | 11 bits | IEEE 754 |
LONG-FLOAT | 1 bit | >=64 bits | 32 bits | variable length |
The single and double float formats are those of the IEEE 754
“Standard for Binary Floating-Point Arithmetic”,
except that CLISP does not support features like
±0, ±inf,
NaN, gradual underflow, etc.
Common Lisp does not make use of these features, so, to reduce portability
problems, CLISP by design returns the same floating point results on
all platforms (CLISP has a floating-point emulation built in for
platforms that do not support IEEE 754). Note that
NaN
in your program, your program is broken, so you will spend time
determining where the NaN came from.
It is better to SIGNAL an ERROR in this case.LONG-FLOATs of
variable precision - it does not
need unnormalized floats.
This is why *FEATURES* does not contain the
:IEEE-FLOATING-POINT keyword.
Arbitrary Precision Floats. 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 (. It can be set by EXT:LONG-FLOAT-DIGITS)(,
where SETF (EXT:LONG-FLOAT-DIGITS) n)n is a positive INTEGER. E.g., ( sets the default precision of SETF (EXT:LONG-FLOAT-DIGITS)
3322)LONG-FLOATs to about
1000 decimal digits.
The floating point contagion is controlled by the variable
CUSTOM:*FLOATING-POINT-CONTAGION-ANSI*. When it is non-NIL, contagion is done as per the
[ANSI CL standard]: SHORT-FLOAT → SINGLE-FLOAT →
DOUBLE-FLOAT → LONG-FLOAT.
1.5 is actually 1.5±0.05.
Consider adding 1.5 and 1.75.
[ANSI CL standard] requires that (+ 1.5 1.75)
return 3.25, while traditional CLISP would return
3.3. The implied random variables are:
3.25±0.005 and 3.3±0.05.
Note that the traditional CLISP way does
lie about the mean: the mean is 3.25 and
nothing else, while the standard way
could be lying about the deviation
(accuracy): if the implied accuracy of 1.5 (0.05)
is its actual accuracy, then the accuracy of the result cannot be
smaller that that. Therefore, since Common Lisp has no way of knowing the
actual accuracy, [ANSI CL standard] (and all the other standard engineering
programming languages, like C, Fortran
etc) decides that keeping the accuracy correct is the business of the
programmer, while the language should preserve what it can - the precision.
E(x2) -
E(x)2 can be negative!)
The user should not mix floats of different precision (that's what
CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION* is for), but one should not be penalized for this too
harshly.When CUSTOM:*FLOATING-POINT-CONTAGION-ANSI* is NIL, the traditional CLISP method is used,
namely 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
[sec_12-1-4-4]!)
{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.
(- (+ 1.7 PI) PI)
should not return 1.700000726342836417234L0, it
should return 1.7f0 (or
1.700001f0 if there were rounding errors).
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.
If the variable CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION* is non-NIL, a WARNING is emitted for
every coercion involving different floating-point types.
As explained above, float precision contagion is not a good idea.
You can avoid the contagion by doing all your computations with the
same floating-point type (and using FLOAT to convert all constants,
e.g., PI, to your preferred type).
This variable helps you eliminate all occurrences of float
precision contagion: set it to T to have CLISP SIGNAL a
WARNING on float precision contagion; set it to ERROR to have
CLISP SIGNAL an ERROR on float precision contagion, so that you
can look at the stack backtrace.
The contagion between floating point and rational numbers is controlled
by the variable CUSTOM:*FLOATING-POINT-RATIONAL-CONTAGION-ANSI*. When it is non-NIL, contagion is done as per
the [ANSI CL standard]: RATIONAL → FLOAT.
When CUSTOM:*FLOATING-POINT-RATIONAL-CONTAGION-ANSI* is NIL, the traditional CLISP method is used,
namely if the result is mathematically an exact rational number, this
rational number is returned (in contrast to
[sec_12-1-4-1]!)
CUSTOM:*FLOATING-POINT-RATIONAL-CONTAGION-ANSI* has an effect only in those few cases when the mathematical
result is exact although one of the arguments is a floating-point number,
such as (, * 0 1.618)(,
/ 0 1.618)(, ATAN 0 1.0)(,
EXPT 2.0 0)(.PHASE 2.718)
If the variable CUSTOM:*WARN-ON-FLOATING-POINT-RATIONAL-CONTAGION* is non-NIL, a WARNING is emitted for
every avoidable coercion from a rational number to a floating-point number.
You can avoid such coercions by calling FLOAT to convert the particular
rational numbers to your preferred floating-point type.
This variable helps you eliminate all occurrences of avoidable
coercions to a floating-point number when a rational number result
would be possible: set it to T to have CLISP SIGNAL a WARNING
in such situations; set it to ERROR to have CLISP SIGNAL an
ERROR in such situations, so that you can look at the stack
backtrace.
CUSTOM:*PHASE-ANSI*A similar variable, CUSTOM:*PHASE-ANSI*, controls the return
value of PHASE when the argument is an exact nonnegative REAL.
Namely, if CUSTOM:*PHASE-ANSI* is non-NIL, it returns a floating-point zero;
if CUSTOM:*PHASE-ANSI* is NIL, it returns an exact zero. Example:
(PHASE 2/3)
Complex numbers can have a real part and an imaginary part of
different types. For example, ( evaluates to
the number SQRT -9.0),
which has a real part of exactly #C(0 3.0)0,
not only 0.0
(which would mean “approximately 0”).
The type specifier for this is (, and COMPLEX
INTEGER SINGLE-FLOAT)( in general.COMPLEX
type-of-real-part
type-of-imaginary-part)
The type specifier ( is equivalent to COMPLEX
type)(.COMPLEX
type type)
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.
This has the advantage that
( - instead of
evaluating to LET ((x (SQRT -9.0))) (* x x)),
with #C(-9.0 0.0)x = -
evaluates to #C(0.0 3.0) =
#C(-9.0 0)-9.0,
with x = .#C(0 3.0)
To ease reproducibility, the variable *RANDOM-STATE* is
initialized to the same value on each invocation, so that
$clisp -norc-x'(RANDOM1s0)'
will always print the same number.
If you want a new random state on each invocation, you can arrange for that by using init function:
$clisp -norc-x'(EXT:SAVEINITMEM"foo" :init-function (LAMBDA() (SETQ*RANDOM-STATE*(MAKE-RANDOM-STATET))))'$clisp -norc-Mfoo.mem-x'(RANDOM1s0)'
or by placing ( into your RC file.SETQ *RANDOM-STATE*
(MAKE-RANDOM-STATE T))
Table of Contents
CHAR-CODECHAR-CODE takes values from 0 (inclusive) to
CHAR-CODE-LIMIT (exclusive), i.e., the implementation
supports exactly CHAR-CODE-LIMIT characters.
Table 13.1. Number of characters
| binaries built | without UNICODE support | with UNICODE support |
|---|---|---|
CHAR-CODE-LIMIT | 28 = 256 | 17 * 216 = 1114112 |
BASE-CHARThe types EXT:STRING-CHAR and
BASE-CHAR are equivalent to CHARACTER.
EXT:STRING-CHAR used to be available as
STRING-CHAR prior to removal from [ANSI CL standard] by
CHARACTER-PROPOSAL:2.
EXT:CHAR-WIDTH( returns the number of screen
columns occupied by EXT:CHAR-WIDTH char)char. The value is
See also function EXT:STRING-WIDTH.
The characters are ordered according to a superset of the ASCII character set.
More precisely, CLISP uses the ISO Latin-1 (ISO 8859-1) character set:
| #x0 | #x1 | #x2 | #x3 | #x4 | #x5 | #x6 | #x7 | #x8 | #x9 | #xA | #xB | #xC | #xD | #xE | #xF | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| #x00 | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** |
| #x10 | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** | ** |
| #x20 | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
| #x30 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
| #x40 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
| #x50 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
| #x60 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
| #x70 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | |
| #x80 | ||||||||||||||||
| #x90 | ||||||||||||||||
| #xA0 | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ | | ® | ¯ | |
| #xB0 | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ |
| #xC0 | À | Á | Â | Ã | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï |
| #xD0 | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß |
| #xE0 | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï |
| #xF0 | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ |
Here ** are control characters, not graphic characters. (The characters left blank here cannot be represented in this character set).
Table 13.3. Semi-standard characters
| character | code |
|---|---|
| #\Backspace | #x08 |
| #\Tab | #x09 |
| #\Linefeed | #x0A |
| #\Page | #x0C |
| #\Return | #x0D |
#\Newline is the line terminator.
Table 13.5. Additional syntax for characters with code from #x00 to #x1F:
| character | code |
|---|---|
| #\^@ | #x00 |
| #\^A … #\^Z | #x01 … #x1A |
| #\^[ | #x1B |
| #\^\ | #x1C |
| #\^] | #x1D |
| #\^^ | #x1E |
| #\^_ | #x1F |
See also Section 2.6.1, “Sharpsign Backslash ”.
The only defined character script is the type CHARACTER
itself.
Characters have no implementation-defined or [CLtL1] font and bit attributes. All characters are simple characters.
For backward compatibility, there is a class SYS::INPUT-CHARACTER
representing either a character with font and bits, or a keystroke.
The following functions work with objects of types CHARACTER
and SYS::INPUT-CHARACTER.
Note that EQL or EQUAL are equivalent to EQ on objects of type
SYS::INPUT-CHARACTER.
EXT:CHAR-FONT-LIMIT = 16EXT:CHAR-BITS-LIMIT = 16Character bits:
| key | value |
|---|---|
:CONTROL | EXT:CHAR-CONTROL-BIT |
:META | EXT:CHAR-META-BIT |
:SUPER | EXT:CHAR-SUPER-BIT |
:HYPER | EXT:CHAR-HYPER-BIT |
(EXT:CHAR-FONT
object)CHARACTER or SYS::INPUT-CHARACTER.
(EXT:CHAR-BITS
object)CHARACTER or SYS::INPUT-CHARACTER.
(EXT:MAKE-CHAR
char [bits
[font]])SYS::INPUT-CHARACTER, or NIL if such a
character cannot be created.(EXT:CHAR-BIT
object name)T if the named bit is set in object,
else NIL.(EXT:SET-CHAR-BIT
object name new-value)SYS::INPUT-CHARACTER with the named bit set or
unset, depending on the BOOLEAN new-value.
SYS::INPUT-CHARACTER is not a subtype of
CHARACTER.
SYS::INPUT-CHARACTER type only to
mention special keys and Control/Alternate/Shift key status on return from
(READ-CHAR EXT:*KEYBOARD-INPUT*).The graphic characters are those UNICODE characters which are defined by the UNICODE standard, excluding the ranges U0000 … U001F and U007F … U009F.
The alphabetic characters are those UNICODE characters which are defined as letters by the UNICODE standard, e.g., the ASCII characters
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
and the international alphabetic characters from the character set:
ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜßáíóúñѪºãõØøÀÃÕ
etc.
EXT:CHAR-INVERTCASE( returns the corresponding
character in the other case for EXT:CHAR-INVERTCASE char)CHAR, i.e., CHAR-UPCASE for a
lowercase character and CHAR-DOWNCASE for an uppercase character; for
a character that does not have a case attribute, the argument is returned.
See also EXT:STRING-INVERTCASE and EXT:NSTRING-INVERTCASE.
The characters with case are those UNICODE characters c, for
which the upper case mapping uc and the lower case mapping lc
have the following properties:
uc and lc are differentc is one of uc and lcuc and of lc
is ucuc and of lc
is lcThe titlecase property of UNICODE characters has no equivalent in Common Lisp.
The numeric characters are those UNICODE characters which are defined as digits by the UNICODE standard.
The characters are ordered according to their UNICODE code.
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.
Newlines are written according to the stream's EXT:ENCODING, see the
function STREAM-EXTERNAL-FORMAT and the description of EXT:ENCODINGs,
in particular, line terminators.
The default behavior is as follows:
When reading from a file, CR/LF is converted to #\Newline
(the usual convention on DOS), and CR not followed by LF is
converted to #\Newline as well (the usual conversion on MacOS, also used
by some programs on Win32).
If you do not want this, i.e., if you really want to distinguish
LF, CR and CR/LF, you have to resort to
binary input (function READ-BYTE).
Justification. Unicode Newline Guidelines say: “Even if you know which characters represents NLF on your particular platform, on input and in interpretation, treat CR, LF, CRLF, and NEL the same. Only on output do you need to distinguish between them.”
Rationale. In CLISP, #\Newline is identical to #\Linefeed
(which is specifically permitted by the [ANSI CL standard] in
[sec_13-1-7] “Character Names”).
Consider a file containing exactly this string:
(
Suppose we open it with CONCATENATE 'STRING "foo" (STRING #\Linefeed)
"bar" (STRING #\Return) (STRING #\Linefeed))(.
What should OPEN "foo" :EXTERNAL-FORMAT :DOS)READ-LINE return?
Right now, it returns "foo"
(the second READ-LINE returns "bar"
and reaches end-of-stream).
If our i/o were “faithful”, READ-LINE would have
returned the string (, i.e., a string with an embedded #\Newline
between "foo"
and "bar" (because a single #\Linefeed is not a
#\Newline in the specified CONCATENATE 'STRING "foo" (STRING
#\Linefeed) "bar"):EXTERNAL-FORMAT, it will not make READ-LINE return,
but it is a CLISP #\Newline!) Even though the specification for
READ-LINE does not explicitly forbids newlines inside the returned
string, such behavior would be quite surprising, to say the least.
Moreover, this line (with an embedded #\Newline) would be written as two
lines (when writing to a STREAM with :EXTERNAL-FORMAT of :DOS), because
the embedded #\Newline would be written as CR+LF.
The integer returned by CHAR-INT is the same as the character's
code (CHAR-CODE).
The characters that are not graphic chars and the space character have names:
Table 13.6. Additional characters (Platform Dependent: Win32 platform only.)
| code | char | |
|---|---|---|
( | #\Null | |
( | #\Bell | |
( | #\Backspace | |
( | #\Tab | |
( | #\Newline | #\Linefeed |
( | #\Code11 | |
( | #\Page | |
( | #\Return | |
( | #\Code26 | |
( | #\Escape | #\Esc |
( | #\Space | |
( | #\Rubout |
Table 13.7. Additional characters (Platform Dependent: UNIX platform only.)
| code | char | ||
|---|---|---|---|
( | #\Null | #\Nul | |
( | #\Soh | ||
( | #\Stx | ||
( | #\Etx | ||
( | #\Eot | ||
( | #\Enq | ||
( | #\Ack | ||
( | #\Bell | #\Bel | |
( | #\Backspace | #\Bs | |
( | #\Tab | #\Ht | |
( | #\Newline | #\Nl | #\Linefeed |
( | #\Vt | ||
( | #\Page | #\Np | |
( | #\Return | #\Cr | |
( | #\So | ||
( | #\Si | ||
( | #\Dle | ||
( | #\Dc1 | ||
( | #\Dc2 | ||
( | #\Dc3 | ||
( | #\Dc4 | ||
( | #\Nak | ||
( | #\Syn | ||
( | #\Etb | ||
( | #\Can | ||
( | #\Em | ||
( | #\Sub | ||
( | #\Escape | #\Esc | |
( | #\Fs | ||
( | #\Gs | ||
( | #\Rs | ||
( | #\Us | ||
( | #\Space | #\Sp | |
( | #\Rubout | #\Delete | #\Del |
Table of Contents
Function EXT:MAPCAP. The function EXT:MAPCAP is like MAPCAN, except that it
concatenates the resulting lists with APPEND instead of NCONC:
(EXT:MAPCAPfunctionx1...xn) ≡ (APPLY#'APPEND(MAPCARfunctionx1...xn))
(Actually a bit more efficient that this would have been.)
Function EXT:MAPLAP. The function EXT:MAPLAP is like MAPCON, except that it
concatenates the resulting lists with APPEND instead of NCONC:
(EXT:MAPLAPfunctionx1...xn) ≡ (APPLY#'APPEND(MAPLISTfunctionx1...xn))
(Actually a bit more efficient that this would have been.)
Table of Contents
Function MAKE-ARRAY. MAKE-ARRAY can return specialized arrays for the ARRAY-ELEMENT-TYPEs
(,
UNSIGNED-BYTE 2)(,
UNSIGNED-BYTE 4)(, UNSIGNED-BYTE 8)(, UNSIGNED-BYTE 16)(, and, of course, the required
specializations UNSIGNED-BYTE 32)NIL, BIT and CHARACTER.
Function ADJUST-ARRAY for displaced arrays. 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 cannot be checked at the time ADJUST-ARRAY is
called!
Table 15.1. Array limits
| CPU type | 32-bit CPU | 64-bit CPU |
|---|---|---|
ARRAY-RANK-LIMIT | 212 = 4096 | |
ARRAY-DIMENSION-LIMIT | 224-1 = 16777215 | 232-1 = 4294967295 |
ARRAY-TOTAL-SIZE-LIMIT | 224-1 = 16777215 | 232-1 = 4294967295 |
Table of Contents