# Implementation Notes for GNU CLISP.

## These notes document CLISP version 2.33.

### Dr. Bruno Haible

### Dr. Sam Steingold

Copyright © 1992-2004 Bruno Haible

Copyright © 1998-2004 Sam Steingold

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), Version 1.2 or 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 the section entitled "GNU Free Documentation License."

List of Tables

5.1. Function call limits
12.1. Boolean Operations
12.2. Fixnum limits
13.1. Standard characters
13.2. Semi-standard characters
13.3. Additional Named Characters
13.4. Additional syntax for characters with code from #x00 to #x1F:
13.5. Number of characters
13.6. Platform dependent characters: Win32 platforms.
13.7. Platform dependent characters: UNIX platforms.
13.8. Character bit constants (obsolete)
15.1. Array limits
19.1. The minimum filename syntax that may be used portably
23.1. Unreadable objects
25.1. Commands common to the main loop, the debugger and the stepper
25.2. Commands common to the debugger and the stepper
25.3. Commands common to the debugger and the stepper
25.4. Commands specific to `EVAL`/`APPLY`
25.5. Commands specific to the debugger
25.6. Commands specific to the stepper
25.7. Time granularity
31.1. Memory models with TYPECODES
31.2. Memory models with no TYPECODES

List of Examples

29.1. prog.lisp
29.2. prog.lisp
29.3. prog.lisp
29.4. prog.pot
29.5. prog.fr.po
30.1. `REGEXP:MATCH`
30.2. `REGEXP:REGEXP-QUOTE`
30.3. shell-count.lisp
30.4. shell-count.perl
30.5. Simple declarations and access
30.6. external C variable and some accesses
30.7. Calling an external function
30.8. Another example for calling an external function
30.9. Calling Lisp from C
30.10. Calling Lisp from C dynamically
30.11. Variable size arguments: calling `gethostname` from CLISP
30.12. Accessing variables in shared libraries.
30.13. Using a predefined library function file
30.14. Using flibcall
30.15. Be fully dynamic, defining library bases ourselves
30.16. Some sample function definitions

## Overview

These notes discuss the CLISP implementation of Common Lisp by

> Bruno's address

> Dr Bruno Haible
> Louisenstraße 103
> Bad Homburg
> D-61348 Germany
> http://www.haible.de/bruno/

and

> Michael's address

> Dr Michael Stoll
> Westerwaldweg 22
> Remagen-Oberwinter
> D-53424 Germany
> http://www.math.uni-duesseldorf.de/~stoll/

The current maintainers are

> Bruno's title

> Dr Bruno Haible

and

> Sam's address

> Dr Sam Steingold
> http://www.podval.org/~sds/

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 is indexed in parallel to the [Common Lisp HyperSpec] and documents how CLISP implements the standard [ANSI CL standard].

The second part documents the CLISP extensions, i.e., the functionality that goes beyond the [ANSI CL standard] requirements.

The third part 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`).

# Chapters or the [Common Lisp HyperSpec]

## Chapter 1. Introduction [CLHS-1]

## 1.1. Special Symbols [CLHS-1.4.1.3]

The final delimiter of an interactive stream: On UNIX, the user has to type Control-D at the beginning of a line. On Win32, the user has to type Control-Z, followed by Return. 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 Newline key or, on the numeric keypad, the Enter key.

## 1.2. Error Terminology [CLHS-1.4.2]

Safety settings are ignored; therefore where the standard uses the phrase “should signal an error”, an `ERROR` is `SIGNAL`ed.

## 1.3. Class Precedence Lists [CLHS-1.4.4.5]

The class precedence lists of the system classes `CLASS` `BUILT-IN-CLASS`, `STRUCTURE-CLASS`, `STANDARD-CLASS`, `STANDARD-METHOD` contain the class `STRUCTURE-OBJECT` instead of the class `STANDARD-OBJECT`.

## 1.4. Symbols in the Package “COMMON-LISP” [CLHS-1.9]

All 978 symbols in the “COMMON-LISP” package specified by the [ANSI CL standard] are implemented.

## Chapter 2. Syntax [CLHS-2]

## 2.1. Reader Algorithm [CLHS-2.2]

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.

## 2.2. Symbols as Tokens [CLHS-2.3.4]

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 creating a symbol from a token, no character attributes are removed.

## 2.3. Valid Patterns for Tokens [CLHS-2.3.5]

When a token with package markers is read, then 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.

## 2.4. Double-Quote [CLHS-2.4.5]

When a string is read, no character attributes are removed.

## 2.5. Backquote [CLHS-2.4.6]

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)))))

## 2.6. Sharpsign [CLHS-2.4.8]

Reader macros are also defined for the following:

Additional reader macros

#,
  load-time evaluation, kept despite the [ANSI CL standard] issue SHARP-COMMA-CONFUSION:REMOVE
#Y
  function objects and file `EXT:ENCODING`s
#""
  `PATHNAME`

## Chapter 3. Evaluation and Compilation [CLHS-3]

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`).

## 3.1. Evaluation [CLHS-3.1]

### 3.1.1. Introduction to Environments [CLHS-3.1.1]

Macro `EXT:THE-ENVIRONMENT`. As in Scheme, the macro `(`EXT:THE-ENVIRONMENT`)` returns the current lexical environment. This works only in interpreted code and is not compilable!

Function `(EXT:EVAL-ENV `form` `&OPTIONAL` `env`)`. evaluates a form in a given lexical environment, just as if the form had been a part of the program that the environment came from.

## 3.2. Compilation [CLHS-3.2]

### 3.2.1. Compiler Terminology [CLHS-3.2.1]

CLISP compiles to platform-independent byte-code.

### 3.2.2. Compiler Macros [CLHS-3.2.2.1]

Compiler macros are expanded in the compiled code only, and ignored by the interpreter.

### 3.2.3. Definition of Similarity [CLHS-3.2.4.2.2]

Hash tables are externalizable objects.

## 3.3. Declarations [CLHS-3.3]

The declarations `(`TYPE` `type` `variable` ...)`, `(`FTYPE` `type` `function` ...)`, `(`OPTIMIZE` (`quality` `value`) ...)` are ignored by the interpreter and the compiler.

The [ANSI CL standard] declaration `(`OPTIMIZE` (debug ...))` is legal.

The [ANSI CL standard] declaration `(`IGNORABLE` `variable` ...)` affects the variable binding for the variable `variable`. The compiler will not warn about the variable, regardless whether it is used or not.

### 3.3.1. Additional declarations

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`.

The type assertion `(`THE` `value-type` `form`)` enforces a type check in interpreted code. No type check is done in compiled code. See also the `EXT:ETHE` macro.

## 3.4. Lambda Lists [CLHS-3.4]

### 3.4.1. Boa Lambda Lists [CLHS-3.4.6]

The initial value of an `&AUX` variable in a boa lambda list is the value of the corresponding slot's initial form.

## 3.5. The Evaluation and Compilation Dictionary [CLHS-3.8]

### 3.5.1. Declaration `SPECIAL`

`(`PROCLAIM` '(`SPECIAL` `variable`))` declarations cannot 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.

constant variables may not be bound dynamically or lexically.

Function `EXT:SPECIAL-VARIABLE-P`. You can use the function `(`EXT:SPECIAL-VARIABLE-P` `symbol` `&OPTIONAL` `env`)` to check whether the symbol is a special variable. `env` of `NIL` or omitted means use the global environment, `T` means use current lexical 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 constants. Note that this function will not work in compiled code as you expect: when called with `NIL` `env`, it will be called at run time and check for globally special variables, but when `env` is `T`, it will be called at compile time and the value will be used as a constant in the code.

### 3.5.2. Function `CONSTANTP`.

Function `CONSTANTP` fully complies with [ANSI CL standard]. Additionally, some non-trivial forms are identified as constants, e.g., `(`CONSTANTP` '(`+` 1 2 3))` returns `T`.

### 3.5.3. Macro `EVAL-WHEN`

`EVAL-WHEN` also accepts the situations `(NOT EVAL)` and `(NOT COMPILE)`.

### Warning

Note that the situations `EVAL`, `LOAD` and `COMPILE` are deprecated by the spec, and they are not equivalent to the new standard situations `:EXECUTE`, `:LOAD-TOPLEVEL` and `:COMPILE-TOPLEVEL` in that they ignore the top-level versus non-top-level distinction.

## Chapter 4. Types and Classes [CLHS-4]

## 4.1. Types [CLHS-4.2]

### 4.1.1. Type Specifiers [CLHS-4.2.3]

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`)`.

The [ANSI CL standard] type specifier `(`REAL` `low` `high`)` denotes the real numbers between `low` and `high`.

`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 `(`EXT:TYPE-EXPAND` `typespec` `&OPTIONAL` `once-p`)`. If `typespec` is a user-defined type, 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 `typespec` was a user-defined type.

The possible results of `TYPE-OF`

- `CONS`
- `SYMBOL`, `NULL`, `BOOLEAN`, `KEYWORD`
- `(`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`, `COMPLEX`
- `CHARACTER`, `BASE-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`
- `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
- `SPECIAL-OPERATOR`, `LOAD-TIME-EVAL`, `SYMBOL-MACRO`, `EXT:ENCODING`, `FFI:FOREIGN-POINTER`, `FFI:FOREIGN-ADDRESS`, `FFI:FOREIGN-VARIABLE`;, `FFI:FOREIGN-FUNCTION`
- `EXT:WEAK-POINTER`, `READ-LABEL`, `FRAME-POINTER`, `SYSTEM-INTERNAL`
- `ADDRESS` (should not occur)
- any other `SYMBOL` (structure types or CLOS classes)
- a class object (CLOS classes without a proper name)

## 4.2. Classes [CLHS-4.3]

The CLOS symbols are `EXPORT`ed from the package “CLOS”. “COMMON-LISP” uses (as in `USE-PACKAGE`) “CLOS” and `EXT:RE-EXPORT`s the [ANSI CL standard] standard exported symbols (the CLISP extensions, e.g., `CLOS:CLASS-PROTOTYPE`, are not `EXT:RE-EXPORT`ed). 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”)
      (SHADOW symbol "CL-NO-CLOS"))
    (DO-SYMBOLS (symbol "CL-NO-CLOS")
      (EXPORT symbol "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

.

## 4.3. Deviations from [ANSI CL standard]

`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 Section 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 `CONS`es and `NUMBER`s, due to the performance concerns.

## 4.4. Standard Metaclasses [CLHS-4.3.1.1]

Among those classes listed in Figure 4-8, only the following are instances of `BUILT-IN-CLASS`:

- `T`
- `CHARACTER`
- `NUMBER`, `COMPLEX`, `REAL`, `FLOAT`, `RATIONAL`, `RATIO`, `INTEGER`
- `SEQUENCE`
- `ARRAY`, `VECTOR`, `BIT-VECTOR` `STRING`
- `LIST`, `CONS`
- `SYMBOL`, `NULL`
- `FUNCTION`, `GENERIC-FUNCTION`, `STANDARD-GENERIC-FUNCTION`
- `HASH-TABLE`
- `PACKAGE`
- `PATHNAME`, `LOGICAL-PATHNAME`
- `RANDOM-STATE`
- `READTABLE`
- `STREAM`, `BROADCAST-STREAM`, `CONCATENATED-STREAM`, `ECHO-STREAM`, `STRING-STREAM`, `FILE-STREAM`, `SYNONYM-STREAM`, `TWO-WAY-STREAM`

## 4.5. Defining Classes [CLHS-4.3.2]

`DEFCLASS` supports the `:METACLASS` option. Possible values are `STANDARD-CLASS` (the default) and `STRUCTURE-CLASS` (which creates structure classes, like `DEFSTRUCT` does).

It is not required that the superclasses of a class are defined before the `DEFCLASS` form for the class is evaluated. Use [Metaobject 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.

## 4.6. Redefining Classes [CLHS-4.3.6]

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.

## 4.7. The Types and Classes Dictionary [CLHS-4.4]

### 4.7.1. 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 `COERCE`s `FIXNUM`s to `CHARACTER`s via `CODE-CHAR`. When `CUSTOM:*COERCE-FIXNUM-CHAR-ANSI*` is non-`NIL`, `FIXNUM`s cannot be `COERCE`d to `CHARACTER`s.

## Chapter 5. Data and Control Flow [CLHS-5]

## 5.1. The Data and Control Flow Dictionary [CLHS-5.3]

Function `FUNCTION-LAMBDA-EXPRESSION`. The `name` of a `FFI:FOREIGN-FUNCTION` is a string (the name of the underlying C function), not a lisp function name.

Macro `DESTRUCTURING-BIND`. This macro does not perform full error checking.

Macros `PROG1`, `PROG2`, `AND`, `OR`, `PSETQ`, `WHEN`, `UNLESS`, `COND`, `CASE`, `MULTIPLE-VALUE-LIST`, `MULTIPLE-VALUE-BIND`, `MULTIPLE-VALUE-SETQ`. These macros are implemented as special operators (as permitted by Section 3.1.2.1.2.2) and, as such, are rather efficient.

Macro `DEFCONSTANT`. The 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.

### 5.1.1. Macro `EXT:FCASE`

This 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)))

### 5.1.2. Function `EXT:XOR`

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`.

### 5.1.3. Function `EQ`

`EQ` compares `CHARACTER`s and `FIXNUM`s as `EQL` does. No unnecessary copies are made of `CHARACTER`s and `NUMBER`s. Nevertheless, one should use `EQL` as it is more portable across Common Lisp implementations.

`(let ((x y)) (eq x x))` always returns `T`, regardless of `y`.

Note that `(eq x x)` might not be `T` for a `FFI:FOREIGN-VARIABLE` `x`.

### 5.1.4. Function `SYMBOL-FUNCTION`

`(`SETF` (`SYMBOL-FUNCTION` `symbol`) `object`)` requires `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`.

### 5.1.5. Macro `SETF`

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`
  `(`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-EXPANSION` `form` `&OPTIONAL` `env`)`, `(EXT:GET-SETF-METHOD `form` `&OPTIONAL` `env`)`, and `(EXT:GET-SETF-METHOD-MULTIPLE-VALUE `form` `&OPTIONAL` `env`)` receive as optional argument `env` 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.

Attempts to modify read-only data will `SIGNAL` 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.

See also the `EXT:LETF` and `EXT:LETF*` macros.

### 5.1.6. Special Operator `FUNCTION`

`(`FUNCTION` `symbol`)` returns the local function definition established by `FLET` or `LABELS`, if it exists, otherwise the global function definition.

`(`SPECIAL-OPERATOR-P` `symbol`)` returns `NIL` or `T`. If it returns `T`, then `(`SYMBOL-FUNCTION` `symbol`)` returns the (useless) special operator handler.

### 5.1.7. Macro `DEFINE-SYMBOL-MACRO`

The macro `DEFINE-SYMBOL-MACRO` establishes `SYMBOL-MACRO`s with global scope (as opposed to `SYMBOL-MACRO`s defined with `SYMBOL-MACROLET`, which have local scope): `(`DEFINE-SYMBOL-MACRO` `symbol` `expansion`)`.

The function `EXT:SYMBOL-MACRO-EXPAND` tests for a `SYMBOL-MACRO`: If `symbol` is defined as a `SYMBOL-MACRO`, `(`EXT:SYMBOL-MACRO-EXPAND` `symbol`)` returns two values, `T` and the expansion; otherwise it returns `NIL`.

Calling `BOUNDP` on a symbol defined as a `SYMBOL-MACRO` returns `T`.

Calling `SYMBOL-VALUE` on a symbol defined as a `SYMBOL-MACRO` returns the value of the expansion. Calling `SET` on a symbol defined as a `SYMBOL-MACRO` calls `SETF` on the expansion.

Calling `MAKUNBOUND` on a symbol defined as a `SYMBOL-MACRO` removes the `SYMBOL-MACRO` definition.

### 5.1.8. Macro `LAMBDA`

Constant `LAMBDA-LIST-KEYWORDS`. `(`&OPTIONAL` `&REST` `&KEY` `&ALLOW-OTHER-KEYS` `&AUX` `&BODY` `&WHOLE` `&ENVIRONMENT`)`

Table 5.1. Function call limits

`CALL-ARGUMENTS-LIMIT` | 212=4096
`MULTIPLE-VALUES-LIMIT` | 27=128
`LAMBDA-PARAMETERS-LIMIT` | 212=4096

### 5.1.9. Macros `DEFUN` & `DEFMACRO`

`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))))

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`.

## Chapter 6. Iteration [CLHS-6]

No notes.

## Chapter 7. Objects [CLHS-7]

## 7.1. Standard Method Combination [CLHS-7.6.6.2]

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 `SIGNAL`ed, additinally making `TYPE-ERROR-DATUM` and `TYPE-ERROR-EXPECTED-TYPE` available.

## 7.2. The Objects Dictionary [CLHS-7.7]

### 7.2.1. Generic function `CLOS:CLASS-PROTOTYPE`.

The [Metaobject Protocol] generic function `CLOS:CLASS-PROTOTYPE` is implemented. This allows non-consing access to slots with allocation `:CLASS`:

      (defclass counter ()
        ((count :allocation :class :initform 0 :reader how-many)))
      (defmethod initialize-instance :after ((obj counter) &rest args)
        (incf (slot-value obj 'count)))
      (defclass counted-object (counter) ((name :initarg :name)))

Now you can find out how many `COUNTED-OBJECT`s have been created by using `(HOW-MANY (`CLOS:CLASS-PROTOTYPE` 'COUNTER))`:

      (make-instance 'counted-object :name 'foo)
        #<COUNTED-OBJECT #x203028C9>
      (how-many (clos:class-prototype 'counter))
        1
      (make-instance 'counted-object :name 'bar)
        #<COUNTED-OBJECT #x20306CB1>
      (how-many (clos:class-prototype 'counter))
        2

## Chapter 8. Structures [CLHS-8]

The `:PRINT-FUNCTION` option should contain a lambda expression `(`LAMBDA` (object stream depth) (declare (ignore depth)) ...)` This lambda expression names a `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:

- The value of `*PRINT-ESCAPE*` must be respected.
- The treatment of `*PRINT-PRETTY*` is up to you.
- The value of `*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.)
- The value of `*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.)
- 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*` 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.
- You need not worry about the values of `*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).

## Chapter 9. Conditions [CLHS-9]

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.

Macro `EXT:MUFFLE-CERRORS`. The macro `(`EXT:MUFFLE-CERRORS` {`form`}*)` executes the `form`s. When a continuable error occurs, no message is printed, instead, the `CONTINUE` `RESTART` is invoked.

Macro `EXT:APPEASE-CERRORS`. The macro `(`EXT:APPEASE-CERRORS` {`form`}*)` executes the `form`s. Continuable errors are reported as warnings and the `CONTINUE` `RESTART` is invoked.

Macro `EXT:EXIT-ON-ERROR`. The macro `(`EXT:EXIT-ON-ERROR` {`form`}*)` executes the `form`s. When a non-continuable error or a Control-C interrupt occurs, the error message is printed and CLISP terminates with an error status.

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`. `(`EXT:WITH-RESTARTS` ({`restart-clause`}*) {`form`}*)` is therefore equivalent to `(`RESTART-CASE` (`PROGN` {`form`}*) {`restart-clause`}*)`.

## 9.1. Embedded Newlines in Condition Reports [CLHS-9.1.3.1.3]

The error message prefix for the first line is "*** - ". There is no prefix for subsequent error lines. The aesthetics of `CONDITION` reports containing an object which requires newlines when pretty printing is enabled, is undefined.

## 9.2. The Conditions Dictionary [CLHS-9.2]

Macro `RESTART-CASE`. In `(`RESTART-CASE` `form` {`restart-clause`}*)`, the argument list can also be specified after the keyword/value pairs instead of before them, i.e., each `restart-clause` can be either `(`restart-name` `arglist` {`keyword-value-pair`}* {`form`}*)` or `(`restart-name` {`keyword-value-pair`}* `arglist` {`form`}*)`.

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.

## Chapter 10. Symbols [CLHS-10]

No notes.

## Chapter 11. Packages [CLHS-11]

The [ANSI CL standard] packages present in CLISP

“COMMON-LISP”
  with the nicknames “CL” and “LISP”
“COMMON-LISP-USER”
  with the nicknames “CL-USER” and “USER”
“KEYWORD”
  with the nickname “”

The package “COMMON-LISP” `EXPORT`s only those symbols from the [ANSI CL standard] that are actually implemented.

## 11.1. Constraints on the “COMMON-LISP” Package for Conforming Programs - package locking [CLHS-11.1.2.1.2]

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 `SIGNAL`ed for redefine operations. Function `(`EXT:PACKAGE-LOCK` `package`)` returns the generalized boolean indicating whether the `package` is locked. A package (or a list thereof) can be locked using `(`SETF` (`EXT:PACKAGE-LOCK` `package-or-list`) `T`)`. CLISP locks its system packages (specified in the variable `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 ("LISP" "EXT" "CLOS")
      (defun restart () ...))

or

    (EXT:WITHOUT-PACKAGE-LOCK ("LISP") (trace read-line))

`(`EXT:WITHOUT-PACKAGE-LOCK` () ...)` temporarily unlocks all packages in `CUSTOM:*SYSTEM-PACKAGE-LIST*`.

Discussion - see also the USENET posting by Steven M. Haflich. 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.

## 11.2. The “COMMON-LISP-USER” Package [CLHS-11.1.2.2]

The “COMMON-LISP-USER” package uses the “COMMON-LISP” and “EXT” packages.

## 11.3. Implementation-Defined Packages [CLHS-11.1.2.4]

The following additional packages exist:

Implementation-Defined Packages

“CLOS”
  `EXPORT`s all CLOS-specific symbols, including some additional symbols.
“SYSTEM”
  has the nicknames “SYS” and “COMPILER”, and has no `EXPORT`ed symbols. It defines many system internals.
“EXT”
  is the umbrella package for all extensions: it imports and `EXT:RE-EXPORT`s 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”): “LDAP”, “POSIX”, “SOCKET”, “GSTREAM”, “GRAY”, “I18N”, “CUSTOM”.
“CHARSET”
  defines and `EXPORT`s some character sets, for use with `EXT:MAKE-ENCODING` and as `:EXTERNAL-FORMAT` argument.
“FFI”
  implements the foreign function interface. Some platforms only.
“SCREEN”
  defines an API for random screen access. Some platforms only.

All pre-existing packages except “COMMON-LISP-USER” belong to the implementation, in the sense that the programs that do not follow Section 11.1.2.1.2 ("Constraints on the “COMMON-LISP” Package for Conforming Programs") cause undefined behavior.

## 11.4. The Packages Dictionary [CLHS-11.2]

### 11.4.1. Function `MAKE-PACKAGE`

For `MAKE-PACKAGE`, the default value of the `:USE` argument is `(“COMMON-LISP”)`.

`MAKE-PACKAGE` accepts a keyword argument `:CASE-SENSITIVE`. Similarly, `DEFPACKAGE` accepts an option `:CASE-SENSITIVE`. When its value is non-`NIL`, the package will be case sensitive, i.e., the reader will not case-convert symbol names before looking them up or creating them in this package. The package names are still subject to `(`READTABLE-CASE` `*READTABLE*`)`, though.

### 11.4.2. Function `EXT:RE-EXPORT`

The function `(`EXT:RE-EXPORT` `FROM-PACK` `TO-PACK`)` re-`EXPORT`s all external `SYMBOL`s from `FROM-PACK` also from `TO-PACK`, provided it already uses `FROM-PACK`; and `SIGNAL`s an `ERROR` otherwise.

## Chapter 12. Numbers [CLHS-12]

## 12.1. Numeric Types

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`.

## 12.2. Number Concepts [CLHS-12.1]

### 12.2.1. Byte Operations on Integers [CLHS-12.1.1.3.2]

Byte specifiers are objects of built-in type BYTE, not `INTEGER`s.

### 12.2.2. Rule of Float Substitutability [CLHS-12.1.3.3]

When a mathematical function may return an exact (`RATIONAL`) or inexact (`FLOAT`) result, it always returns the exact result.

### 12.2.3. Floating-point Computations [CLHS-12.1.4]

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

- When you got a `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.
- When you got unnormalized floats in your program, your results will have a greatly reduced accuracy anyway. Since CLISP has the means to cope with this - `LONG-FLOAT`s 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 `(`EXT:LONG-FLOAT-DIGITS`)`. It can be set by `(`SETF` (`EXT:LONG-FLOAT-DIGITS`) `n`)`, where `n` is a positive integer. E.g., `(`SETF` (`EXT:LONG-FLOAT-DIGITS`) 3322)` sets the default precision of long floats to about 1000 decimal digits.

#### 12.2.3.1. Rule of Float Precision Contagion [CLHS-12.1.4.4]

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`.

Rationale:
  See it pragmatically: save what you can and let others worry about the rest.
Brief:
  Common Lisp knows the number's precision, not accuracy, so preserving the precision can be accomplished reliably, while anything relating to the accuracy is just a speculation - only the user (programmer) knows what it is in each case.
Detailed:
  A computer float is an approximation of a real number. One can think of it as a random variable with the mean equal to itself and standard deviation equal to half the last significant digit. E.g., `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.
Experience:
  Rounding errors accumulate, and if a computation is conducted with insufficient precision, an outright incorrect result can be returned. (E.g., `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 12.1.4.4 Rule of Float Precision Contagion!)

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`.
Brief:
  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-FLOAT`s, 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-FLOAT`s when only `SHORT-FLOAT`s would be needed.

Variable `CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION*`. 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, this is why `CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION*` is set to `T` initially. 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). Set it to `ERROR` to have CLISP `SIGNAL` an `ERROR` on float precision contagion.

### 12.2.4. Complex Computations [CLHS-12.1.5]

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`)`.

### 12.2.5. Rule of Canonical Representation for Complex Rationals [CLHS-12.1.5.3]

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 `(let ((x (sqrt -9.0))) (* x x))` - instead of evaluating 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)`.

## 12.3. The Numbers Dictionary [CLHS-12.2]

Function `UPGRADED-COMPLEX-PART-TYPE`. When the argument is not a recognizable subtype or `REAL`, `UPGRADED-COMPLEX-PART-TYPE` `SIGNAL`s an `ERROR`, otherwise it returns `REAL`, since a `COMPLEX` number in CLISP can always have `REALPART` and `IMAGPART` of any type.

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*`.

Macro `EXT:WITHOUT-FLOATING-POINT-UNDERFLOW`. The macro `(`EXT:WITHOUT-FLOATING-POINT-UNDERFLOW` {`form`}*)` executes the `form`s, with errors of type `FLOATING-POINT-UNDERFLOW` inhibited. Floating point operations will silently return zero instead of `SIGNAL`ing an `ERROR` of type `FLOATING-POINT-UNDERFLOW`.

### 12.3.1. Additional Integer Functions

Function `EXT:!` `(`EXT:!` `n`)` returns the factorial of `n`, `n` being a nonnegative `INTEGER`.

Function `EXT:EXQUO`. `(`EXT:EXQUO` `x` `y`)` returns the integer quotient `x/y` of two integers `x`,`y`, and `SIGNAL`s an `ERROR` when the quotient is not integer. (This is more efficient than `/`.)

Function `EXT:XGCD`. `(`EXT:XGCD` `x1` ... `xn`)` returns the values `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 = (GCD x1 ... xn)
       = (+ (* k1 x1) ... (* kn xn))

Function `EXT:MOD-EXPT`. `(`EXT:MOD-EXPT` `k` `l` `m`)` is equivalent to `(`MOD` (`EXPT` `k` `l`) `m`)` except it is more efficient for very large arguments.

### 12.3.2. Floating Point

Function `EXPT`. `(`EXPT` `base` `exponent`)` is not very precise if `exponent` has a large absolute value.

Function `LOG`. `(`LOG` `number` `base`)` `SIGNAL`s an `ERROR` if ``base` = 1`.

Constant `PI`. The value of `PI` is a `LONG-FLOAT` with the precision given by `(`EXT:LONG-FLOAT-DIGITS`)`. When this precision is changed, the value of `PI` is automatically recomputed. Therefore `PI` is not a constant variable.

### 12.3.3. Float Decoding [CLHS]

`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 always evaluates to `T`:

       (>= (FLOAT-DIGITS (FLOAT-DIGITS number digits)) digits)

### 12.3.4. Boolean Operations [CLHS]

Table 12.1. Boolean Operations

constant | value
--- | ---
`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.3.5. Fixnum Limits [CLHS]

Table 12.2. Fixnum limits

CPU type | 16-bit CPU | 32-bit CPU | 64-bit CPU
--- | --- | --- | ---
`MOST-POSITIVE-FIXNUM` | 224-1 = 16777215 | 232-1 = 4294967295
`MOST-NEGATIVE-FIXNUM` | -224 = -16777216 | -232 = -4294967296

### 12.3.6. Float Limits [CLHS]

Together with `PI`, the other long float constants `LEAST-NEGATIVE-LONG-FLOAT` `LEAST-NEGATIVE-NORMALIZED-LONG-FLOAT` `LEAST-POSITIVE-LONG-FLOAT` `LEAST-POSITIVE-NORMALIZED-LONG-FLOAT` `LONG-FLOAT-EPSILON` `LONG-FLOAT-NEGATIVE-EPSILON` `MOST-NEGATIVE-LONG-FLOAT` `MOST-POSITIVE-LONG-FLOAT` are recomputed whenever `(`EXT:LONG-FLOAT-DIGITS`)` is `SETF`ed. They are not constant variables.

### 12.3.7. Condition `FLOATING-POINT-INVALID-OPERATION`

This `CONDITION` is never `SIGNAL`ed by CLISP.

### 12.3.8. Condition `FLOATING-POINT-INEXACT`

This `CONDITION` is never `SIGNAL`ed by CLISP.

## Chapter 13. Characters [CLHS-13]

The characters are ordered according to a superset of the ASCII character set.

Platform dependent: only in CLISP built with the compile-time flag UNICODE.
  More precisely, CLISP uses the 21-bit UNICODE 3.2 character set (ISO 10646, also known as UCS-4).

Platform dependent: UNIX (except NeXTstep), Win32 platforms only, and only in CLISP built without compile-time flag UNICODE.

  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).

Platform dependent: NeXTstep platforms only, and only in CLISP built without compile-time flag UNICODE.

  More precisely, CLISP uses the NeXTstep 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.1. Standard characters

character | code
--- | ---
#\Space | #x20
#\Newline | #x0A

Table 13.2. Semi-standard characters

character | code
--- | ---
#\Backspace | #x08
#\Tab | #x09
#\Linefeed | #x0A
#\Page | #x0C
#\Return | #x0D

#\Newline is the line terminator.

Table 13.3. Additional Named Characters

character | code
--- | ---
#\Null | #x00
#\Bell | #x07
#\Escape | #x1B

Table 13.4. 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 23.1, “characters”.

## 13.1. Attributes

Characters do not have the [CLtL1] font and bits attributes. 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` = 16
  The system uses only font 0.
`ext:char-bits-limit` = 16

  Character 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`)`
  returns the font of a `CHARACTER` or `SYS::INPUT-CHARACTER`.
`(`ext:char-bits` `object`)`
  returns the bits of a `CHARACTER` or `SYS::INPUT-CHARACTER`.
`(`ext:make-char` `char` [`bits` [`font`]])`
  returns a new `SYS::INPUT-CHARACTER`, or `NIL` if such a character cannot be created.
`(`ext:char-bit` `object` `name`)`
  returns `T` if the named bit is set in `object`, else `NIL`.
`(`ext:set-char-bit` `object` `name` `newvalue`)`
  returns a new `SYS::INPUT-CHARACTER` with the named bit set or unset, depending on the boolean `newvalue`.

Platform dependent: UNIX, Win32 platforms only.
  The system itself uses this `SYS::INPUT-CHARACTER` type only to mention special keys and Control/Alternate/Shift key status on return from `(`READ-CHAR` `EXT:*KEYBOARD-INPUT*`)`.

## 13.2. Character Scripts [CLHS-13.1.2.1]

The only defined character script is the type `CHARACTER` itself.

## 13.3. Character Attributes [CLHS-13.1.3]

Characters have no implementation-defined attributes. All characters are simple characters.

## 13.4. Graphic Characters [CLHS-13.1.4.1]

The graphic characters are those UNICODE characters which are defined by the UNICODE standard, excluding the ranges U0000 … U001F and U007F … U009F.

## 13.5. Alphabetic Characters [CLHS-13.1.4.2]

The alphabetic characters are those UNICODE characters which are defined as letters by the UNICODE standard.

## 13.6. Case of Implementation-Defined Characters [CLHS-13.1.4.3.4]

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 different
- `c` is one of `uc` and `lc`
- the upper case mapping of `uc` and of `lc` is `uc`
- the lower case mapping of `uc` and of `lc` is `lc`

The titlecase property of UNICODE characters has no equivalent in Common Lisp.

## 13.7. Numeric Characters [CLHS-13.1.4.4]

The numeric characters are those UNICODE characters which are defined as digits by the UNICODE standard.

## 13.8. Ordering of Characters [CLHS-13.1.6]

The characters are ordered according to their UNICODE code.

## 13.9. Treatment of Newline during Input and Output [CLHS-13.1.8]

Newlines are written according to the stream's `EXT:ENCODING`, see the function `STREAM-EXTERNAL-FORMAT` and the description of `EXT:ENCODING`s, in particular, line terminators. The default behavior is as follows:

Platform dependent: Win32 platforms only.
  When writing to a file, #\Newline is converted to CR/LF. (This is the usual convention on DOS.) For example, #\Return+#\Newline is written as CR/CR/LF.

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`).

Rationale. In CLISP, #\Newline is identical to #\Linefeed (which is specifically permitted by [ANSI CL standard] in section Character Names). Consider a file containing exactly this string: `(`CONCATENATE` 'string "foo" (string #\Linefeed) "bar" (string #\Return) (string #\Linefeed))` Suppose we open it with `(`OPEN` "foo" `:EXTERNAL-FORMAT` `:DOS`)`. What should `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 `(`CONCATENATE` 'string "foo" (string #\Linefeed) "bar")`, i.e., a string with an embedded #\Newline between `"foo"` and `"bar"` (because a single #\Linefeed is not a #\Newline in the specified `: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.

## 13.10. Character Encodings [CLHS-13.1.9]

The integer returned by `CHAR-INT` is the same as the character's code.

## 13.11. Documentation of Implementation-Defined Scripts [CLHS-13.1.10]

See Section 29.4, “Extensions-1.4. Encodings”.

## 13.12. The Characters Dictionary [CLHS-13.2]

`CHAR-CODE` takes values from `0` (inclusive) to `CHAR-CODE-LIMIT` (exclusive), i.e., the implementation supports exactly `CHAR-CODE-LIMIT` characters.

Table 13.5. Number of characters

binaries built | without UNICODE support | with UNICODE support
--- | --- | ---
`CHAR-CODE-LIMIT` | 28 = 256 | 17 * 216 = 1114112

The types `EXT:STRING-CHAR` and `BASE-CHAR` are equivalent to `CHARACTER`.

The graphic characters have been described above.

The standard characters are #\Newline and the graphic characters with a code between 32 and 126 (inclusive).

The alphabetic characters are these characters:

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.13. Functions on characters

Function `(`EXT:CHAR-WIDTH` `char`)`. returns the number of screen columns occupied by `char`. This is 0 for non-spacing characters (such as control characters and many combining characters), 2 for double-width East Asian characters, and 1 for all other characters. See also function `EXT:STRING-WIDTH`.

## 13.14. Platform-Dependent Characters

The characters that are not graphic chars and the space character have names:

Table 13.6. Platform dependent characters: Win32 platforms.

code | char
--- | ---
`(`CODE-CHAR` #x00)` | #\Null
`(`CODE-CHAR` #x07)` | #\Bell
`(`CODE-CHAR` #x08)` | #\Backspace | #\Rubout
`(`CODE-CHAR` #x09)` | #\Tab |
`(`CODE-CHAR` #x0A)` | #\Newline | #\Linefeed
`(`CODE-CHAR` #x0B)` | #\Code11 |
`(`CODE-CHAR` #x0C)` | #\Page |
`(`CODE-CHAR` #x0D)` | #\Return |
`(`CODE-CHAR` #x1A)` | #\Code26 |
`(`CODE-CHAR` #x1B)` | #\Escape |
`(`CODE-CHAR` #x20)` | #\Space |

Table 13.7. Platform dependent characters: UNIX platforms.

code | char
--- | ---
`(`CODE-CHAR` #x00)` | #\Null | #\Nul
`(`CODE-CHAR` #x01)` | #\Soh |
`(`CODE-CHAR` #x02)` | #\Stx |
`(`CODE-CHAR` #x03)` | #\Etx |
`(`CODE-CHAR` #x04)` | #\Eot |
`(`CODE-CHAR` #x05)` | #\Enq |
`(`CODE-CHAR` #x06)` | #\Ack |
`(`CODE-CHAR` #x07)` | #\Bell | #\Bel
`(`CODE-CHAR` #x08)` | #\Backspace | #\Bs
`(`CODE-CHAR` #x09)` | #\Tab | #\Ht
`(`CODE-CHAR` #x0A)` | #\Newline | #\Nl | #\Linefeed
`(`CODE-CHAR` #x0B)` | #\Vt |  |
`(`CODE-CHAR` #x0C)` | #\Page | #\Np |
`(`CODE-CHAR` #x0D)` | #\Return | #\Cr |
`(`CODE-CHAR` #x0E)` | #\So |  |
`(`CODE-CHAR` #x0F)` | #\Si |  |
`(`CODE-CHAR` #x10)` | #\Dle |  |
`(`CODE-CHAR` #x11)` | #\Dc1 |  |
`(`CODE-CHAR` #x12)` | #\Dc2 |  |
`(`CODE-CHAR` #x13)` | #\Dc3 |  |
`(`CODE-CHAR` #x14)` | #\Dc4 |  |
`(`CODE-CHAR` #x15)` | #\Nak |  |
`(`CODE-CHAR` #x16)` | #\Syn |  |
`(`CODE-CHAR` #x17)` | #\Etb |  |
`(`CODE-CHAR` #x18)` | #\Can |  |
`(`CODE-CHAR` #x19)` | #\Em |  |
`(`CODE-CHAR` #x1A)` | #\Sub |  |
`(`CODE-CHAR` #x1B)` | #\Escape | #\Esc |
`(`CODE-CHAR` #x1C)` | #\Fs |  |
`(`CODE-CHAR` #x1D)` | #\Gs |  |
`(`CODE-CHAR` #x1E)` | #\Rs |  |
`(`CODE-CHAR` #x1F)` | #\Us |  |
`(`CODE-CHAR` #x20)` | #\Space | #\Sp |
`(`CODE-CHAR` #x7F)` | #\Rubout | #\Delete | #\Del

## 13.15. Obsolete Constants

Table 13.8. Character bit constants (obsolete)

constant | value
--- | ---
`EXT:CHAR-CONTROL-BIT` | 1
`EXT:CHAR-META-BIT` | 2
`EXT:CHAR-SUPER-BIT` | 4
`EXT:CHAR-HYPER-BIT` | 8

## Chapter 14. Conses [CLHS-14]

## 14.1. The Conses Dictionary [CLHS-14.2]

### 14.1.1. Functions `MAPCAR`, `MAPCAN`, `MAPLIST`, `MAPCON`, ...

Function `EXT:MAPCAP`. The function `EXT:MAPCAP` is like `MAPCAN`, except that it concatenates the resulting lists with `APPEND` instead of `NCONC`:

    (EXT:MAPCAP function x1 ... xn) ≡
    (APPLY #'APPEND (MAPCAR function x1 ... 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:MAPLAP function x1 ... xn) ≡
    (APPLY #'APPEND (MAPLIST function x1 ... xn))

(Actually a bit more efficient that this would have been.)

## Chapter 15. Arrays [CLHS-15]

Function `MAKE-ARRAY`. `MAKE-ARRAY` can return specialized arrays for the `ARRAY-ELEMENT-TYPE`s `(`UNSIGNED-BYTE` 2)`, `(`UNSIGNED-BYTE` 4)`, `(`UNSIGNED-BYTE` 8)`, `(`UNSIGNED-BYTE` 16)`, `(`UNSIGNED-BYTE` 32)`, and, of course, the required specializations `NIL`, `BIT` and `CHARACTER`.

## 15.1. Array Elements [CLHS-15.1.1]

Table 15.1. Array limits

CPU type | 16-bit CPU | 32-bit CPU | 64-bit CPU
--- | --- | --- | ---
`ARRAY-RANK-LIMIT` | 212 = 4096
`ARRAY-DIMENSION-LIMIT` | 224 = 16777216 | 232 = 4294967296
`ARRAY-TOTAL-SIZE-LIMIT` | 224 = 16777216 | 232 = 4294967296

### Note

Note that `ARRAY-DIMENSION-LIMIT` and `ARRAY-TOTAL-SIZE-LIMIT` are not `FIXNUM`s (they are equal to `(`1+` `MOST-POSITIVE-FIXNUM`)`), contrary to the [ANSI CL standard] Issue ARRAY-DIMENSION-LIMIT-IMPLICATIONS:ALL-FIXNUM.

## 15.2. The Arrays Dictionary [CLHS-15.2]

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 is not checked at the time `ADJUST-ARRAY` is called!

## Chapter 16. Strings [CLHS-16]

String comparison is based on the function `CHAR<=`. Therefore diphthongs do not obey the usual national rules. Example: `o` < `oe` < `z` < `ö`.

## 16.1. The Strings Dictionary [CLHS-16.2]

### 16.1.1. Functions on strings

Function `EXT:STRING-WIDTH`. `(`EXT:STRING-WIDTH` `string` `&KEY` `start` `end`)` returns the number of screen columns occupied by `string`. This is computed as the sum of all `EXT:CHAR-WIDTH`s of all of the `string`'s characters.

## Chapter 17. Sequences [CLHS-17]

## 17.1. The Sequences Dictionary [CLHS-17.3]

### 17.1.1. Additional Macros

#### 17.1.1.1. Macro `EXT:DOSEQ`

For iteration through a sequence, a macro `EXT:DOSEQ`, similar to `DOLIST`, may be used instead of `MAP`:

    (EXT:DOSEQ (variable seqform [resultform])
      {declaration}*
      {tag|form}*)

`EXT:DOSEQ` forms are iteration forms.

### 17.1.2. Functions `NREVERSE` & `NRECONC`

Function `NREVERSE`. 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.

Function `NRECONC`. The result of `NRECONC` is `EQ` to the first argument unless it is `NIL`, in which case the result is `EQ` to the second argument.

### 17.1.3. Functions `REMOVE` & `DELETE`

`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.

Variable `CUSTOM:*SEQUENCE-COUNT-ANSI*`. Contrary to the [ANSI CL standard] issue 283 RANGE-OF-COUNT-KEYWORD:NIL-OR-INTEGER, negative `:COUNT` keyword arguments are not allowed unless you set `CUSTOM:*SEQUENCE-COUNT-ANSI*` to a non-`NIL` value, in which case “using a negative integer value is functionally equivalent to using a value of zero”, as per the [ANSI CL standard] issue.

### 17.1.4. Functions `SORT` & `STABLE-SORT`

`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. Worst case complexity: `O(n*log(n))` comparisons, where `n` is the `LENGTH` of the subsequence bounded by the `:START` and `:END` arguments.

## Chapter 18. Hash Tables [CLHS-18]

## 18.1. The Hash Tables Dictionary [CLHS-18.2]

### 18.1.1. Function `MAKE-HASH-TABLE`

`MAKE-HASH-TABLE` supports additional keywords `:INITIAL-CONTENTS` and `:WEAK`:

    (MAKE-HASH-TABLE &KEY :test :initial-contents :size
                     :rehash-size :rehash-threshold :weak)

The `:INITIAL-CONTENTS` argument is an alist that is used to initialize the new hash table. The `:REHASH-THRESHOLD` argument is ignored.

The `:WEAK` can take the following values:

`NIL` (default)
`:KEY`
`:VALUE`
`:EITHER`
`:BOTH`

and specifies whether the `HASH-TABLE` is weak: if the key, value, either or both are not accessible for the garbage-collection purposes, i.e., if they are only accessible via weak `HASH-TABLE`s and `EXT:WEAK-POINTER`s, it is garbage-collected and removed from the weak `HASH-TABLE`.

The `SETF`able predicate `EXT:HASH-TABLE-WEAK-P` checks whether the `HASH-TABLE` is weak.

Just like `EXT:WEAK-POINTER`s, weak `HASH-TABLE`s cannot be printed readably.

### 18.1.2. Macro `EXT:DEFINE-HASH-TABLE-TEST`

You can define a new hash table test using the macro `EXT:DEFINE-HASH-TABLE-TEST`: `(`EXT:DEFINE-HASH-TABLE-TEST` test-name `test-function` `hash-function`)`, after which `test-name` can be passed as the `:TEST` argument to `MAKE-HASH-TABLE`. E.g.:

     (EXT:DEFINE-HASH-TABLE-TEST string STRING= SXHASH)
     (MAKE-HASH-TABLE :test 'string)

(which is not too useful because it is equivalent to an `EQUAL` `HASH-TABLE` but less efficient).

The fundamental requirement is that the `test-function` and `hash-function` are consistent:

      (FUNCALL test-function x y) ⇒
      (= (FUNCALL hash-function x) (FUNCALL hash-function y))

This means that the following definition:

      (EXT:DEFINE-HASH-TABLE-TEST number = SXHASH) ; BAD!

is not correct because `(`=` 1 1d0)` is `T` but `(`=` (`SXHASH` 1) (`SXHASH` 1d0))` is `NIL`. The correct way is, e.g.:

      (EXT:DEFINE-HASH-TABLE-TEST number = (LAMBDA (x) (SXHASH (COERCE x 'SHORT-FLOAT))))

(note that `(`COERCE` `x` `SHORT-FLOAT`)` does not cons up fresh objects while `(`COERCE` `x` `DOUBLE-FLOAT`)` does).

### 18.1.3. Function `HASH-TABLE-TEST`

Function `HASH-TABLE-TEST` returns either one of the four standard symbols `EQ`, `EQL`, `EQUAL`, `EQUALP`, or, for `HASH-TABLE`s created with a user-defined `HASH-TABLE-TEST` (see macro `EXT:DEFINE-HASH-TABLE-TEST`), a `CONS` cell `(`test-function` . `hash-function`)`.

### 18.1.4. Macro `EXT:DOHASH`

For iteration through a `HASH-TABLE`, a macro `EXT:DOHASH`, similar to `DOLIST`, can be used instead of `MAPHASH`:

    (EXT:DOHASH (key-var value-var hash-table-form [resultform])
      {declaration}*
      {tag|form}*)

`EXT:DOHASH` forms are iteration forms.

## Chapter 19. Filenames [CLHS-19]

For most operations, pathnames denoting files and pathnames denoting directories cannot be used interchangeably.

Platform dependent: UNIX platforms only.
  For example, `#P"foo/bar"` denotes the file `#P"bar"` in the directory `#P"foo"`, while `#P"foo/bar/"` denotes the subdirectory `#P"bar"` of the directory `#P"foo"`.
Platform dependent: Win32 platforms only.
  For example, `#P"foo\\bar"` denotes the file `#P"bar"` in the directory `#P"foo"`, while `#P"foo\\bar\\"` denotes the subdirectory `#P"bar"` of the directory `#P"foo"`.
Platform dependent: Win32 and Cygwin platforms only.
  User variable `CUSTOM:*DEVICE-PREFIX*` controls translation between Cygwin pathnames (e.g., `#P"/cygdrive/c/gnu/clisp/"`) and native Win32 pathnames (e.g., `#P"C:\\gnu\\clisp\\"`) When it is set to `NIL`, no translations occur and the Cygwin port will not understand the native paths and the native Win32 port will not understand the Cygwin paths. When its value is a string, it is used by `PARSE-NAMESTRING` to translate into the appropriate platform-specific representation, so that on Cygwin, `(`PARSE-NAMESTRING` "c:/gnu/clisp/")` returns `#P"/cygdrive/c/gnu/clisp/"`, while on Win32 `(`PARSE-NAMESTRING` "/cygdrive/c/gnu/clisp/")` returns `#P"C:/gnu/clisp/"`. The initial value is `"cygdrive"`, you should edit `#P"config.lisp"` to change it.

This is especially important for the directory-handling functions.

Table 19.1. The minimum filename syntax that may be used portably

pathname | meaning
--- | ---
`"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 or with name `.yy` and no type, depending on the value of `CUSTOM:*PARSE-NAMESTRING-DOT-FILE*`.

Hereby `xxx` denotes 1 to 8 characters, and `yy` denotes 1 to 3 characters, each of which being either an alphanumeric character or the underscore #\_. Other properties of pathname syntax vary between operating systems.

## 19.1. Pathname Components [CLHS-19.2.1]

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` `EQ` `NIL` may not be allowed either.

### 19.1.1. Directory canonicalization.

As permitted by the `MAKE-PATHNAME` secification, the `PATHNAME` directory component is canonicalized when the pathname is constructed:

1. `""` and `"."` are removed
2. `".."`, `"*"`, and `"**"` are converted to `:UP`, `:WILD` and `:WILD-INFERIORS`, respectively
3. patterns `foo/../` are collapsed

### 19.1.2. Platform-specific issues.

Platform dependent: UNIX platforms only.

  Pathname components

  `host`
    always `NIL`
  `device`
    always `NIL`
  ``directory` = (`startpoint` . `subdirs`)`

    element | values | meaning
    --- | --- | ---
    `startpoint` | `:RELATIVE` | `:ABSOLUTE`
    `subdirs` | `()` | `(`subdir` . `subdirs`)`
    `subdir` | `:WILD-INFERIORS` | `**` or `...`, all subdirectories
    `subdir` | `SIMPLE-STRING`, may contain wildcard characters `"?"` and `"*"` (may also be specified as `:WILD`) |

  `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`)

  A UNIX filename is split into name and type.

  External notation: | `"server:sub1.typ/sub2.typ/name.typ"`
  using defaults: | `"sub1.typ/sub2.typ/name.typ"`
  or | `"name.typ"`
  or | `"sub1.typ/**/sub3.typ/x*.lisp"`
  or similar. |

Platform dependent: Win32 platforms only.

  Pathname components

  `host`
    `NIL` or `SIMPLE-STRING`, wildcard characters may occur but do not act as wildcards
  `device`
    `NIL` or `:WILD` or `A`|...|`Z`
  ``directory` = (`startpoint` . `subdirs`)`

    element | values | meaning
    --- | --- | ---
    `startpoint` | `:RELATIVE` | `:ABSOLUTE`
    `subdirs` | `()` | `(`subdir` . `subdirs`)`
    `subdir` | `:WILD-INFERIORS` | `**` or `...`, all subdirectories
    `subdir` | `SIMPLE-STRING`, may contain wildcard characters `"?"` and `"*"` (may also be specified as `:WILD`) |

  `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`)

  If `host` is non-`NIL`, `device` must be `NIL`.

  A Win32 filename is split into name and type.

  External notation: | `"A:\sub1.typ\sub2.typ\name.typ"`
  using defaults: | `"\sub1.typ\sub2.typ\name.typ"`
  or | `"name.typ"`
  or | `"*:\sub1.typ\**\sub3.typ\x*.lisp"`
  or similar. |

  Instead of `"\"` one may use `"/"`, as usual for DOS calls.

  If `host` is non-`NIL` and the `directory`'s `startpoint` is not `:ABSOLUTE`, `(`PARSE-NAMESTRING` (`NAMESTRING` `pathname`))` will not be the same as `pathname`.

Platform dependent: UNIX, Win32 platforms only.
  The wildcard characters: `"*"` matches any sequence of characters, `"?"` matches any one character.

Name/type namestring split.

Platform dependent: UNIX, Win32 platforms only.

  A filename is split into name and type according to the following rule:

  - if there is no `"."` in the filename, then the `name` is everything, `type` is `NIL`;
  - if there is a `"."`, then `name` is the part before and `type` the part after the last dot.

  - if the only `"."` is the first character, then the behavior depends on the value of the user variable `CUSTOM:*PARSE-NAMESTRING-DOT-FILE*` which can be either

    `:TYPE`
      `NIL` `name`, everything after the `"."` is the `type`; or
    `:NAME`
      `NIL` `type`, everything is the `name`

  Due to this name/type splitting rule, there are pathnames that cannot 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` "foo.bar")`.

## 19.2. :UNSPECIFIC as a Component Value [CLHS-19.2.2.2.3]

The symbol `:UNSPECIFIC` is not permitted as a pathname component for any slot of any pathname. It is also illegal to pass it as an argument to `MAKE-PATHNAME`.

The only use for `:UNSPECIFIC` is that it is returned by `PATHNAME-DEVICE` for `LOGICAL-PATHNAME`s, as required by [CLHS-19.3.2.1] Unspecific Components of a Logical Pathname.

## 19.3. External notation.

External notation of pathnames (cf. `PARSE-NAMESTRING` and `NAMESTRING`), of course without spaces, [,],{,}:

Platform dependent: UNIX platforms only.

  [ `"/"` ] | `"/"` denotes absolute pathnames
  { `name``"/"` } | each one a subdirectory
  [ `name` [`"."``type`] ] | filename with type (extension)

  Name and type may be `STRING`s of any `LENGTH` (consisting of printing ASCII characters, except `"/"`).

Platform dependent: Win32 platforms only.

  [ [`drivespec`] : ] | a letter `"*"`|`a`|...|`z`|`A`|...|`Z`
  { `name` [. `type`] \ } | each one a subdirectory, `"\"` may be replaced by `"/"`
  [ `name` [. `type`] ] | filename with type (extension)

  Name and type may be `STRING`s of any `LENGTH` (consisting of printing ASCII characters, except `"/"`, `"\"`, `":"`).

`NAMESTRING` has an optional flag argument: `(`NAMESTRING` `pathname` `T`)` returns an external notation suitable for passing to the operating system or other programs.

Platform dependent: unknown platforms only.
  The function `USER-HOMEDIR-PATHNAME` is not implemented.

## 19.4. Logical Pathnames [CLHS-19.3]

When the argument of the function `TRANSLATE-LOGICAL-PATHNAME` is a string, it is interpreted as a logical pathname string.

## 19.5. The Filenames Dictionary [CLHS-19.4]

Pathname Designators. When `CUSTOM:*PARSE-NAMESTRING-ANSI*` is `NIL`, `SYMBOL` is also treated as a pathname designator, namely its `SYMBOL-NAME` is converted to the operating system's preferred pathname case.

Function `PATHNAME`. `PATHNAME` always returns a physical pathname.

Function `PATHNAME-MATCH-P`. `PATHNAME-MATCH-P` does not interpret missing components as wild.

### 19.5.1. Function `TRANSLATE-PATHNAME`

`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`.

### 19.5.2. Function `PARSE-NAMESTRING`

`(`PARSE-NAMESTRING` `string` `&OPTIONAL` `host` `defaults` `&KEY` `start` `end` `junk-allowed`)` 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.

The [ANSI CL standard] behavior of recognizing logical pathnames when the `string` begins with some alphanumeric characters followed by a colon (#\:) can be very confusing (cf. `"c:/autoexec.bat"`, `"home:.clisprc"` and `"prep:/pub/gnu"`) and therefore is disabled by default. To enable the [ANSI CL standard] behavior, you should set `CUSTOM:*PARSE-NAMESTRING-ANSI*` to non-`NIL`.

### 19.5.3. Function `MERGE-PATHNAMES`

`(`MERGE-PATHNAMES` `pathname` [`default-pathname`])` returns a logical pathname only if `default-pathname` is a logical pathname. To construct a logical pathname from a string, the function `LOGICAL-PATHNAME` can be used.

When both `pathname` and `default-pathname` are relative pathnames, the behavior depends on `CUSTOM:*MERGE-PATHNAMES-ANSI*`: when it is `NIL`, then CLISP retains its traditional behavior: `(`MERGE-PATHNAMES` #P"x/" #P"y/")` evaluates to `#P"x/"`

Rationale. `MERGE-PATHNAMES` is used to specify default components for pathnames, so there is some analogy between `(`MERGE-PATHNAMES` a b)` and `(`OR` a b)`. Obviously, putting in the same default a second time should do the same as putting it in once: `(`OR` a b b)` is the same as `(`OR` a b)`, so `(`MERGE-PATHNAMES` (`MERGE-PATHNAMES` a b) b)` should be the same as `(`MERGE-PATHNAMES` a b)`.

(This question actually does matter because in Common Lisp there is no distinction between “pathnames with defaults merged-in” and “pathnames with defaults not yet applied”.)

Now, `(`MERGE-PATHNAMES` (`MERGE-PATHNAMES` #P"x/" #P"y/") #P"y/")` and `(`MERGE-PATHNAMES` #P"x/" #P"y/")` are `EQUAL` in CLISP (when `CUSTOM:*MERGE-PATHNAMES-ANSI*` is `NIL`), but not in implementations that strictly follow the [ANSI CL standard] spec. In fact, the above twice-default = once-default rule holds for all pathnames in CLISP.

Reversely, when `CUSTOM:*MERGE-PATHNAMES-ANSI*` is non-`NIL`, the normal [ANSI CL standard] behavior is exhibited: `(`MERGE-PATHNAMES` #P"x/" #P"y/")` evaluates to `#P"y/x/"`.

Rationale. “merge” is merge and not or.

### 19.5.4. Function `LOAD-LOGICAL-PATHNAME-TRANSLATIONS`

When the `host` argument to `LOAD-LOGICAL-PATHNAME-TRANSLATIONS` is not a defined logical host yet, we proceed as follows:

1. If both environment variables `LOGICAL_HOST_`host`_FROM` and `LOGICAL_HOST_`host`_TO` exist, then their values define the map of the `host`.
2. If the environment variable `LOGICAL_HOST_`host`` exists, its value is read from, and the result is passed to `(`SETF` `LOGICAL-PATHNAME-TRANSLATIONS`)`.
3. Variable `CUSTOM:*LOAD-LOGICAL-PATHNAME-TRANSLATIONS-DATABASE*` is consulted. Its value should be a list of files and/or directories, which are searched for in the `CUSTOM:*LOAD-PATHS*`, just like for `LOAD`. When the element is a file, it is `READ` from, Allegro CL-style, odd objects being host names and even object being their `LOGICAL-PATHNAME-TRANSLATIONS`. When the element is a directory, a file, named ``host`` or ``host`.host`, in that directory, is `READ` from once, CMUCL-style, the object read being the `LOGICAL-PATHNAME-TRANSLATIONS` of the `host`.

## Chapter 20. Files [CLHS-20]

## 20.1. The Files Dictionary [CLHS-20.2]

Function `RENAME-FILE`. `RENAME-FILE` always returns a non-logical pathname as its first value.

Function `PROBE-FILE`. `PROBE-FILE` cannot be used to check whether a directory exists. Use functions `EXT:PROBE-DIRECTORY` or `DIRECTORY` for this.

Function `FILE-AUTHOR`. `FILE-AUTHOR` always returns `NIL`, because the operating systems CLISP is ported to do not store a file's author in the file system. Some operating systems, such as Unix, have the notion of a file's owner, and some other Common Lisp implementations return the user name of the file owner. CLISP does not do this, because owner and author are not the same; in particular, authorship is preserved by copying, while ownership is not.

Function `EXT:PROBE-DIRECTORY`. `(`EXT:PROBE-DIRECTORY` `pathname`)` tests whether `pathname` exists and is a directory. It will, unlike `PROBE-FILE` or `TRUENAME`, not `SIGNAL` an `ERROR` if the parent directory of `pathname` does not exist.

Function `DELETE-FILE`. `(`DELETE-FILE` `pathname`)` deletes the pathname `pathname`, not its `TRUENAME`, and returns the absolute pathname it actually removed or `NIL` if `pathname` did not exist. When `pathname` points to a file which is currently open in CLISP, an `ERROR` is `SIGNAL`ed.

### 20.1.1. Function `DIRECTORY`

`(`DIRECTORY` `&OPTIONAL` `pathname` `&KEY` :FULL :CIRCLE `:IF-DOES-NOT-EXIST`)` can run in two modes:

- If `pathname` contains no name or type component, a list of all matching directories is produced. E.g., `(`DIRECTORY` "/etc/*/")` lists all subdirectories in the directory `#P"/etc/"`.
- Otherwise a list of all matching files is returned. E.g., `(`DIRECTORY` "/etc/*")` lists all regular files in the directory `#P"/etc/"`. If the `:FULL` argument is non-`NIL`, additional information is returned: 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`)`.

If you want all the files and subdirectories in the current directory, you should use `(`NCONC` (`DIRECTORY` "*/") (`DIRECTORY` "*"))`. If you want all the files and subdirectories in all the subdirectories under the current directory (similar to the ls `-R` UNIX command), use `(`NCONC` (`DIRECTORY` "**/") (`DIRECTORY` "**/*"))`.

Platform dependent: UNIX platforms only.
  If the `:CIRCLE` argument is non-`NIL`, the function avoids endless loops that may result from symbolic links.

The argument `:IF-DOES-NOT-EXIST` controls the treatment of links pointing to non-existent files and can take the following values:

`:DISCARD` (default)
  discard the bad directory entries
`:ERROR`
  `SIGNAL` an `ERROR` on bad directory entries (this corresponds to the default behavior of `DIRECTORY` in CMU CL)
`:KEEP`
  keep bad directory entries in the returned list (this roughly corresponds to the `(`DIRECTORY` ... `:TRUNAMEP` `NIL`)` call in CMU CL)
`:IGNORE`
  Similar to `:DISCARD`, but also do not signal an error when a directory is unaccessible (contrary to the [ANSI CL standard] specification).

Function `EXT:DIR`. `(`EXT:DIR` `&OPTIONAL` `pathname`)` is like `DIRECTORY`, but displays the pathnames instead of returning them. `(EXT:DIR)` shows the contents of the current directory.

Function `EXT:CD`. `(`EXT:CD` `pathname`)` sets it, `(`EXT:CD`)` returns it.

Platform dependent: UNIX platforms only.
  `(`EXT:CD` [`pathname`])` manages the current directory.
Platform dependent: Win32 platforms only.
  `(`EXT:CD` [`pathname`])` manages the current device and the current directory.

Function `EXT:DEFAULT-DIRECTORY`. `(`EXT:DEFAULT-DIRECTORY`)` is equivalent to `(`EXT:CD`)`. `(`SETF` (`EXT:DEFAULT-DIRECTORY`) `pathname`)` is equivalent to `(`EXT:CD` `pathname`)`, except for the return value.

Function `EXT:MAKE-DIR`. `(`EXT:MAKE-DIR` `directory-pathname`)` creates a new subdirectory.

Function `EXT:DELETE-DIR`. `(`EXT:DELETE-DIR` `directory-pathname`)` removes an (empty) subdirectory.

## Chapter 21. Streams [CLHS-21]

## 21.1. Interactive Streams [CLHS-21.1.1.1.3]

Interactive streams are those whose next input might depend on a prompt one might output.

## 21.2. Terminal interaction.

GNU readline

Platform dependent: UNIX platforms only, and only in CLISP built without compile-time flag `NO_READLINE` (and when GNU readline is installed on your machine already).

  Input through `*TERMINAL-IO*` uses the GNU readline library. Arrow keys can be used to move within the input history. The #\Tab key completes the `SYMBOL` name or `PATHNAME` that is being typed. See readline user manual for general details and clisp(1) for CLISP-specific extensions.

  ### Warning

  The GNU readline library is not used if standard input and standard output do not both refer to the same terminal. In some exotic cases, e.g., when running under gdb in an rxvt window under Cygwin, this may be determined incorrectly.

Macro `EXT:WITH-KEYBOARD`

Platform dependent: UNIX, Win32 platforms only.

  `*TERMINAL-IO*` is not the only stream that communicates directly with the user: During execution of the body of a `(`EXT:WITH-KEYBOARD` . `body`)` form, `EXT:*KEYBOARD-INPUT*` is the stream that reads the keystrokes from the keyboard. It returns every keystroke in detail, as `CHARACTER` or `SYS::INPUT-CHARACTER` with the following bits:

  `:hyper`
    (Platform dependent: Win32 platforms only.) if a non-standard key. These keys are: [Win32]: Function keys, cursor keypads, numeric keypad.
  slot `key`

    the key name, for non-standard keys:

    Platform dependent: UNIX, Win32 platforms only.

      key | value
      --- | ---
      F1..F12 | `:F1`..`:F12`
      Insert | `:Insert`
      Delete | `:Delete`
      Home | `:Home`
      End | `:End`
      Center | `:Center`
      PgUp | `:PgUp`
      PgDn | `:PgDn`
      Arrow keys | `:Left``:Right``:Up``:Down`

  slot `char`
    the ASCII code for standard keys
  `:super`
    (Platform dependent: Win32 platforms only.) 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.
  `:meta`
    (Platform dependent: Win32 platforms only.) if pressed together with the Alternate key.

  This keyboard input is not echoed on the screen. During execution of a `(`EXT:WITH-KEYBOARD` . `body`)` form, no input from `*TERMINAL-IO*` or any synonymous stream should be requested.

See also Section 30.1, “Extensions-2.1. Random Screen Access”.

## 21.3. The Streams Dictionary [CLHS-21.2]

### 21.3.1. Function `STREAM-ELEMENT-TYPE`

`STREAM-ELEMENT-TYPE` is `SETF`able. The `STREAM-ELEMENT-TYPE` of `STREAM`s created by the functions `OPEN`, `EXT:MAKE-PIPE-INPUT-STREAM` `EXT:MAKE-PIPE-OUTPUT-STREAM`, `EXT:MAKE-PIPE-IO-STREAM`, `SOCKET:SOCKET-ACCEPT`, `SOCKET:SOCKET-CONNECT` can be modified, if the old and the new `STREAM-ELEMENT-TYPE`s are either

- both equivalent to `CHARACTER` or `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`; or
- both equivalent to `(`UNSIGNED-BYTE` `n`)` or `(`SIGNED-BYTE` `n`)`, with the same `n`.

Functions `STREAM-ELEMENT-TYPE` and `(`SETF` `STREAM-ELEMENT-TYPE`)` are `GENERIC-FUNCTION`s, see Section 29.5.1, “Gray streams”.

#### 21.3.1.1. Binary input from `*STANDARD-INPUT*`

Note that you cannot change `STREAM-ELEMENT-TYPE` for some built-in streams, such as terminal streams, which is normally the value of `*TERMINAL-IO*`. Since `*STANDARD-INPUT*` normally is a `SYNONYM-STREAM` pointing to `*TERMINAL-IO*`, you cannot use `READ-BYTE` in the it.

Since CGI (Common Gateway Interface) provides the form data for METHOD="POST" on the stdin, and the server will not send you an `end-of-stream` on the end of the data, you will need to use `(`EXT:GETENV` `"CONTENT_LENGTH"`)` to determine how much data you should read from stdin. CLISP will detect that stdin is not a terminal and create a regular `FILE-STREAM` which can be passed to `(`SETF` `STREAM-ELEMENT-TYPE`)`. To test this functionality interactively, you will need to open the standard input in the binary mode:

    (let ((buf (MAKE-ARRAY (PARSE-INTEGER (EXT:GETENV "CONTENT_LENGTH"))
                           :element-type (UNSIGNED-BYTE 8))))
      (WITH-OPEN-STREAM (in (EXT:MAKE-STREAM :INPUT :ELEMENT-TYPE (UNSIGNED-BYTE 8)))
        (READ-SEQUENCE buf in))
      buf)

### 21.3.2. Function `EXT:MAKE-STREAM`

Function `EXT:MAKE-STREAM` creates a Lisp stream out of an OS file handle: `(`EXT:MAKE-STREAM` `object` `:DIRECTION` `:ELEMENT-TYPE` `:EXTERNAL-FORMAT` `:BUFFERED`)`

`object` designates an OS handle (a file descriptor), and should be one of the following:

number
  denotes the file descriptor of this value
`:INPUT`
  denotes CLISP process standard input
`:OUTPUT`
  denotes CLISP process standard output
`:ERROR`
  denotes CLISP process standard error
`STREAM`
  denotes the handle of this stream, which should be a `FILE-STREAM` or a `SOCKET:SOCKET-STREAM`

The handle is duplicated (with `dup/dup2`), so it is safe to `CLOSE` a `STREAM` returned by `EXT:MAKE-STREAM`.

### 21.3.3. Binary input, `READ-BYTE`, `EXT:READ-INTEGER` & `EXT:READ-FLOAT`

The function `(`EXT:READ-INTEGER` `stream` `element-type` `&OPTIONAL` `ENDIANNESS` `eof-error-p` `eof-value`)` reads a multi-byte `INTEGER` from `stream`. `stream` should be a stream with `STREAM-ELEMENT-TYPE` `(`UNSIGNED-BYTE` 8)`. `element-type` should be type equivalent to `(`UNSIGNED-BYTE` `n`)`, where `n` is a multiple of 8.

`(`EXT:READ-INTEGER` `stream` `element-type`)` is like `(`READ-BYTE` `stream`)` if `stream`'s `STREAM-ELEMENT-TYPE` were set to `element-type`, except that `stream`'s `FILE-POSITION` will increase by `n`/8 instead of 1.

Together with `(`SETF` `STREAM-ELEMENT-TYPE`)`, this function permits mixed character/binary input from a stream.

The function `(`EXT:READ-FLOAT` `stream` `element-type` `&OPTIONAL` `ENDIANNESS` `eof-error-p` `eof-value`)` reads a floating-point number in IEEE 754 binary representation from `stream`. `stream` should be a `STREAM` with `STREAM-ELEMENT-TYPE` `(`UNSIGNED-BYTE` 8)`. `element-type` should be type equivalent to `SINGLE-FLOAT` or `DOUBLE-FLOAT`.

Endianness. `ENDIANNESS` can be `:LITTLE` or `:BIG`. The default is `:LITTLE`, which corresponds to the `READ-BYTE` behavior in CLISP.

### 21.3.4. Binary output, `WRITE-BYTE`, `EXT:WRITE-INTEGER` & `EXT:WRITE-FLOAT`

The function `(`EXT:WRITE-INTEGER` `integer` `stream` `element-type` `&OPTIONAL` `ENDIANNESS`)` writes a multi-byte integer to `stream`. `stream` should be a `STREAM` with `STREAM-ELEMENT-TYPE` `(`UNSIGNED-BYTE` 8)`. `element-type` should be type equivalent to `(`UNSIGNED-BYTE` `n`)`, where `n` is a multiple of 8.

`(`EXT:WRITE-INTEGER` `integer` `stream` `element-type`)` is like `(`WRITE-BYTE` `integer` `stream`)` if `stream`'s `STREAM-ELEMENT-TYPE` were set to `element-type`, except that `stream`'s `FILE-POSITION` will increase by `n`/8 instead of 1.

Together with `(`SETF` `STREAM-ELEMENT-TYPE`)`, this function permits mixed character/binary output to a `STREAM`.

The function `(`EXT:WRITE-FLOAT` `float` `stream` `element-type` `&OPTIONAL` `ENDIANNESS`)` writes a floating-point number in IEEE 754 binary representation to `stream`. `stream` should be a `STREAM` with `STREAM-ELEMENT-TYPE` `(`UNSIGNED-BYTE` 8)`. `element-type` should be type equivalent to `SINGLE-FLOAT` or `DOUBLE-FLOAT`.

### 21.3.5. Bulk Input and Output

Function `READ-SEQUENCE`. In addition to `READ-SEQUENCE`, the following two functions are provided:

`EXT:READ-BYTE-SEQUENCE` performs multiple `READ-BYTE` operations:

  `(`EXT:READ-BYTE-SEQUENCE` `sequence` `stream` `&KEY` `:START` `:END` :NO-HANG)` fills the subsequence of `sequence` specified by `:START` and `:END` with `INTEGER`s 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). When `:NO-HANG` is non-`NIL`, does not block: treat input unavailability as `end-of-stream`.

  This function is especially efficient if `sequence` is a `(`VECTOR` (`UNSIGNED-BYTE` 8))` and `stream` is a file/pipe/socket `STREAM` with `STREAM-ELEMENT-TYPE` `(`UNSIGNED-BYTE` 8)`.

`EXT:READ-CHAR-SEQUENCE` performs multiple `READ-CHAR` operations:

  `(`EXT:READ-CHAR-SEQUENCE` `sequence` `stream` `&KEY` `: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/pipe/socket stream with `STREAM-ELEMENT-TYPE` `CHARACTER` or an input `STRING-STREAM`.

Function `WRITE-SEQUENCE`. In addition to `WRITE-SEQUENCE`, the following two functions are provided:

`EXT:WRITE-BYTE-SEQUENCE` performs multiple `WRITE-BYTE` operations:

  `(`EXT:WRITE-BYTE-SEQUENCE` `sequence` `stream` `&KEY` `:START` `:END`)` outputs the `INTEGER`s 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/pipe/socket `STREAM` with `STREAM-ELEMENT-TYPE` `(`UNSIGNED-BYTE` 8)`.

`EXT:WRITE-CHAR-SEQUENCE` performs multiple `WRITE-CHAR` operations:

  `(`EXT:WRITE-CHAR-SEQUENCE` `sequence` `stream` `&KEY` `:START` `:END` :NO-HANG)` outputs the characters of the subsequence of `sequence` specified by `:START` and `:END` to `:STREAM`. When `:NO-HANG` is non-`NIL`, does not block. Returns two values: `sequence` and the index of the first byte that was not output.

  This function is especially efficient if `sequence` is a `STRING` and `:STREAM` is a file/pipe/socket `STREAM` with `STREAM-ELEMENT-TYPE` `CHARACTER`.

Rationale. The rationale for `EXT:READ-CHAR-SEQUENCE`, `EXT:READ-BYTE-SEQUENCE`, `EXT:WRITE-CHAR-SEQUENCE` and `EXT:WRITE-BYTE-SEQUENCE` is that some `STREAM`s support both character and binary i/o, and when you read into a `SEQUENCE` that can hold both (e.g., `LIST` or `SIMPLE-VECTOR`) you cannot determine which kind of input to use. In such situation `READ-SEQUENCE` and `WRITE-SEQUENCE` `SIGNAL` an `ERROR`, while `EXT:READ-CHAR-SEQUENCE`, `EXT:READ-BYTE-SEQUENCE`, `EXT:WRITE-CHAR-SEQUENCE` and `EXT:WRITE-BYTE-SEQUENCE` work just fine.

### 21.3.6. Non-Blocking Input and Output

In addition to the standard functions `LISTEN` and `READ-CHAR-NO-HANG`, CLISP provides the following functionality facilitating non-blocking input and output, both binary and character.

`(`EXT:READ-CHAR-WILL-HANG-P` `stream`)`

  `EXT:READ-CHAR-WILL-HANG-P` queries the stream's input status. It returns `NIL` if `READ-CHAR` and `PEEK-CHAR` with a `peek-type` of `NIL` will return immediately. Otherwise it returns `T`. (In the latter case the standard `LISTEN` function would return `NIL`.)

  Note the difference with `(`NOT` (`LISTEN` `stream`))`: When the `end-of-stream` is reached, `LISTEN` returns `NIL`, whereas `EXT:READ-CHAR-WILL-HANG-P` returns `NIL`.

  Note also that `EXT:READ-CHAR-WILL-HANG-P` is not a good way to test for `end-of-stream`: If `EXT:READ-CHAR-WILL-HANG-P` returns `T`, this does not mean that the `stream` will deliver more characters. It only means that it is not known at this moment whether the `stream` is already at `end-of-stream`, or will deliver more characters.

`(`EXT:READ-BYTE-LOOKAHEAD` `stream`)`
  To be called only if `stream`'s `STREAM-ELEMENT-TYPE` is `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`. Returns `T` if `READ-BYTE` would return immediately with an `INTEGER` result. Returns `:EOF` if the `end-of-stream` is already known to be reached. If `READ-BYTE`'s value is not available immediately, returns `NIL` instead of waiting.
`(`EXT:READ-BYTE-WILL-HANG-P` `stream`)`
  To be called only if `stream`'s `STREAM-ELEMENT-TYPE` is `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`. Returns `NIL` if `READ-BYTE` will return immediately. Otherwise it returns true.
`(`EXT:READ-BYTE-NO-HANG` `stream` `&OPTIONAL` `eof-error-p` `eof-value`)`
  To be called only if `stream`'s `STREAM-ELEMENT-TYPE` is `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`. Returns an `INTEGER` or does `end-of-stream` handling, like `READ-BYTE`, if that would return immediately. If `READ-BYTE`'s value is not available immediately, returns `NIL` instead of waiting.

### 21.3.7. Function `FILE-POSITION`

Platform dependent: Win32 platforms only.
  `FILE-POSITION` works on any `:BUFFERED` `FILE-STREAM`. When a #\Newline is output to (respectively input from) a file stream, its file position is increased by 2 since #\Newline is encoded as CR/LF in the file.

### 21.3.8. Function `OPEN`

`OPEN` cannot handle files of size ≥ 4 GB.

`OPEN` accepts an additional keyword `:BUFFERED`.

The acceptable values for the arguments to the file/pipe/socket functions

`:ELEMENT-TYPE`

  types equivalent to `CHARACTER` or `(`UNSIGNED-BYTE` `n`)`, `(`SIGNED-BYTE` `n`)`; if the stream is to be un`:BUFFERED`, `n` must be a multiple of 8.

  If `n` is not a multiple of 8, CLISP will use the specified number of bits for i/o, and write the file length (as a number of `n`-bit bytes) in the preamble.

  This is done to ensure the input/output consistency: suppose you open a file with `:ELEMENT-TYPE` of `(`UNSIGNED-BYTE` 3)` and write 7 bytes (i.e., 21 bit) there. The underlying OS can do input/output only in whole 8-bit bytes. Thus the OS will report the size of the file as 3 (8-bit) bytes. Without the preamble CLISP will have no way to know how many 3-bit bytes to read from this file - 6, 7 or 8.

`:EXTERNAL-FORMAT`
  `EXT:ENCODING`s, (constant) `SYMBOL`s in the “CHARSET” package, `STRING`s (denoting `iconv`-based encodings), the symbol `:DEFAULT`, and the line terminator keywords `:UNIX`, `:MAC`, `:DOS`. The default encoding is `CUSTOM:*DEFAULT-FILE-ENCODING*`. This argument determines how the lisp `CHARACTER` data is converted to/from the 8-bit bytes that the underlying OS uses.
`:BUFFERED`

  `NIL`, `T`, or `:DEFAULT`. Have CLISP manage an internal buffer for input or output (in addition to the buffering that might be used by the underlying OS). Buffering is a known general technique to significantly speed up i/o.

  - for functions that create `SOCKET:SOCKET-STREAM`s and pipes, `:DEFAULT` is equivalent to `NIL`; it you are transmitting a lot of data then using buffering will significantly speed up your i/o;
  - for functions that open files, `:DEFAULT` means that buffered file streams will be returned for regular files and (on Unix) block-devices, and unbuffered file streams for special files.

  Note that some files, notably those on the `/proc` filesystem (on UNIX systems), are actually, despite their innocuous appearance, special files, so you might need to supply an explicit `:BUFFERED` `NIL` argument for them. Actually, CLISP detects that the file is a `/proc` file, so that one is covered, but there are probably more strange beasts there!

### 21.3.9. Function `CLOSE`

Function `CLOSE` is a `GENERIC-FUNCTION`, see Section 29.5.1, “Gray streams”.

`CLOSE` ignores its `:ABORT` argument.

`GET-OUTPUT-STREAM-STRING` returns the same value after `CLOSE` as it would before it.

`CLOSE` on an already closed `STREAM` does nothing and returns `T`.

If you do not `CLOSE` your `STREAM` explicitly, it will be closed at garbage-collection time automatically. This is not recommended though because garbage-collection is not deterministic. Please use `WITH-OPEN-STREAM` etc.

### 21.3.10. Function `OPEN-STREAM-P`

Function `OPEN-STREAM-P` is a `GENERIC-FUNCTION`, see Section 29.5.1, “Gray streams”.

### 21.3.11. Class `BROADCAST-STREAM`

`INPUT-STREAM-P` and `INTERACTIVE-STREAM-P` return false for `BROADCAST-STREAM`s.

### 21.3.12. Functions `EXT:MAKE-BUFFERED-INPUT-STREAM` and `EXT:MAKE-BUFFERED-OUTPUT-STREAM`

`(EXT:MAKE-BUFFERED-OUTPUT-STREAM `function`)` returns a buffered output `STREAM`. `function` is a `FUNCTION` expecting one argument, a `SIMPLE-STRING`. `WRITE-CHAR` collects the `CHARACTER`s in a `STRING`, until a newline character is written or `FORCE-OUTPUT`/`FINISH-OUTPUT` is called. Then `function` is called with a `SIMPLE-STRING` as argument, that contains the characters collected so far. `CLEAR-OUTPUT` dicards the characters collected so far.

`(EXT:MAKE-BUFFERED-INPUT-STREAM `function` `mode`)` returns a buffered input `STREAM`. `function` is a `FUNCTION` of 0 arguments that returns either `NIL` (stands for `end-of-stream`) or up to three values `string`, `start`, `end`. `READ-CHAR` returns the `CHARACTER`s of the current `string` one after another, as delimited by `start` and `end`, which default to `0` and `NIL`, respectively. When the `string` is consumed, `function` is called again. The `string` returned by `function` should not be changed, otherwise `function` should copy the `string` with `COPY-SEQ` or `SUBSEQ` beforehand. `mode` determines the behavior of `LISTEN` when the current `string` buffer is empty:

`NIL`
  the stream acts like a `FILE-STREAM`, i.e. `function` is called
`T`
  the stream acts like an interactive stream without `end-of-stream`, i.e. one can assume that further characters will always arrive, without calling `function`
`FUNCTION`
  this `FUNCTION` tells, upon call, if further non-empty `string`s are to be expected.

`CLEAR-INPUT` discards the rest of the current `string`, so `function` will be called upon the next `READ-CHAR` operation.

## Chapter 22. Printer [CLHS-22]

## 22.1. Multiple Possible Textual Representations [CLHS-22.1.1.1]

Variable `CUSTOM:*PRINT-CLOSURE*`. An additional variable `CUSTOM:*PRINT-CLOSURE*` controls whether compiled and interpreted functions (closures) are output in detailed form. If `CUSTOM:*PRINT-CLOSURE*` is non-`NIL`, compiled closures are output in #Y syntax which the reader understands. `CUSTOM:*PRINT-CLOSURE*` is initially set to `NIL`.

Variable `CUSTOM:*PRINT-RPARS*`. An additional variable `CUSTOM:*PRINT-RPARS*` controls the output of the right (closing) parentheses. If `CUSTOM:*PRINT-RPARS*` is non-`NIL`, closing parentheses which do not fit onto the same line as the the corresponding opening parenthesis are output just below their corresponding opening parenthesis, in the same column. `CUSTOM:*PRINT-RPARS*` is initially set to `NIL`.

Variable `CUSTOM:*PRINT-INDENT-LISTS*`. An additional variable `CUSTOM:*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. `CUSTOM:*PRINT-INDENT-LISTS*` is initially set to `1`.

Variable `CUSTOM:*PPRINT-FIRST-NEWLINE*`. An additional variable `CUSTOM:*PPRINT-FIRST-NEWLINE*` controls pretty-printing of multi-line objects. When `CUSTOM:*PPRINT-FIRST-NEWLINE*` is non-`NIL`, and the current line already has some characters on it, and the next object will be printed on several lines, and it does not start with a #\Newline, then a #\Newline is printed before the object. `CUSTOM:*PPRINT-FIRST-NEWLINE*` has no effect if `*PRINT-PRETTY*` is `NIL`. `CUSTOM:*PPRINT-FIRST-NEWLINE*` is initially set to `T`.

## 22.2. Printing Other Vectors [CLHS-22.1.3.7]

When `*PRINT-READABLY*` is true, other vectors are written as follows: if the `ARRAY-ELEMENT-TYPE` is `T`, the syntax `#(`x0` ... `xn-1`)` is used. Otherwise, the syntax `#A(`element-type` `dimensions` `contents`)` is used.

## 22.3. Printing Other Arrays [CLHS-22.1.3.8]

When `*PRINT-READABLY*` is true, other arrays are written as follows: if the `ARRAY-ELEMENT-TYPE` is `T`, the syntax `#`rank`A `contents`` is used. Otherwise, the syntax `#A(`element-type` `dimensions` `contents`)` is used.

## 22.4. The Lisp Pretty Printer [CLHS-22.2]

The Lisp Pretty Printer implementation is not perfect yet. `PPRINT-LOGICAL-BLOCK` does not respect `*PRINT-LINES*`.

### 22.4.1. Pretty Print Dispatch Table [CLHS-22.2.1.4]

A pprint dispatch table is a `CONS` of a symbol `*PRINT-PPRINT-DISPATCH*` an alist which maps types into priorities and print functions. Their use is strongly discouraged because of the performance issues: when `*PRINT-PPRINT-DISPATCH*` is non-trivial and `*PRINT-PRETTY*` is non-`NIL`, printing of every object requires a lookup in the table, which entails many calls to `TYPEP` (which cannot be made fast enough).

## 22.5. The Printer Dictionary [CLHS-22.4]

Functions `WRITE` & `WRITE-TO-STRING`. The functions `WRITE` and `WRITE-TO-STRING` have an additional keyword argument `:closure` which is used to bind `CUSTOM:*PRINT-CLOSURE*`.

### 22.5.1. Function `FORMAT`

The additional `FORMAT` instruction ~! is similar to `~/`, but avoids putting a function name into a string, thus, even if the function is not interned in the “COMMON-LISP-USER” package, you might not need to specify the package explicitly. `(`FORMAT` `stream` "~args!" `function` `object`)` is equivalent to `(`FUNCALL` `function` `stream` `object` `colon-modifier-p` `atsign-modifier-p` `args`)`.

`FORMAT` `~R` and `FORMAT` `~:R` can output only integers in the range `|n| < `1066``. The output is in English, according to the American conventions, and these conventions are identical to the British conventions only in the range `|n| < `109``.

`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*` does not matter if `*PRINT-READABLY*` is true.

`FORMAT` `~T` can determine the current column of any built-in stream.

### 22.5.2. pathnames

Pathnames are printed as follows: If `*PRINT-ESCAPE*` is `NIL`, only the namestring is printed; otherwise it is printed with the `#P""` syntax, as per [ANSI CL standard] Issue PRINT-READABLY-BEHAVIOR:CLARIFY. But, if `*PRINT-READABLY*` is true, we are in trouble as `#P""` is ambiguous (which is verboten when `*PRINT-READABLY*` is true), while being mandated by the [ANSI CL standard]. Therefore, in this case, CLISP's behavior is determined by the value of `CUSTOM:*PRINT-PATHNAMES-ANSI*`: when it is `NIL`, we print pathnames like this: `#-CLISP #P"" #+CLISP #S(PATHNAME ...)`. Otherwise, when the variable `CUSTOM:*PRINT-PATHNAMES-ANSI*` is non-`NIL`, the `#P""` notation is used as per 1.5.1.4.1 Resolution of Apparent Conflicts in Exceptional Situations.

### Warning

When both `*PRINT-READABLY*` and `CUSTOM:*PRINT-PATHNAMES-ANSI*` are non-`NIL` and the namestring will be parsed to a dissimilar object (with the current value of `CUSTOM:*PARSE-NAMESTRING-DOT-FILE*`), an `ERROR` of type `PRINT-NOT-READABLE` is `SIGNAL`ed.

### 22.5.3. Miscellaneous Issues

`*PRINT-CASE*` controls the output not only of symbols, but also of characters and some `#<...>` objects.

In the absence of `SYS::WRITE-FLOAT-DECIMAL` , floating point numbers are output in radix 2. This function is defined in `"floatpri.lisp"` and is not available if you run CLISP without a memory image (which you should never do anyway!)

If `*PRINT-READABLY*` is true, `*READ-DEFAULT-FLOAT-FORMAT*` has no influence on the way floating point numbers are printed.

Platform dependent: UNIX, Win32 platforms only.
  `*PRINT-PRETTY*` is initially `NIL` but set to `T` in `#P"config.lisp"`. This makes screen output prettier.

`*PRINT-ARRAY*` is initially set to `T`.

## Chapter 23. Reader [CLHS-23]

This is the list of objects whose external representation cannot be meaningfully read in:

Table 23.1. Unreadable objects

format | meaning
--- | ---
`#<`type` ...>` | all `STRUCTURE-OBJECT`s lacking a keyword constructor
`#<ARRAY `type` `dimensions`>` | all `ARRAY`s except `STRING`s, if `*PRINT-ARRAY*` is `NIL`
`#<SYSTEM-FUNCTION `name`>` | built-in function written in C
`#<ADD-ON-SYSTEM-FUNCTION `name`>` | other function written in C
`#<SPECIAL-OPERATOR `name`>` | special operator handler
`#<COMPILED-CLOSURE `name`>` | compiled function, if `CUSTOM:*PRINT-CLOSURE*` is `NIL`
`#<CLOSURE `name` ...>` | interpreted function
`#<FRAME-POINTER #x...>` | pointer to a stack frame
`#<DISABLED POINTER>` | frame pointer which has become invalid on exit from the corresponding `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`>` | macro expander (defined by `DEFMACRO` and friends)
`#<`FFI:FOREIGN-POINTER` #x...>` | foreign pointer (Platform dependent: UNIX, Win32 platforms only.)
`#<`FFI:FOREIGN-ADDRESS` #x...>` | foreign address (Platform dependent: UNIX, Win32 platforms only.)
`#<`FFI:FOREIGN-VARIABLE` `name` #x...>` | foreign variable (Platform dependent: UNIX, Win32 platforms only.)
`#<`FFI:FOREIGN-FUNCTION` `name` #x...>` | foreign function (Platform dependent: UNIX, Win32 platforms only.)
`#<UNBOUND>` | "value" of a symbol without value, "value" of an unsupplied optional or keyword argument
`#<SPECIAL REFERENCE>` | environment marker for variables declared `SPECIAL`
`#<DOT>` | internal `READ` result for "."
`#<END OF FILE>` | internal `READ` result, when the end of file is reached
`#<READ-LABEL ...>` | intermediate `READ` result for `#n#`
`#<ADDRESS #x...>` | machine address, should not occur
`#<SYSTEM-POINTER #x...>` | should not occur

## 23.1. characters

#\Code allows input of characters of arbitrary code: e.g., #\Code231 reads as the character `(`CODE-CHAR` 231.)`.

## 23.2. Additional read dispatch macros

- #Y is used to read compiled functions and to set the current input `STREAM`'s `EXT:ENCODING`.

- `#""` is used to read pathnames: `#"test.lisp"` is the value of `(`PATHNAME` "test.lisp")`

  Platform dependent: Win32 platforms only.
    As in all strings, backslashes must be written twice here: `#"A:\\programs\\test.lisp"`

## 23.3. Function `READTABLE-CASE`

When the value of `(`READTABLE-CASE` `readtable`)` is `:INVERT`, it applies to the package name and the symbol name of a symbol separately (not to the entire token at once). An alternative to the use of `READTABLE-CASE` is the use of the `:CASE-SENSITIVE` option of `MAKE-PACKAGE` and `DEFPACKAGE`.

## Chapter 24. System Construction [CLHS-24]

## 24.1. The System Construction Dictionary [CLHS-24.2]

The compiler can be called not only by the functions `COMPILE`, `COMPILE-FILE` and `DISASSEMBLE`, but also by the declaration `(compile)`.

### 24.1.1. Function `COMPILE-FILE`

`(`COMPILE-FILE` `input-file` `&KEY` `:OUTPUT-FILE` :LISTING `:WARNINGS` `:VERBOSE` `:PRINT` `:EXTERNAL-FORMAT`)` compiles a file to platform-independent bytecode.

Options for `COMPILE-FILE`

`input-file`
  should be a pathname designator.
`:OUTPUT-FILE`
  should be `NIL` or `T` or a pathname designator or an output `STREAM`. The default is `T`.
`:LISTING`
  should be `NIL` or `T` or a pathname designator or an output `STREAM`. The default is `NIL`.
`:WARNINGS`
  specifies whether warnings should also appear on the screen.
`:VERBOSE`
  specifies whether error messages should also appear on the screen.
`:PRINT`
  specifies whether an indication which forms are being compiled should appear on the screen.

The variables `CUSTOM:*COMPILE-WARNINGS*`, `*COMPILE-VERBOSE*`, `*COMPILE-PRINT*` provide defaults for the `:WARNINGS`, `:VERBOSE`, `:PRINT` keyword arguments, respectively, and are bound by `COMPILE-FILE` to the values of the arguments, i.e., these arguments are recursive.

For each input file (default file type: `#P".lisp"`) the following files are generated:

File | When | Default file type | Contents
--- | --- | --- | ---
output file | only if `:OUTPUT-FILE` is not `NIL` | `#P".fas"` | can be loaded using the `LOAD` function
auxiliary output file | only if `:OUTPUT-FILE` is not `NIL` | `#P".lib"` | used by `COMPILE-FILE` when compiling a `REQUIRE` form referring to the input file
listing file | only if `:LISTING` is not `NIL` | `#P".lis"` | disassembly of the output file
C output file | only if `:OUTPUT-FILE` is not `NIL` | `#P".c"` | foreign function interface; this file is deleted if it is empty

### Warning

If you have two files in the same directory - `#P"foo.lisp"` and `#P"foo.c"`, and you compile the first file with CLISP, the second file will be clobbered if you have any “FFI” forms in the first one!

### 24.1.2. Function `COMPILE-FILE-PATHNAME`

The default for the `:OUTPUT-FILE` argument is `T`, which means `#P".fas"`.

### 24.1.3. Function `REQUIRE`

The function `REQUIRE` receives as the optional argument either a `PATHNAME` or a `LIST` of `PATHNAME`s: files to be `LOAD`ed if the required module is not already present.

At compile time, `(`REQUIRE` `#P"foo"`)` forms are treated specially: `CUSTOM:*LOAD-PATHS*` is searched for `#P"foo.lisp"` and `#P"foo.lib"`. If the latest such file is a `#P".lisp"`, it is compiled; otherwise the `#P".lib"` is loaded.

The `#P".lib"` is a “header” file which contains the constant, variable, inline and macro definitions necessary for compilation of the files that `REQUIRE` this file, but not the function definitions and calls that are not necessary for that. Thus it is not necessary to either enclose `REQUIRE` forms in `EVAL-WHEN` or to load the required files in the makefiles: if you have two files, `#P"foo.lisp"` and `#P"bar.lisp"`, and the latter requires the former, you can write in your `#P"Makefile"`:

    all: foo.fas bar.fas

    foo.fas: foo.lisp
    	clisp -c foo

    bar.fas: bar.lisp foo.fas
            clisp -c bar

instead of the more cumbersome (and slower, since `#P".lib"`s are usually smaller and load faster that `#P".fas"`s):

    bar.fas: bar.lisp foo.fas
            clisp -i foo -c bar

Thus, you do not need to `(`LOAD` `#P"foo"`)` in order to `(`COMPILE-FILE` `#P"bar.lisp"`)`. If memory is tight, and if `#P"foo.lisp"` contains only a few inline functions, macros, constants or variables, this is a space and time saver. If `#P"foo.lisp"` does a lot of initializations or side effects when being loaded, this is important as well.

### 24.1.4. Function `LOAD`

`LOAD` has four additional keywords `:ECHO`, `:COMPILING`, `:EXTRA-FILE-TYPES`, and `:OBSOLETE-ACTION`.

`(`LOAD` `filename` `&KEY` `:VERBOSE` `:PRINT` `:ECHO` `:IF-DOES-NOT-EXIST` `:COMPILING` `:EXTRA-FILE-TYPES` `:OBSOLETE-ACTION`)`

`: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 `CUSTOM:*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 default is `CUSTOM:*LOAD-COMPILING*`, which is initially `NIL`.
`:EXTRA-FILE-TYPES` `LIST`

  Specifies the additional file types considered for loading, in addition to `CUSTOM:*SOURCE-FILE-TYPES*` (which is initially `("lisp" "lsp" "cl")`) and `CUSTOM:*COMPILED-FILE-TYPES*` (which is initially `("fas")`).

  When `filename` does not spefify a unique file (e.g., `filename` is `#P"foo"` and both `#P"foo.lisp"` and `#P"foo.fas"` are found in the `CUSTOM:*LOAD-PATHS*`), then the newest file is loaded.

`:OBSOLETE-ACTION` `NIL`
  Specifies the action to take when loading a `#P".fas"` with a different bytecode version from the one supported by this CLISP version. The possible actions are `:DELETE` to delete the `#P".fas"` and `:ERROR` to `SIGNAL` an `ERROR`. The default action is to `WARN` and look for another matching file. If no file can be loaded and `:IF-DOES-NOT-EXIST` is non-`NIL`, an `ERROR` is `SIGNAL`ed. The default is `CUSTOM:*LOAD-OBSOLETE-ACTION*`, which is initially `NIL`.

The variables `*LOAD-VERBOSE*`, `*LOAD-PRINT*`, `CUSTOM:*LOAD-OBSOLETE-ACTION*`, `CUSTOM:*LOAD-COMPILING*`, and `CUSTOM:*LOAD-ECHO*` are bound by `LOAD` when it receives a corresponding keyword argument (`:VERBOSE`, `:PRINT`, `:OBSOLETE-ACTION`, `:COMPILING`, and `:ECHO`), i.e., these arguments are recursive, just like the arguments `:WARNINGS`, `:VERBOSE`, and `:PRINT` for `COMPILE-FILE`.

Variable `CUSTOM:*LOAD-PATHS*`. The variable `CUSTOM:*LOAD-PATHS*` contains a list of directories where the files are looked for - in addition to the specified or current directory - by `LOAD`, `REQUIRE`, `COMPILE-FILE` and `LOAD-LOGICAL-PATHNAME-TRANSLATIONS`.

### 24.1.5. Variable `*FEATURES*`

The variable `*FEATURES*` initially contains the following symbols

Default `*FEATURES*`

`:CLISP`
  the name of this implementation
`:ANSI-CL`
  CLISP purports to conform to [ANSI CL standard]
`:COMMON-LISP`
  required by [ANSI CL standard]
`:INTERPRETER`
  `EVAL` is implemented
`:COMPILER`
  `COMPILE` and `COMPILE-FILE` are implemented
`:SOCKETS`
  see Section 30.5, “Extensions-2.5. Socket Streams”
`:GENERIC-STREAMS`
  see Section 29.5, “Extensions-1.5. Defining new kinds of Streams”
`:LOGICAL-PATHNAMES`
  Logical Pathnames are implemented
`:FFI`
  if a foreign function interface (see Section 30.3, “Extensions-2.3. The Foreign Function Call Facility”) is supported (Platform dependent: many UNIX, Win32 platforms only)
`:GETTEXT`
  if internationalization (see Section 29.3, “Extensions-1.3. Internationalization”) using the GNU gettext package is supported (Platform dependent: most UNIX platforms only)
`:UNICODE`
  if UNICODE (ISO 10646) characters are supported (see “CHARSET”)
`:LOOP`
  `LOOP` is implemented
`:CLOS`
  CLOS is implemented
`:WIN32`
  if `hardware` = PC (clone) and `operating system` = Win32 (Windows 95/98/NT/Me/2000/XP)
`:PC386`
  if `hardware` = PC (clone) with a 386/486/586/686/786 CPU
`:UNIX`
  if `operating system` = Unix (in this case the `hardware` is irrelevant!)
`:CYGWIN`
  if CLISP is using the Cygwin UNIX compatibility layer on top of Win32 (in that case `:UNIX` is also present)

Each module should add the appropriate keyword, e.g., `:SYSCALLS`, `:DIR-KEY`, `:REGEXP`, `:PCRE`, etc.

## Chapter 25. Environment [CLHS-25]

## 25.1. Debugging Utilities [CLHS-25.1.2]

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 loop (called "break loops") which are similar to the main read-eval-print loop except for the prompt and the set of available commands. Commands must be typed literally, in any case, without surrounding quotes or white space. Each command has a keyword abbreviation, indicated in the second column.

Table 25.1. Commands common to the main loop, the debugger and the stepper

command | abbreviation | operation
--- | --- | ---
Help | :h | prints a list of available commands

Table 25.2. Commands common to the debugger and the stepper

command | abbreviation | operation
--- | --- | ---
Abort | :a | abort to the next most recent read-eval-print loop
Unwind | :uw | abort to the next most recent read-eval-print loop
Quit | :q | quit to the top 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.

Table 25.3. Commands common to the debugger and the stepper

command | abbreviation | operation
--- | --- | ---
Error | :e | print the last error message.
Inspect | :i | inspect the last error message.
Mode-1 | :m1 | sets the current mode to 1: all the stack elements are considered. This mode works fine for debugging compiled functions.
Mode-2 | :m2 | sets the current mode to 2: all the frames are considered.
Mode-3 | :m3 | sets the current mode to 3: only lexical frames (frames that correspond to special forms that modify the lexical environment) are considered.
Mode-4 | :m4 | 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 | :m5 | sets the current mode to 5: only `APPLY` frames are considered. Every invocation of an interpreted function corresponds to one `APPLY` frame.
Where | :w | shows the current stack frame.
Up | :u | goes up one frame, i.e., to the caller if in mode-5
Down | :d | does down one frame, i.e., to the callee if in mode-5
Top | :t | goes to top frame, i.e., to the top-level form if in mode-4
Bottom | :b | goes to bottom (most recent) frame, i.e., most probably to the form or function that caused the debugger to be entered.
Backtrace | :bt | lists the stack in current mode, bottom frame first, top frame last.
Backtrace-1 | :bt1 | lists the stack in mode 1.
Backtrace-2 | :bt2 | lists the stack in mode 2.
Backtrace-3 | :bt3 | lists the stack in mode 3.
Backtrace-4 | :bt4 | lists the stack in mode 4.
Backtrace-5 | :bt5 | lists the stack in mode 5.
Frame-limit | :fl | set the frame-limit: this many frames will be printed in a backtrace at most.
Backtrace-l | :bl | limit of frames to print will be prompted for.

If the current stack frame is an `EVAL` or `APPLY` frame, the following commands are available as well:

Table 25.4. Commands specific to `EVAL`/`APPLY`

command | abbreviation | operation
--- | --- | ---
Break+ | :br+ | 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 `EXT:*TRACE-VALUES*` containing a list of its values.
Break- | :br- | removes a breakpoint from the current frame.
Redo | :rd | re-evaluates the corresponding form or function call. This command can be used to restart parts of a computation without aborting it entirely.
Return | :rt | leaves the current frame. You will be prompted for the return values.

Table 25.5. Commands specific to the debugger

command | abbreviation | operation
--- | --- | ---
Continue | :c | continues evaluation of the program.

Table 25.6. Commands specific to the stepper

command | abbreviation | operation
--- | --- | ---
Step | :s | step into a form: evaluate this form in single step mode
Next | :n | step over a form: evaluate this form at once
Over | :o | step over this level: evaluate at once up to the next return
Continue | :c | 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.

## 25.2. The Environment Dictionary [CLHS-25.2]

### 25.2.1. Function `DISASSEMBLE`

Platform dependent: UNIX platforms only.
  `DISASSEMBLE` can disassemble to machine code, provided that GNU gdb is present. In that case the argument may be a `EXT:SYSTEM-FUNCTION`, a `FFI:FOREIGN-FUNCTION`, a special operator indicator, a symbol denoting one of these, a number, or a string.

### 25.2.2. Function `EXT:UNCOMPILE`

The function `EXT:UNCOMPILE` does the converse of `COMPILE`: `(`EXT:UNCOMPILE` `function`)` reverts a compiled `function` (name), that has been entered or loaded in the same session and then compiled, back to its interpreted form.

### 25.2.3. Function `DOCUMENTATION`

No on-line documentation is available for the system functions (yet).

Function `EXT:CLHS`. [Common Lisp HyperSpec] access is provided via `(`EXT:CLHS` `symbol` `&KEY` `:BROWSER`)` function, which uses your web browser. `browser` (defaults to `CUSTOM:*BROWSER*`) should be a valid keyword in the `CUSTOM:*BROWSERS*` alist.

### 25.2.4. Macro `TRACE`

`(`TRACE` `function` ...)` makes the functions `function`, ... traced. `function` should be either a symbol or a list `(`symbol` `&KEY` `:suppress-if` `:step-if` `:pre` `:post` `:pre-break-if` `:post-break-if` `:pre-print` `:post-print` `:PRINT`)`, where

`: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 following variables:

`EXT:*TRACE-FUNCTION*`
  the function itself
`EXT:*TRACE-ARGS*`
  the arguments to the function
`EXT:*TRACE-FORM*`
  the function/macro call as form
`EXT:*TRACE-VALUES*`
  after return from the function: the list of return values from the function call

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.

Variable `CUSTOM:*TRACE-INDENT*`. If you want the `TRACE` level to be indicated by the indentation in addition to the printed numbers, set `CUSTOM:*TRACE-INDENT*` to non-`NIL`. Initially it is `NIL` since many nested traced calls will easily exhaust the available line length.

### 25.2.5. Function `INSPECT`

The function `INSPECT` takes a keyword argument `:frontend`, which specifies the way CLISP will interact with the user.

Available `:frontend`s for `INSPECT` in CLISP

`:tty`
  The interaction is conducted via the `*TERMINAL-IO*` stream. Please use the `:h` command to get the list of all available commands.
`:http`

  A window in your Web browser (specified by the `:BROWSER` keyword argument) is opened and it is controlled by CLISP via a `SOCKET:SOCKET-STREAM`, using the HTTP protocol. You should be able to use all the standard browser features.

  Since CLISP is not multitasking at this time, you will not be able to do anything else during an `INSPECT` session. Please click on the `quit` link to terminate the session.

  Please be aware though, that once you terminate an `INSPECT` session, all links in all `INSPECT` windows in your browser will become obsolete and using them in a new `INSPECT` session will result in unpredictable behavior.

### 25.2.6. Function `ROOM`

The function `ROOM` 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 `EXT:GC` starts a global garbage-collection and its return value has the same meaning as the second value of `ROOM`.

### 25.2.7. Macro `TIME`

The timing data printed by the macro `TIME` includes:

the real time ("wall" time),
the run time (processor time for this process),
the number of bytes allocated, and
the number of garbage-collections performed, if any.

The macro `EXT:TIMES` (mnemonic: "TIME and Space") is like the macro `TIME`: `(`EXT:TIMES` `form`)` evaluates the `form`, and, as a side effect, outputs detailed information about the memory allocations caused by this evaluation. It also prints everything printed by `TIME`.

### 25.2.8. Function `ED`

The function `ED` calls the external editor specified by the value of `(`EXT:GETENV` "EDITOR")` or, failing that, the value of the variable `CUSTOM:*EDITOR*` (see `#P"config.lisp"`). If the argument is a function name which was defined in the current session (not loaded from a file), the program text to be edited is a pretty-printed version (without comments) of the text which was used to define the function.

### 25.2.9. Clock Time

Default Time Zone

Platform dependent: unknown platforms only.
  The variable `CUSTOM:*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 time zone in a decoded time must not necessarily be an `INTEGER`, but (as `FLOAT` or `RATIONAL` number) it should be a multiple of `1/3600`.

Table 25.7. Time granularity

platform | UNIX | Win32 |  |
`INTERNAL-TIME-UNITS-PER-SECOND` | 50 | 1,000,000 | 10,000,000 |

`GET-INTERNAL-RUN-TIME` returns the amount of run time consumed by the current CLISP process since its startup.

### 25.2.10. Machine

Platform dependent: UNIX platform only.
  The functions `SHORT-SITE-NAME`, `LONG-SITE-NAME` should be defined in a site-specific `#P"config.lisp"` file. The default implementations try to read the value of the environment variable `ORGANIZATION`, and, failing that, call `uname`.
Platform dependent: Win32 platform only.
  The functions `SHORT-SITE-NAME`, `LONG-SITE-NAME` should be defined in a site-specific `#P"config.lisp"` file. The default implementations try to read the registry.
Platform dependent: unknown platforms only.
  The functions `MACHINE-TYPE`, `MACHINE-VERSION`, `MACHINE-INSTANCE` and `SHORT-SITE-NAME`, `LONG-SITE-NAME` should be defined by every user in his user-specific `#P"config.lisp"` file.

### 25.2.11. Functions `APROPOS` & `APROPOS-LIST`

The search performed by `APROPOS` and `APROPOS-LIST` is case-insensitive.

Variable `CUSTOM:*APROPOS-DO-MORE*`. You can make `APROPOS` print more information about the symbols it found by setting `CUSTOM:*APROPOS-DO-MORE*` to a list containing some of `:FUNCTION`, `:VARIABLE`, `:TYPE`, and `:CLASS` or just set it to `T` to get all of the values.

Variable `CUSTOM:*APROPOS-MATCHER*`. You can make `APROPOS` and `APROPOS-LIST` be more flexible in their search by setting `CUSTOM:*APROPOS-MATCHER*` to a `FUNCTION` of one argument, a pattern (a `STRING`), returning a new `FUNCTION` of one argument, a `SYMBOL` name (also a `STRING`), which returns non-`NIL` when the symbol name matches the pattern for the purposes of `APROPOS`. When `CUSTOM:*APROPOS-MATCHER*` is `NIL`, `SEARCH` is used. Some modules come with functions which can be used for `CUSTOM:*APROPOS-MATCHER*`, e.g., `REGEXP:REGEXP-MATCHER`, `WILDCARD:WILDCARD-MATCHER`, `PCRE:PCRE-MATCHER`.

### 25.2.12. Function `DRIBBLE`

If `DRIBBLE` is called with an argument, and dribbling is already enabled, a warning is printed, and the new dribbling request is ignored.

Dribbling is implemented via a kind (but not recognizable subtype) of `TWO-WAY-STREAM`, named `EXT:DRIBBLE-STREAM`. If you have a `source` bidirectional `STREAM` `x` and you want all transactions (input and output) on `x` to be copied to the `target` output `STREAM` `y`, you can do

      (DEFVAR *loggable* x)
      (SETQ x (MAKE-SYNONYM-STREAM '*loggable*))
      (DEFUN toggle-logging (&OPTIONAL s)
        (MULTIPLE-VALUE-BIND (so ta) (dribble-toggle *loggable* s)
          (WHEN (STREAMP so) (SETQ *loggable* so))
          ta))
      (toggle-logging y)     ; start logging
      ...
      (toggle-logging)       ; finish logging
      ...
      (toggle-logging y)     ; restart logging
      ...
      (toggle-logging)       ; finish logging
      (CLOSE y)

`(`EXT:DRIBBLE-STREAM` `stream`)`
  When `stream` is a `EXT:DRIBBLE-STREAM`, returns two values: the `source` and the `target` streams. Otherwise returns `NIL`.
`(`EXT:DRIBBLE-STREAM-P` `stream`)`
  When `stream` is a `EXT:DRIBBLE-STREAM`, returns `T`, otherwise returns `NIL`.
`(`EXT:DRIBBLE-STREAM-SOURCE` `stream`)`
  When `stream` is a `EXT:DRIBBLE-STREAM`, returns its `source` stream, otherwise signals a `TYPE-ERROR`.
`(`EXT:DRIBBLE-STREAM-TARGET` `stream`)`
  When `stream` is a `EXT:DRIBBLE-STREAM`, returns its `target` stream, otherwise signals a `TYPE-ERROR`.
`(`EXT:MAKE-DRIBBLE-STREAM` `source` `target`)`
  Create a new `EXT:DRIBBLE-STREAM`.
`(`EXT:DRIBBLE-TOGGLE` `stream` `&OPTIONAL` `pathname`)`
  When `stream` is a `EXT:DRIBBLE-STREAM` and `pathname` is `NIL`, writes a dribble termination note to the `stream`'s `target` `STREAM` and returns `stream`'s `source` and `target` `STREAM`s; when `stream` is not a `EXT:DRIBBLE-STREAM` and `pathname` is non-`NIL`, creates a new `EXT:DRIBBLE-STREAM`, dribbling from `stream` to `pathname`, writes a dribble initialization note to `pathname`, and return the `EXT:DRIBBLE-STREAM` (the second value is the `target` `STREAM`); otherwise `WARN` that no appropriate action may be taken. `pathname` may be an open output `STREAM` or a pathname designator. See above for the sample usage. See also `#P"src/dribble.lisp"` in the CLISP source tree.

### 25.2.13. Function `LISP-IMPLEMENTATION-VERSION`

`LISP-IMPLEMENTATION-VERSION` returns the numeric version (like `3.14`), and the release date (like `"1999-07-21"`). When running on the same machine on which CLISP was built, it appends the binary build and memory image dump date in universal time (like `3141592654`). When running on a different machine, it appends the `MACHINE-INSTANCE` of the machine on which it was built.

### 25.2.14. Function `EXT:ARGV`

This function will return a fresh `SIMPLE-VECTOR` of `STRING` command line arguments passed to the runtime, including those already processed by CLISP. Use `EXT:*ARGS*` instead of this function to get the arguments for your program.

## Chapter 26. Glossary [CLHS-26]

No notes.

## Chapter 27. Appendix [CLHS-a]

No notes.

## Chapter 28. X3J13 Issue Index [CLHS-ic]

This is the list of ANSI CL issues and their current status in CLISP, i.e., whether CLISP supports code that makes use of the functionality specified by the vote.

X3J13 Issues

&ENVIRONMENT-BINDING-ORDER:FIRST
  yes
ACCESS-ERROR-NAME
  yes
ADJUST-ARRAY-DISPLACEMENT
  yes
ADJUST-ARRAY-FILL-POINTER
  yes
ADJUST-ARRAY-NOT-ADJUSTABLE:IMPLICIT-COPY
  yes
ALLOCATE-INSTANCE:ADD
  yes
ALLOW-LOCAL-INLINE:INLINE-NOTINLINE
  yes
ALLOW-OTHER-KEYS-NIL:PERMIT
  yes
AREF-1D
  yes
ARGUMENT-MISMATCH-ERROR-AGAIN:CONSISTENT
  yes
ARGUMENT-MISMATCH-ERROR-MOON:FIX
  yes
ARGUMENT-MISMATCH-ERROR:MORE-CLARIFICATIONS
  yes, except for argument list checking in `CALL-NEXT-METHOD` in compiled code (items 11,12)
ARGUMENTS-UNDERSPECIFIED:SPECIFY
  yes
ARRAY-DIMENSION-LIMIT-IMPLICATIONS:ALL-FIXNUM
  no
ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING
  yes
ASSERT-ERROR-TYPE:ERROR
  yes
ASSOC-RASSOC-IF-KEY
  yes
ASSOC-RASSOC-IF-KEY:YES
  yes
BOA-AUX-INITIALIZATION:ERROR-ON-READ
  yes
BREAK-ON-WARNINGS-OBSOLETE:REMOVE
  yes
BROADCAST-STREAM-RETURN-VALUES:CLARIFY-MINIMALLY
  no
BUTLAST-NEGATIVE:SHOULD-SIGNAL
  yes
CHANGE-CLASS-INITARGS:PERMIT
  yes
CHAR-NAME-CASE:X3J13-MAR-91
  yes
CHARACTER-LOOSE-ENDS:FIX
  yes
CHARACTER-PROPOSAL:2
  yes
CHARACTER-PROPOSAL:2-1-1
  yes
CHARACTER-PROPOSAL:2-1-2
  yes
CHARACTER-PROPOSAL:2-2-1
  yes
CHARACTER-PROPOSAL:2-3-1
  yes
CHARACTER-PROPOSAL:2-3-2
  yes
CHARACTER-PROPOSAL:2-3-3
  yes
CHARACTER-PROPOSAL:2-3-4
  yes
CHARACTER-PROPOSAL:2-3-5
  yes
CHARACTER-PROPOSAL:2-3-6
  yes
CHARACTER-PROPOSAL:2-4-1
  yes
CHARACTER-PROPOSAL:2-4-2
  yes
CHARACTER-PROPOSAL:2-4-3
  yes
CHARACTER-PROPOSAL:2-5-2
  yes
CHARACTER-PROPOSAL:2-5-6
  yes
CHARACTER-PROPOSAL:2-5-7
  yes
CHARACTER-PROPOSAL:2-6-1
  yes
CHARACTER-PROPOSAL:2-6-2
  yes
CHARACTER-PROPOSAL:2-6-3
  yes
CHARACTER-PROPOSAL:2-6-5
  yes
CHARACTER-VS-CHAR:LESS-INCONSISTENT-SHORT
  yes
CLASS-OBJECT-SPECIALIZER:AFFIRM
  yes
CLOS-CONDITIONS-AGAIN:ALLOW-SUBSET
  yes
CLOS-CONDITIONS:INTEGRATE
  yes
CLOS-ERROR-CHECKING-ORDER:NO-APPLICABLE-METHOD-FIRST
  yes
CLOS-MACRO-COMPILATION:MINIMAL
  yes
CLOSE-CONSTRUCTED-STREAM:ARGUMENT-STREAM-ONLY
  yes
CLOSED-STREAM-OPERATIONS:ALLOW-INQUIRY
  yes
COERCING-SETF-NAME-TO-FUNCTION:ALL-FUNCTION-NAMES
  yes
COLON-NUMBER
  yes
COMMON-FEATURES:SPECIFY
  yes
COMMON-TYPE:REMOVE
  yes
COMPILE-ARGUMENT-PROBLEMS-AGAIN:FIX
  yes
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY
  yes
COMPILE-FILE-OUTPUT-FILE-DEFAULTS:INPUT-FILE
  yes
COMPILE-FILE-PACKAGE
  yes
COMPILE-FILE-PATHNAME-ARGUMENTS:MAKE-CONSISTENT
  yes
COMPILE-FILE-SYMBOL-HANDLING:NEW-REQUIRE-CONSISTENCY
  yes
COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN
  yes
COMPILER-DIAGNOSTICS:USE-HANDLER
  no
COMPILER-LET-CONFUSION:ELIMINATE
  yes
COMPILER-VERBOSITY:LIKE-LOAD
  yes
COMPILER-WARNING-STREAM
  yes
COMPLEX-ATAN-BRANCH-CUT:TWEAK
  yes
COMPLEX-ATANH-BOGUS-FORMULA:TWEAK-MORE
  yes
COMPLEX-RATIONAL-RESULT:EXTEND
  yes
COMPUTE-APPLICABLE-METHODS:GENERIC
  yes
CONCATENATE-SEQUENCE:SIGNAL-ERROR
  yes
CONDITION-ACCESSORS-SETFABLE:NO
  yes
CONDITION-RESTARTS:BUGGY
  yes
CONDITION-RESTARTS:PERMIT-ASSOCIATION
  yes
CONDITION-SLOTS:HIDDEN
  yes
CONS-TYPE-SPECIFIER:ADD
  yes
CONSTANT-CIRCULAR-COMPILATION:YES
  yes
CONSTANT-COLLAPSING:GENERALIZE
  yes
CONSTANT-COMPILABLE-TYPES:SPECIFY
  yes
CONSTANT-FUNCTION-COMPILATION:NO
  no
CONSTANT-MODIFICATION:DISALLOW
  yes
CONSTANTP-DEFINITION:INTENTIONAL
  yes
CONSTANTP-ENVIRONMENT:ADD-ARG
  yes
CONTAGION-ON-NUMERICAL-COMPARISONS:TRANSITIVE
  yes
COPY-SYMBOL-COPY-PLIST:COPY-LIST
  yes
COPY-SYMBOL-PRINT-NAME:EQUAL
  yes
DATA-IO:ADD-SUPPORT
  yes
DATA-TYPES-HIERARCHY-UNDERSPECIFIED
  yes
DEBUGGER-HOOK-VS-BREAK:CLARIFY
  yes
DECLARATION-SCOPE:NO-HOISTING
  no
DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES:RESTRICTIVE
  yes
DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION
  yes
DECLARE-MACROS:FLUSH
  yes
DECLARE-TYPE-FREE:LEXICAL
  yes
DECLS-AND-DOC
  ??
DECODE-UNIVERSAL-TIME-DAYLIGHT:LIKE-ENCODE
  yes
DEFCONSTANT-SPECIAL:NO
  yes
DEFGENERIC-DECLARE:ALLOW-MULTIPLE
  yes
DEFINE-COMPILER-MACRO:X3J13-NOV89
  yes
DEFINE-CONDITION-SYNTAX:INCOMPATIBLY-MORE-LIKE-DEFCLASS+EMPHASIZE-READ-ONLY
  yes
DEFINE-METHOD-COMBINATION-BEHAVIOR:CLARIFY
  no
DEFINING-MACROS-NON-TOP-LEVEL:ALLOW
  yes
DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS
  yes
DEFMACRO-LAMBDA-LIST:TIGHTEN-DESCRIPTION
  yes
DEFMETHOD-DECLARATION-SCOPE:CORRESPONDS-TO-BINDINGS
  yes
DEFPACKAGE:ADDITION
  yes
DEFSTRUCT-CONSTRUCTOR-KEY-MIXTURE:ALLOW-KEY
  yes
DEFSTRUCT-CONSTRUCTOR-OPTIONS:EXPLICIT
  yes
DEFSTRUCT-CONSTRUCTOR-SLOT-VARIABLES:NOT-BOUND
  yes
DEFSTRUCT-COPIER-ARGUMENT-TYPE:RESTRICT
  yes
DEFSTRUCT-COPIER:ARGUMENT-TYPE
  yes
DEFSTRUCT-DEFAULT-VALUE-EVALUATION:IFF-NEEDED
  yes
DEFSTRUCT-INCLUDE-DEFTYPE:EXPLICITLY-UNDEFINED
  yes
DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93
  yes
DEFSTRUCT-PRINT-FUNCTION-INHERITANCE:YES
  yes
DEFSTRUCT-REDEFINITION:ERROR
  yes
DEFSTRUCT-SLOTS-CONSTRAINTS-NAME:DUPLICATES-ERROR
  yes
DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER
  yes
DEFTYPE-DESTRUCTURING:YES
  yes
DEFTYPE-KEY:ALLOW
  yes
DEFVAR-DOCUMENTATION:UNEVALUATED
  yes
DEFVAR-INIT-TIME:NOT-DELAYED
  yes
DEFVAR-INITIALIZATION:CONSERVATIVE
  yes
DEPRECATION-POSITION:LIMITED
  yes
DESCRIBE-INTERACTIVE:NO
  yes
DESCRIBE-UNDERSPECIFIED:DESCRIBE-OBJECT
  yes
DESTRUCTIVE-OPERATIONS:SPECIFY
  yes
DESTRUCTURING-BIND:NEW-MACRO
  yes
DISASSEMBLE-SIDE-EFFECT:DO-NOT-INSTALL
  yes
DISPLACED-ARRAY-PREDICATE:ADD
  yes
DO-SYMBOLS-BLOCK-SCOPE:ENTIRE-FORM
  yes
DO-SYMBOLS-DUPLICATES
  yes
DOCUMENTATION-FUNCTION-BUGS:FIX
  yes
DOCUMENTATION-FUNCTION-TANGLED:REQUIRE-ARGUMENT
  yes
DOTIMES-IGNORE:X3J13-MAR91
  yes
DOTTED-LIST-ARGUMENTS:CLARIFY
  yes
DOTTED-MACRO-FORMS:ALLOW
  yes
DRIBBLE-TECHNIQUE
  yes
DYNAMIC-EXTENT-FUNCTION:EXTEND
  yes
DYNAMIC-EXTENT:NEW-DECLARATION
  yes
EQUAL-STRUCTURE:MAYBE-STATUS-QUO
  yes
ERROR-TERMINOLOGY-WARNING:MIGHT
  yes
EVAL-OTHER:SELF-EVALUATE
  yes
EVAL-TOP-LEVEL:LOAD-LIKE-COMPILE-FILE
  yes
EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS
  yes
EVAL-WHEN-OBSOLETE-KEYWORDS:X3J13-MAR-1993
  no
EVALHOOK-STEP-CONFUSION:FIX
  yes
EVALHOOK-STEP-CONFUSION:X3J13-NOV-89
  yes
EXIT-EXTENT-AND-CONDITION-SYSTEM:LIKE-DYNAMIC-BINDINGS
  yes
EXIT-EXTENT:MINIMAL
  yes, actually implement MEDIUM
EXPT-RATIO:P.211
  yes
EXTENSIONS-POSITION:DOCUMENTATION
  yes
EXTERNAL-FORMAT-FOR-EVERY-FILE-CONNECTION:MINIMUM
  yes
EXTRA-RETURN-VALUES:NO
  yes
FILE-OPEN-ERROR:SIGNAL-FILE-ERROR
  yes
FIXNUM-NON-PORTABLE:TIGHTEN-DEFINITION
  yes
FLET-DECLARATIONS
  yes
FLET-DECLARATIONS:ALLOW
  yes
FLET-IMPLICIT-BLOCK:YES
  yes
FLOAT-UNDERFLOW:ADD-VARIABLES
  yes
FLOATING-POINT-CONDITION-NAMES:X3J13-NOV-89
  yes
FORMAT-ATSIGN-COLON
  yes
FORMAT-COLON-UPARROW-SCOPE
  yes
FORMAT-COMMA-INTERVAL
  yes
FORMAT-E-EXPONENT-SIGN:FORCE-SIGN
  yes
FORMAT-OP-C
  yes
FORMAT-PRETTY-PRINT:YES
  yes, except that `~F`, `~E`, `~G`, `~$` also bind `*PRINT-BASE*` to 10 and `*PRINT-RADIX*` to `NIL`
FORMAT-STRING-ARGUMENTS:SPECIFY
  yes
FUNCTION-CALL-EVALUATION-ORDER:MORE-UNSPECIFIED
  yes
FUNCTION-COMPOSITION:JAN89-X3J13
  yes
FUNCTION-DEFINITION:JAN89-X3J13
  yes
FUNCTION-NAME:LARGE
  yes
FUNCTION-TYPE
  yes
FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS:RESTRICTIVE
  yes
FUNCTION-TYPE-KEY-NAME:SPECIFY-KEYWORD
  yes
FUNCTION-TYPE-REST-LIST-ELEMENT:USE-ACTUAL-ARGUMENT-TYPE
  yes
FUNCTION-TYPE:X3J13-MARCH-88
  yes
GENERALIZE-PRETTY-PRINTER:UNIFY
  no
GENERIC-FLET-POORLY-DESIGNED:DELETE
  yes
GENSYM-NAME-STICKINESS:LIKE-TEFLON
  yes
GENTEMP-BAD-IDEA:DEPRECATE
  yes
GET-MACRO-CHARACTER-READTABLE:NIL-STANDARD
  yes
GET-SETF-METHOD-ENVIRONMENT:ADD-ARG
  yes
HASH-TABLE-ACCESS:X3J13-MAR-89
  yes
HASH-TABLE-KEY-MODIFICATION:SPECIFY
  yes
HASH-TABLE-PACKAGE-GENERATORS:ADD-WITH-WRAPPER
  yes
HASH-TABLE-REHASH-SIZE-INTEGER
  yes
HASH-TABLE-SIZE:INTENDED-ENTRIES
  yes
HASH-TABLE-TESTS:ADD-EQUALP
  yes
IEEE-ATAN-BRANCH-CUT:SPLIT
  yes
IGNORE-USE-TERMINOLOGY:VALUE-ONLY
  yes
IMPORT-SETF-SYMBOL-PACKAGE
  yes
IN-PACKAGE-FUNCTIONALITY:MAR89-X3J13
  yes
IN-SYNTAX:MINIMAL
  yes
INITIALIZATION-FUNCTION-KEYWORD-CHECKING
  yes
ISO-COMPATIBILITY:ADD-SUBSTRATE
  yes
JUN90-TRIVIAL-ISSUES:11
  yes
JUN90-TRIVIAL-ISSUES:14
  yes
JUN90-TRIVIAL-ISSUES:24
  yes
JUN90-TRIVIAL-ISSUES:25
  yes
JUN90-TRIVIAL-ISSUES:27
  yes for `THE`, no for `APPLY` (spec not clear)
JUN90-TRIVIAL-ISSUES:3
  yes
JUN90-TRIVIAL-ISSUES:4
  yes
JUN90-TRIVIAL-ISSUES:5
  yes
JUN90-TRIVIAL-ISSUES:9
  yes
KEYWORD-ARGUMENT-NAME-PACKAGE:ANY
  yes
LAST-N
  yes
LCM-NO-ARGUMENTS:1
  yes
LEXICAL-CONSTRUCT-GLOBAL-DEFINITION:UNDEFINED
  yes
LISP-PACKAGE-NAME:COMMON-LISP
  yes
LISP-SYMBOL-REDEFINITION-AGAIN:MORE-FIXES
  yes
LISP-SYMBOL-REDEFINITION:MAR89-X3J13
  yes
LOAD-OBJECTS:MAKE-LOAD-FORM
  yes
LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM
  obsolete
LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM
  yes
LOAD-TRUENAME:NEW-PATHNAME-VARIABLES
  yes
LOCALLY-TOP-LEVEL:SPECIAL-FORM
  yes
LOOP-AND-DISCREPANCY:NO-REITERATION
  yes
LOOP-FOR-AS-ON-TYPO:FIX-TYPO
  yes
LOOP-INITFORM-ENVIRONMENT:PARTIAL-INTERLEAVING-VAGUE
  no
LOOP-MISCELLANEOUS-REPAIRS:FIX
  yes
LOOP-NAMED-BLOCK-NIL:OVERRIDE
  yes
LOOP-PRESENT-SYMBOLS-TYPO:FLUSH-WRONG-WORDS
  yes
LOOP-SYNTAX-OVERHAUL:REPAIR
  yes
MACRO-AS-FUNCTION:DISALLOW
  yes
MACRO-DECLARATIONS:MAKE-EXPLICIT
  yes
MACRO-ENVIRONMENT-EXTENT:DYNAMIC
  yes
MACRO-FUNCTION-ENVIRONMENT
  obsolete
MACRO-FUNCTION-ENVIRONMENT:YES
  yes
MACRO-SUBFORMS-TOP-LEVEL-P:ADD-CONSTRAINTS
  no
MACROEXPAND-HOOK-DEFAULT:EXPLICITLY-VAGUE
  yes
MACROEXPAND-HOOK-INITIAL-VALUE:IMPLEMENTATION-DEPENDENT
  yes
MACROEXPAND-RETURN-VALUE:TRUE
  yes
MAKE-LOAD-FORM-CONFUSION:REWRITE
  yes
MAKE-LOAD-FORM-SAVING-SLOTS:NO-INITFORMS
  yes
MAKE-PACKAGE-USE-DEFAULT:IMPLEMENTATION-DEPENDENT
  yes
MAP-INTO:ADD-FUNCTION
  yes
MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE
  yes
METACLASS-OF-SYSTEM-CLASS:UNSPECIFIED
  yes
METHOD-COMBINATION-ARGUMENTS:CLARIFY
  no
METHOD-INITFORM:FORBID-CALL-NEXT-METHOD
  no
MUFFLE-WARNING-CONDITION-ARGUMENT
  yes
MULTIPLE-VALUE-SETQ-ORDER:LIKE-SETF-OF-VALUES
  yes
MULTIPLE-VALUES-LIMIT-ON-VARIABLES:UNDEFINED
  yes
NINTERSECTION-DESTRUCTION
  yes
NINTERSECTION-DESTRUCTION:REVERT
  yes
NOT-AND-NULL-RETURN-VALUE:X3J13-MAR-93
  yes
NTH-VALUE:ADD
  yes
OPTIMIZE-DEBUG-INFO:NEW-QUALITY
  yes
PACKAGE-CLUTTER:REDUCE
  yes
PACKAGE-DELETION:NEW-FUNCTION
  yes
PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE
  yes
PARSE-ERROR-STREAM:SPLIT-TYPES
  yes
PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT
  yes
PATHNAME-COMPONENT-VALUE:SPECIFY
  no
PATHNAME-HOST-PARSING:RECOGNIZE-LOGICAL-HOST-NAMES
  yes when `CUSTOM:*PARSE-NAMESTRING-ANSI*` is non-`NIL`
PATHNAME-LOGICAL:ADD
  yes
PATHNAME-PRINT-READ:SHARPSIGN-P
  yes
PATHNAME-STREAM
  yes
PATHNAME-STREAM:FILES-OR-SYNONYM
  yes
PATHNAME-SUBDIRECTORY-LIST:NEW-REPRESENTATION
  yes
PATHNAME-SYMBOL
  yes when `CUSTOM:*PARSE-NAMESTRING-ANSI*` is non-`NIL`
PATHNAME-SYNTAX-ERROR-TIME:EXPLICITLY-VAGUE
  yes
PATHNAME-UNSPECIFIC-COMPONENT:NEW-TOKEN
  yes
PATHNAME-WILD:NEW-FUNCTIONS
  yes
PEEK-CHAR-READ-CHAR-ECHO:FIRST-READ-CHAR
  yes
PLIST-DUPLICATES:ALLOW
  yes
PRETTY-PRINT-INTERFACE
  yes
PRINC-READABLY:X3J13-DEC-91
  yes
PRINT-CASE-BEHAVIOR:CLARIFY
  yes
PRINT-CASE-PRINT-ESCAPE-INTERACTION:VERTICAL-BAR-RULE-NO-UPCASE
  yes
PRINT-CIRCLE-SHARED:RESPECT-PRINT-CIRCLE
  yes
PRINT-CIRCLE-STRUCTURE:USER-FUNCTIONS-WORK
  yes
PRINT-READABLY-BEHAVIOR:CLARIFY
  yes
PRINTER-WHITESPACE:JUST-ONE-SPACE
  yes
PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO
  yes
PUSH-EVALUATION-ORDER:FIRST-ITEM
  yes
PUSH-EVALUATION-ORDER:ITEM-FIRST
  yes
PUSHNEW-STORE-REQUIRED:UNSPECIFIED
  yes
QUOTE-SEMANTICS:NO-COPYING
  yes
RANGE-OF-COUNT-KEYWORD:NIL-OR-INTEGER
  yes, when `CUSTOM:*SEQUENCE-COUNT-ANSI*` is non-`NIL`; otherwise negative `:COUNT` values are not allowed.
RANGE-OF-START-AND-END-PARAMETERS:INTEGER-AND-INTEGER-NIL
  yes
READ-AND-WRITE-BYTES:NEW-FUNCTIONS
  yes
READ-CASE-SENSITIVITY:READTABLE-KEYWORDS
  yes
READ-MODIFY-WRITE-EVALUATION-ORDER:DELAYED-ACCESS-STORES
  no
READ-SUPPRESS-CONFUSING:GENERALIZE
  yes, except that `READ-DELIMITED-LIST` still constructs a `LIST`
READER-ERROR:NEW-TYPE
  yes
REAL-NUMBER-TYPE:X3J13-MAR-89
  yes
RECURSIVE-DEFTYPE:EXPLICITLY-VAGUE
  yes
REDUCE-ARGUMENT-EXTRACTION
  yes
REMF-DESTRUCTION-UNSPECIFIED:X3J13-MAR-89
  yes
REQUIRE-PATHNAME-DEFAULTS-AGAIN:X3J13-DEC-91
  yes
REQUIRE-PATHNAME-DEFAULTS-YET-AGAIN:RESTORE-ARGUMENT
  yes
REQUIRE-PATHNAME-DEFAULTS:ELIMINATE
  superseded by REQUIRE-PATHNAME-DEFAULTS-AGAIN:X3J13-DEC-91
REST-LIST-ALLOCATION:MAY-SHARE
  yes
RESULT-LISTS-SHARED:SPECIFY
  yes
RETURN-VALUES-UNSPECIFIED:SPECIFY
  yes
ROOM-DEFAULT-ARGUMENT:NEW-VALUE
  yes
SELF-MODIFYING-CODE:FORBID
  yes
SEQUENCE-TYPE-LENGTH:MUST-MATCH
  yes
SETF-APPLY-EXPANSION:IGNORE-EXPANDER
  no
SETF-FIND-CLASS:ALLOW-NIL
  yes
SETF-FUNCTIONS-AGAIN:MINIMAL-CHANGES
  yes
SETF-GET-DEFAULT:EVALUATED-BUT-IGNORED
  yes
SETF-MACRO-EXPANSION:LAST
  yes
SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS
  yes
SETF-MULTIPLE-STORE-VARIABLES:ALLOW
  yes
SETF-OF-APPLY:ONLY-AREF-AND-FRIENDS
  yes
SETF-OF-VALUES:ADD
  yes
SETF-SUB-METHODS:DELAYED-ACCESS-STORES
  yes
SHADOW-ALREADY-PRESENT
  yes
SHADOW-ALREADY-PRESENT:WORKS
  yes
SHARP-COMMA-CONFUSION:REMOVE
  no
SHARP-O-FOOBAR:CONSEQUENCES-UNDEFINED
  yes
SHARP-STAR-DELIMITER:NORMAL-DELIMITER
  yes
SHARPSIGN-PLUS-MINUS-PACKAGE:KEYWORD
  yes
SLOT-MISSING-VALUES:SPECIFY
  yes
SLOT-VALUE-METACLASSES:LESS-MINIMAL
  yes
SPECIAL-FORM-P-MISNOMER:RENAME
  yes
SPECIAL-TYPE-SHADOWING:CLARIFY
  yes
STANDARD-INPUT-INITIAL-BINDING:DEFINED-CONTRACTS
  yes
STANDARD-REPERTOIRE-GRATUITOUS:RENAME
  yes
STEP-ENVIRONMENT:CURRENT
  yes
STEP-MINIMAL:PERMIT-PROGN
  yes
STREAM-ACCESS:ADD-TYPES-ACCESSORS
  yes
STREAM-CAPABILITIES:INTERACTIVE-STREAM-P
  yes
STRING-COERCION:MAKE-CONSISTENT
  yes
STRING-OUTPUT-STREAM-BASHING:UNDEFINED
  yes
STRUCTURE-READ-PRINT-SYNTAX:KEYWORDS
  yes
SUBSEQ-OUT-OF-BOUNDS
  yes
SUBSEQ-OUT-OF-BOUNDS:IS-AN-ERROR
  yes
SUBSETTING-POSITION:NONE
  yes
SUBTYPEP-ENVIRONMENT:ADD-ARG
  yes
SUBTYPEP-TOO-VAGUE:CLARIFY-MORE
  yes
SXHASH-DEFINITION:SIMILAR-FOR-SXHASH
  yes
SYMBOL-MACROLET-DECLARE:ALLOW
  yes
SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM
  yes
SYMBOL-MACROLET-TYPE-DECLARATION:NO
  yes
SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS:SIGNALS-AN-ERROR
  yes
SYMBOL-PRINT-ESCAPE-BEHAVIOR:CLARIFY
  yes
SYNTACTIC-ENVIRONMENT-ACCESS:RETRACTED-MAR91
  yes
TAGBODY-TAG-EXPANSION:NO
  yes
TAILP-NIL:T
  yes
TEST-NOT-IF-NOT:FLUSH-ALL
  yes, but no warning
THE-AMBIGUITY:FOR-DECLARATION
  yes
THE-VALUES:RETURN-NUMBER-RECEIVED
  yes
TIME-ZONE-NON-INTEGER:ALLOW
  yes
TYPE-DECLARATION-ABBREVIATION:ALLOW-ALL
  no
TYPE-OF-AND-PREDEFINED-CLASSES:TYPE-OF-HANDLES-FLOATS
  yes
TYPE-OF-AND-PREDEFINED-CLASSES:UNIFY-AND-EXTEND
  yes, except for class `METHOD-COMBINATION`
TYPE-OF-UNDERCONSTRAINED:ADD-CONSTRAINTS
  yes
TYPE-SPECIFIER-ABBREVIATION:X3J13-JUN90-GUESS
  yes
UNDEFINED-VARIABLES-AND-FUNCTIONS:COMPROMISE
  yes
UNINITIALIZED-ELEMENTS:CONSEQUENCES-UNDEFINED
  yes, could add error checking
UNREAD-CHAR-AFTER-PEEK-CHAR:DONT-ALLOW
  yes
UNSOLICITED-MESSAGES:NOT-TO-SYSTEM-USER-STREAMS
  yes
VARIABLE-LIST-ASYMMETRY:SYMMETRIZE
  yes
WITH-ADDED-METHODS:DELETE
  yes
WITH-COMPILATION-UNIT:NEW-MACRO
  yes
WITH-OPEN-FILE-DOES-NOT-EXIST:STREAM-IS-NIL
  yes
WITH-OPEN-FILE-SETQ:EXPLICITLY-VAGUE
  yes
WITH-OPEN-FILE-STREAM-EXTENT:DYNAMIC-EXTENT
  yes
WITH-OUTPUT-TO-STRING-APPEND-STYLE:VECTOR-PUSH-EXTEND
  yes
WITH-STANDARD-IO-SYNTAX-READTABLE:X3J13-MAR-91
  yes

# Extensions

## Chapter 29. Extensions-1: Platform independent Extensions

## 29.1. Extensions-1.1. Saving an Image

The function `(`EXT:SAVEINITMEM` `&OPTIONAL` (`filename` "lispinit.mem") `&KEY` :QUIET :INIT-FUNCTION :LOCKED-PACKAGES :START-PACKAGE)` saves the running CLISP's memory to the file `filename`; extension `#P".mem"` is recommended (when `filename` does not have an extension, `#P".mem"` extension is automatically added).

`:QUIET`
  If this argument is not `NIL`, the startup banner and the good-bye message will be suppressed.
`:INIT-FUNCTION`

  This argument specifies a function that will be executed at startup of the saved image, before entering the standard read-eval-print loop; thus, if you want to avoid the read-eval-print loop, you have to call `EXT:EXIT` at the end of the init function yourself.

  See the manual for passing command line arguments to this function.

`:LOCKED-PACKAGES`
  This argument specifies the packages to lock before saving the image; this is convenient for application delivery, when you do not want your users to mess up your product. This argument defaults to `CUSTOM:*SYSTEM-PACKAGE-LIST*`.
`:START-PACKAGE`
  This argument specifies the starting value of `*PACKAGE*` in the image being saved, and defaults to the current value of `*PACKAGE*`.

You can use this memory image with the `-M` option. On UNIX systems, you may compress it with GNU gzip to save disk space.

## 29.2. Extensions-1.2. Quitting CLISP

The functions `(`EXT:EXIT` [`errorp`])`, `(`EXT:QUIT` [`errorp`])` and `(`EXT:BYE` [`errorp`])` - all synonymous - terminate CLISP. If `errorp` is non-`NIL`, CLISP aborts with the supplied numeric error status, i.e., the OS environment is informed that the CLISP session did not succeed.

## 29.3. Extensions-1.3. Internationalization

"Internationalization" means to prepare a program so that it can use multiple national languages and national cultural conventions without requiring further source code changes. Localization means providing the data - mostly textual translations - necessary for an internationalized program to work in a particular language and with particular cultural conventions.

CLISP is internationalized, and is localized for the languages English, German, French, Spanish, Dutch and Russian. CLISP also supports internationalized Lisp programs, through GNU gettext.

### 29.3.1. The GNU gettext

GNU gettext is a set of functions, included in CLISP or the C library, which permit looking up translations of strings through message catalogs. It is also a set of tools which makes the translation maintenance easy for the translator and the program maintainer.

The GNU gettext functions are available in CLISP in the “I18N” package, which is `EXT:RE-EXPORT`ed from the “EXT” package.

`(`I18N:GETTEXT` `MSGID` `&OPTIONAL` `DOMAIN` `CATEGORY`)`
  returns the translation of the message `MSGID`, in the given `DOMAIN`, depending on the given `CATEGORY`. `MSGID` should be an ASCII string, and is normally the English message.
`(`I18N:NGETTEXT` `MSGID` `msgid_plural` `n` `&OPTIONAL` `DOMAIN` `CATEGORY`)`
  returns the plural form of the translation for of `MSGID` and `n` in the given `DOMAIN`, depending on the given `CATEGORY`. `MSGID` and `msgid_plural` should be ASCII strings, and are normally the English singular and English plural variant of the message, respectively.

#### 29.3.1.1. Domain

The `DOMAIN` is a string identifier denoting the program that is requesting the translation. The pathname of the message catalog depends on the `DOMAIN`: usually it is located at `TEXTDOMAINDIR/l/LC_MESSAGES/domain.mo`, where `l` is the ISO 639 code of the language. The notion of `DOMAIN` allows several Lisp programs running in the same image to request translations independently of each other.

Function `I18N:TEXTDOMAIN`. `(`I18N:TEXTDOMAIN`)` is a place that returns the default `DOMAIN`, used when no `DOMAIN` argument is passed to the `I18N:GETTEXT` and `I18N:NGETTEXT` functions. It is `SETF`able. `(`SETF` `I18N:TEXTDOMAIN`)` is usually used during the startup phase of a program. Note that the default `DOMAIN` is not saved in a memory image. The use of `(`SETF` `I18N:TEXTDOMAIN`)` is recommended only for programs that are so simple that they will never need more than one `DOMAIN`.

Function `I18N:TEXTDOMAINDIR`. `(`I18N:TEXTDOMAINDIR` `DOMAIN`)` is a place that returns the base directory, called `TEXTDOMAINDIR` above, where the message catalogs for the given `DOMAIN` are assumed to be installed. It is `SETF`able. `(`SETF` `I18N:TEXTDOMAINDIR`)` is usually used during the startup phase of a program, and should be used because only the program knows where its message catalogs are installed. Note that the `TEXTDOMAINDIR`s are not saved in a memory image.

#### 29.3.1.2. Category

The `CATEGORY` argument of the `I18N:GETTEXT` and `I18N:NGETTEXT` functions denotes which locale facet the result should depend on. The default value is `:LC_MESSAGES`. Other possible values are `:LC_CTYPE`, `:LC_TIME`, `:LC_COLLATE`, `:LC_MONETARY`. The use of these values is useful for users who have a character/time/collation/money handling set differently from the usual message handling. Note that when a `CATEGORY` argument is used, the message catalog location depends on the `CATEGORY`: it will be expected at `TEXTDOMAINDIR/ll/category/domain.mo`.

#### 29.3.1.3. Example

A non-internationalized program simulating a restaurant dialogue might look as follows.

Example 29.1. prog.lisp

    (setq n (parse-integer (first EXT:*ARGS*)))

    (format t "~A~%" "'Your command, please?', asked the waiter.")

    (format t "~@?~%"
              (if (= n 1) "a piece of cake" "~D pieces of cake")
              n)

After being internationalized, all strings are wrapped in `I18N:GETTEXT` calls, and `I18N:NGETTEXT` is used for plurals. Also, `I18N:TEXTDOMAINDIR` is assigned a value; in our case, for simplicity, the current directory.

Example 29.2. prog.lisp

    (setf (textdomain) "prog")
    (setf (textdomaindir "prog") "./")

    (setq n (parse-integer (first EXT:*ARGS*)))

    (format t "~A~%"
              (gettext "'Your command, please?', asked the waiter."))

    (format t "~@?~%"
              (ngettext "a piece of cake" "~D pieces of cake" n)
              n)

For ease of reading, it is customary to define an abbreviation for the `I18N:GETTEXT` function. An underscore is customary.

Example 29.3. prog.lisp

    (setf (textdomaindir "prog") "./")
    (defun _ (msgid) (gettext msgid "prog"))

    (setq n (parse-integer (first EXT:*ARGS*)))

    (format t "~A~%"
              (_"'Your command, please?', asked the waiter."))

    (format t "~@?~%"
              (ngettext "a piece of cake" "~D pieces of cake" n "prog")
              n)

Now the program's maintainer creates a message catalog template through the command

    bash$ xgettext -o prog.pot prog.lisp

### Note

xgettext version 0.11 or higher is required here.

The message catalog template looks roughly like this.

Example 29.4. prog.pot

    msgid "'Your command, please?', asked the waiter."
    msgstr ""

    msgid "a piece of cake"
    msgid_plural "%d pieces of cake"
    msgstr[0] ""
    msgstr[1] ""

Then a French translator creates a French message catalog

Example 29.5. prog.fr.po

    msgid ""
    msgstr ""
    "Content-Type: text/plain; charset=ISO-8859-1\n"
    "Plural-Forms: nplurals=2; plural=(n > 1);\n"

    msgid "'Your command, please?', asked the waiter."
    msgstr "«Votre commande, s'il vous plait», dit le garçon."

    # Les gateaux allemands sont les meilleurs du monde.
    msgid "a piece of cake"
    msgid_plural "%d pieces of cake"
    msgstr[0] "un morceau de gateau"
    msgstr[1] "%d morceaux de gateau"

and sends it to the program's maintainer.

The program's maintainer compiles the catalog as follows:

    bash$ mkdir -p ./fr/LC_MESSAGES
    bash$ msgfmt -o ./fr/LC_MESSAGES/prog.mo prog.fr.po

When a user in a french locale then runs the program

    bash$ clisp prog.lisp 2

she will get the output

        «Votre commande, s'il vous plait», dit le garçon.
        2 morceaux de gateau

### 29.3.2. The Language

### Warning

Note that the facilities described in this section will work only for the languages for which CLISP itself is already localized.

The language CLISP uses to communicate with the user can be one of

`ENGLISH`
`DEUTSCH` (i.e., German)
`FRANÇAIS` (i.e., French)
`ESPAÑOL` (i.e., Spanish)
`NEDERLANDS` (i.e., Dutch)
`РУССКИЙ` (i.e. Russian)

This is controlled by the `SYMBOL-MACRO` `CUSTOM:*CURRENT-LANGUAGE*`, which can be set at run time as well as using `-L` start-up option. If you wish to change the locale directory at run time too, you can do that by setting `CUSTOM:*CURRENT-LANGUAGE*` to a `CONS` cell, whose `CAR` is the language (a `SYMBOL`, one of the above), and whose `CDR` is the new locale directory.

More languages can be defined through the macro `I18N:DEFLANGUAGE`: `(`I18N:DEFLANGUAGE` `language`)`. For such an additional language to take effect, you must install the corresponding message catalog, or translate the messages yourself, using GNU gettext and Emacs (or XEmacs) po-mode.

This works only for strings. For arbitrary language-dependent Lisp objects, you define one through the macro `I18N:DEFINTERNATIONAL`: `(`I18N:DEFINTERNATIONAL` `symbol` `&OPTIONAL` (`default-language` `T`))` and add language-dependent values through the macro `I18N:DEFLOCALIZED`: `(`I18N:DEFLOCALIZED` `symbol` `language` `value-form`)` (One such form for each language. Languages without an assigned value will be treated like the default-language.) You can then access the localized value by calling `I18N:LOCALIZED`: `(`I18N:LOCALIZED` `symbol` `&OPTIONAL` `language`)`

## 29.4. Extensions-1.4. Encodings

### 29.4.1. Introduction

An “encoding” describes the correspondence between `CHARACTER`s and raw bytes during input/output via `STREAM`s with `STREAM-ELEMENT-TYPE` `CHARACTER`.

An `EXT:ENCODING` is an object composed of the following facets:

character set
  This denotes both the set of characters that can be represented and passed through the I/O channel, and the way these characters translate into raw bytes. In this context, for example, "UTF-8" and "UCS-4" are considered different, although they can represent the same set of characters.
line terminator mode
  This denotes the way newline characters are represented.

`EXT:ENCODING`s are also types. As such, they represent the set of characters encodable in the character set. In this context, the way characters are translated into raw bytes is ignored, and the line terminator mode is ignored as well. `TYPEP` and `SUBTYPEP` can be used on encodings.

### 29.4.2. Character Sets

Platform dependent: Only in CLISP built without compile-time flag UNICODE.
  Only one character set is understood: the platform's native (8-bit) character set. See Chapter 13, Characters [CLHS-13].
Platform dependent: Only in CLISP built with compile-time flag UNICODE.

  The following character sets are supported, as values of the corresponding (constant) symbol in the “CHARSET” package:

  Symbols in package “CHARSET”

  1. `UCS-2` ≡ `UNICODE-16` ≡ `UNICODE-16-BIG-ENDIAN`, the 16-bit basic multilingual plane of the UNICODE character set. Every character is represented as two bytes.
  2. `UNICODE-16-LITTLE-ENDIAN`
  3. `UCS-4` ≡ `UNICODE-32` ≡ `UNICODE-32-BIG-ENDIAN`, the 21-bit UNICODE character set. Every character is represented as four bytes.
  4. `UNICODE-32-LITTLE-ENDIAN`
  5. `UTF-8`, the 21-bit UNICODE character set. Every character is represented as one to four bytes. ASCII characters represent themselves and need one byte per character. Most Latin/Greek/Cyrillic/Hebrew characters need two bytes per character. Most other characters need three bytes per character, and the rarely used remaining characters need four bytes per character. This is therefore, in general, the most space-efficient encoding of all of Unicode.
  6. `UTF-16`, the 21-bit UNICODE character set. Every character in the 16-bit basic multilingual plane is represented as two bytes, and the rarely used remaining characters need four bytes per character. This character set is only available on platforms with GNU libc or GNU libiconv.
  7. `UTF-7`, the 21-bit UNICODE character set. This is a stateful 7-bit encoding. Not all ASCII characters represent themselves. This character set is only available on platforms with GNU libc or GNU libiconv.
  8. `JAVA`, the 21-bit UNICODE character set. ASCII characters represent themselves and need one byte per character. All other characters of the basic multilingual plane are represented by `\u`nnnn`` sequences (`nnnn` a hexadecimal number) and need 6 bytes per character. The remaining characters are represented by `\u`xxxx`\u`yyyy`` and need 12 bytes per character. While this encoding is very comfortable for editing Unicode files using only ASCII-aware tools and editors, it cannot faithfully represent all UNICODE text. Only text which does not contain `\u` (backslash followed by lowercase Latin u) can be faithfully represented by this encoding.
  9. `ASCII`, the well-known US-centric 7-bit character set (American Standard Code for Information Interchange - ASCII).
  10. `ISO-8859-1`, an extension of the ASCII character set, suitable for the Afrikaans, Albanian, Basque, Breton, Catalan, Cornish, Danish, Dutch, English, Faeroese, Finnish, French, Frisian, Galician, German, Greenlandic, Icelandic, Irish, Italian, Latin, Luxemburgish, Norwegian, Portuguese, Raeto-Romanic, Scottish, Spanish, and Swedish languages.
  11. `ISO-8859-2`, an extension of the ASCII character set, suitable for the Croatian, Czech, German, Hungarian, Polish, Slovak, Slovenian, and Sorbian languages.
  12. `ISO-8859-3`, an extension of the ASCII character set, suitable for the Esperanto and Maltese languages.
  13. `ISO-8859-4`, an extension of the ASCII character set, suitable for the Estonian, Latvian, Lithuanian and Sami (Lappish) languages.
  14. `ISO-8859-5`, an extension of the ASCII character set, suitable for the Bulgarian, Byelorussian, Macedonian, Russian, Serbian, and Ukrainian languages.
  15. `ISO-8859-6`, suitable for the Arabic language.
  16. `ISO-8859-7`, an extension of the ASCII character set, suitable for the Greek language.
  17. `ISO-8859-8`, an extension of the ASCII character set, suitable for the Hebrew language (without punctuation).
  18. `ISO-8859-9`, an extension of the ASCII character set, suitable for the Turkish language.
  19. `ISO-8859-10`, an extension of the ASCII character set, suitable for the Estonian, Icelandic, Inuit (Greenlandic), Latvian, Lithuanian, and Sami (Lappish) languages.
  20. `ISO-8859-13`, an extension of the ASCII character set, suitable for the Estonian, Latvian, Lithuanian, Polish and Sami (Lappish) languages.
  21. `ISO-8859-14`, an extension of the ASCII character set, suitable for the Irish Gaelic, Manx Gaelic, Scottish Gaelic, and Welsh languages.
  22. `ISO-8859-15`, an extension of the ASCII character set, suitable for the ISO-8859-1 languages, with improvements for French, Finnish and the Euro.
  23. `ISO-8859-16` an extension of the ASCII character set, suitable for the Rumanian language.
  24. `KOI8-R`, an extension of the ASCII character set, suitable for the Russian language (very popular, especially on the internet).
  25. `KOI8-U`, an extension of the ASCII character set, suitable for the Ukrainian language (very popular, especially on the internet).
  26. `KOI8-RU`, an extension of the ASCII character set, suitable for the Russian language. This character set is only available on platforms with GNU libiconv.
  27. `JIS_X0201`, a character set for the Japanese language.
  28. `MAC-ARABIC`, a platform specific extension of the ASCII character set.
  29. `MAC-CENTRAL-EUROPE`, a platform specific extension of the ASCII character set.
  30. `MAC-CROATIAN`, a platform specific extension of the ASCII character set.
  31. `MAC-CYRILLIC`, a platform specific extension of the ASCII character set.
  32. `MAC-DINGBAT`, a platform specific character set.
  33. `MAC-GREEK`, a platform specific extension of the ASCII character set.
  34. `MAC-HEBREW`, a platform specific extension of the ASCII character set.
  35. `MAC-ICELAND`, a platform specific extension of the ASCII character set.
  36. `MAC-ROMAN` ≡ `MACINTOSH`, a platform specific extension of the ASCII character set.
  37. `MAC-ROMANIA`, a platform specific extension of the ASCII character set.
  38. `MAC-SYMBOL`, a platform specific character set.
  39. `MAC-THAI`, a platform specific extension of the ASCII character set.
  40. `MAC-TURKISH`, a platform specific extension of the ASCII character set.
  41. `MAC-UKRAINE`, a platform specific extension of the ASCII character set.
  42. `CP437`, a DOS oldie, a platform specific extension of the ASCII character set.
  43. `CP437-IBM`, an IBM variant of `CP437`.
  44. `CP737`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Greek language.
  45. `CP775`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for some Baltic languages.
  46. `CP850`, a DOS oldie, a platform specific extension of the ASCII character set.
  47. `CP852`, a DOS oldie, a platform specific extension of the ASCII character set.
  48. `CP852-IBM`, an IBM variant of `CP852`.
  49. `CP855`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Russian language.
  50. `CP857`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Turkish language.
  51. `CP860`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Portuguese language.
  52. `CP860-IBM`, an IBM variant of `CP860`.
  53. `CP861`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Icelandic language.
  54. `CP861-IBM`, an IBM variant of `CP861`.
  55. `CP862`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Hebrew language.
  56. `CP862-IBM`, an IBM variant of `CP862`.
  57. `CP863`, a DOS oldie, a platform specific extension of the ASCII character set.
  58. `CP863-IBM`, an IBM variant of `CP863`.
  59. `CP864`, a DOS oldie, meant to be suitable for the Arabic language.
  60. `CP864-IBM`, an IBM variant of `CP864`.
  61. `CP865`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for some Nordic languages.
  62. `CP865-IBM`, an IBM variant of `CP865`.
  63. `CP866`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Russian language.
  64. `CP869`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Greek language.
  65. `CP869-IBM`, an IBM variant of `CP869`.
  66. `CP874`, a DOS oldie, a platform specific extension of the ASCII character set, meant to be suitable for the Thai language.
  67. `CP874-IBM`, an IBM variant of `CP874`.
  68. `WINDOWS-1250` ≡ `CP1250`, a platform specific extension of the ASCII character set, heavily incompatible with ISO-8859-2.
  69. `WINDOWS-1251` ≡ `CP1251`, a platform specific extension of the ASCII character set, heavily incompatible with ISO-8859-5, meant to be suitable for the Russian language.
  70. `WINDOWS-1252` ≡ `CP1252`, a platform specific extension of the ISO-8859-1 character set.
  71. `WINDOWS-1253` ≡ `CP1253`, a platform specific extension of the ASCII character set, gratuitously incompatible with ISO-8859-7, meant to be suitable for the Greek language.
  72. `WINDOWS-1254` ≡ `CP1254`, a platform specific extension of the ISO-8859-9 character set.
  73. `WINDOWS-1255` ≡ `CP1255`, a platform specific extension of the ASCII character set, gratuitously incompatible with ISO-8859-8, suitable for the Hebrew language. This character set is only available on platforms with GNU libc or GNU libiconv.
  74. `WINDOWS-1256` ≡ `CP1256`, a platform specific extension of the ASCII character set, meant to be suitable for the Arabic language.
  75. `WINDOWS-1257` ≡ `CP1257`, a platform specific extension of the ASCII character set.
  76. `WINDOWS-1258` ≡ `CP1258`, a platform specific extension of the ASCII character set, meant to be suitable for the Vietnamese language. This character set is only available on platforms with GNU libc or GNU libiconv.
  77. `HP-ROMAN8`, a platform specific extension of the ASCII character set.
  78. `NEXTSTEP`, a platform specific extension of the ASCII character set.
  79. `EUC-JP`, a multibyte character set for the Japanese language. This character set is only available on platforms with GNU libc or GNU libiconv.
  80. `SHIFT-JIS`, a multibyte character set for the Japanese language. This character set is only available on platforms with GNU libc or GNU libiconv.
  81. `CP932`, a Microsoft variant of `SHIFT-JIS`. This character set is only available on platforms with GNU libc or GNU libiconv.
  82. `ISO-2022-JP`, a stateful 7-bit multibyte character set for the Japanese language. This character set is only available on platforms with GNU libc or GNU libiconv.
  83. `ISO-2022-JP-2`, a stateful 7-bit multibyte character set for the Japanese language. This character set is only available on platforms with GNU libc 2.3 or newer or GNU libiconv.
  84. `ISO-2022-JP-1`, a stateful 7-bit multibyte character set for the Japanese language. This character set is only available on platforms with GNU libiconv.
  85. `EUC-CN`, a multibyte character set for simplified Chinese. This character set is only available on platforms with GNU libc or GNU libiconv.
  86. `HZ`, a stateful 7-bit multibyte character set for simplified Chinese. This character set is only available on platforms with GNU libiconv.
  87. `GBK`, a multibyte character set for Chinese, This character set is only available on platforms with GNU libc or GNU libiconv.
  88. `CP936`, a Microsoft variant of `GBK`. This character set is only available on platforms with GNU libc or GNU libiconv.
  89. `GB18030`, a multibyte character set for Chinese, This character set is only available on platforms with GNU libc or GNU libiconv.
  90. `EUC-TW`, a multibyte character set for traditional Chinese. This character set is only available on platforms with GNU libc or GNU libiconv.
  91. `BIG5`, a multibyte character set for traditional Chinese. This character set is only available on platforms with GNU libc or GNU libiconv.
  92. `CP950`, a Microsoft variant of `BIG5`. This character set is only available on platforms with GNU libc or GNU libiconv.
  93. `BIG5-HKSCS`, a multibyte character set for traditional Chinese. This character set is only available on platforms with GNU libc or GNU libiconv.
  94. `ISO-2022-CN`, a stateful 7-bit multibyte character set for Chinese. This character set is only available on platforms with GNU libc or GNU libiconv.
  95. `ISO-2022-CN-EXT`, a stateful 7-bit multibyte character set for Chinese. This character set is only available on platforms with GNU libc or GNU libiconv.
  96. `EUC-KR`, a multibyte character set for Korean. This character set is only available on platforms with GNU libc or GNU libiconv.
  97. `CP949`, a Microsoft variant of `EUC-KR`. This character set is only available on platforms with GNU libc or GNU libiconv.
  98. `ISO-2022-KR`, a stateful 7-bit multibyte character set for Korean. This character set is only available on platforms with GNU libc or GNU libiconv.
  99. `JOHAB`, a multibyte character set for Korean used mostly on DOS. This character set is only available on platforms with GNU libc or GNU libiconv.
  100. `ARMSCII-8`, an extension of the ASCII character set, suitable for the Armenian. This character set is only available on platforms with GNU libc or GNU libiconv.
  101. `GEORGIAN-ACADEMY`, an extension of the ASCII character set, suitable for the Georgian. This character set is only available on platforms with GNU libc or GNU libiconv.
  102. `GEORGIAN-PS`, an extension of the ASCII character set, suitable for the Georgian. This character set is only available on platforms with GNU libc or GNU libiconv.
  103. `TIS-620`, an extension of the ASCII character set, suitable for the Thai. This character set is only available on platforms with GNU libc or GNU libiconv.
  104. `MULELAO-1`, an extension of the ASCII character set, suitable for the Laotian. This character set is only available on platforms with GNU libiconv.
  105. `CP1133`, an extension of the ASCII character set, suitable for the Laotian. This character set is only available on platforms with GNU libc or GNU libiconv.
  106. `VISCII`, an extension of the ASCII character set, suitable for the Vietnamese. This character set is only available on platforms with GNU libc or GNU libiconv.
  107. `TCVN`, an extension of the ASCII character set, suitable for the Vietnamese. This character set is only available on platforms with GNU libc or GNU libiconv.

  Platform dependent: Only on GNU systems with GNU libc 2.2 or better and other systems (UNIX and Win32) on which the GNU libiconv C library has been installed

    The character sets provided by the library function `iconv` can also be used as encodings. To create such an encoding, call `EXT:MAKE-ENCODING` with the character set name (a string) as the `:CHARSET` argument.

    When an `EXT:ENCODING` is available both as a built-in and through `iconv`, the built-in is used, because it is more efficient and available across all platforms.

    These encodings are not assigned to global variables, since there is no portable way to get the list of all character sets supported by `iconv`.

    On GNU systems (such as GNU/Linux and GNU/Hurd) and on systems with GNU libiconv you get this list by calling the program iconv: iconv -l.

    The reason we use only GNU libc 2.2 or GNU libiconv is that the other `iconv` implementations are broken in various ways and we do not want to deal with random CLISP crashes caused by those bugs. If your system supplies an `iconv` implementation which passes the GNU libiconv's test suite, please report that to `<clisp-list@sf.net>` and a future CLISP version will use `iconv` on your system.

### 29.4.3. Line Terminators

The line terminator mode can be one of the following three keywords:

`:UNIX`
  Newline is represented by the ASCII LF character (U000A).
`:MAC`
  Newline is represented by the ASCII CR character (U000D).
`:DOS`
  Newline is represented by the ASCII CR followed by the ASCII LF.

Windows programs typically use the `:DOS` line terminator, sometimes they also accept `:UNIX` line terminators or produce `:MAC` line terminators.

The line terminator mode is relevant only for output (writing to a file/pipe/socket). During input, all three kinds of line terminators are recognized. See also Section 13.9, “Treatment of Newline during Input and Output [CLHS-13.1.8]”.

### 29.4.4. Function `EXT:MAKE-ENCODING`.

The function `(`EXT:MAKE-ENCODING` `&KEY` :CHARSET :LINE-TERMINATOR :INPUT-ERROR-ACTION :OUTPUT-ERROR-ACTION)` returns an `EXT:ENCODING`. The `:CHARSET` argument may be an encoding, a string, or `:DEFAULT`. The possible values for the line terminator argument are the keywords `:UNIX`, `:MAC`, `:DOS`.

The `:INPUT-ERROR-ACTION` argument specifies what happens when an invalid byte sequence is encountered while converting bytes to characters. Its value can be `:ERROR`, `:IGNORE` or a character to be used instead. The UNICODE character #\uFFFD is typically used to indicate an error in the input sequence.

The `:OUTPUT-ERROR-ACTION` argument specifies what happens when an invalid character is encountered while converting characters to bytes. Its value can be `:ERROR`, `:IGNORE`, a byte to be used instead, or a character to be used instead. The UNICODE character #\uFFFD can be used here only if it is encodable in the character set.

### 29.4.5. Function `EXT:ENCODING-CHARSET`.

#### Platform dependent: Only in CLISP built with compile-time flag UNICODE.

The function `(`EXT:ENCODING-CHARSET` `encoding`)` returns the charset of the `encoding`, as a `SYMBOL` or a `STRING`. Note that `(`STRING` (`EXT:ENCODING-CHARSET` `encoding`))` is not necessarily a valid MIME name.

### 29.4.6. Default encodings.

Besides every file/pipe/socket stream containing an encoding, the following `SYMBOL-MACRO` places contain global `EXT:ENCODING`s:

Macro `CUSTOM:*DEFAULT-FILE-ENCODING*`. The `SYMBOL-MACRO` place `CUSTOM:*DEFAULT-FILE-ENCODING*` is the encoding used for new file/pipe/socket streams, when no `:EXTERNAL-FORMAT` argument was specified.

Platform dependent: Only in CLISP built with compile-time flag UNICODE.

  The following are `SYMBOL-MACRO` places.

  `CUSTOM:*PATHNAME-ENCODING*`
    is the encoding used for pathnames in the file system. Normally, this is a 1:1 encoding. Its line terminator mode is ignored.
  `CUSTOM:*TERMINAL-ENCODING*`
    is the encoding used for communication with the terminal, in particular by `*TERMINAL-IO*`.
  `CUSTOM:*MISC-ENCODING*`
    is the encoding used for access to environment variables, command line options, and the like. Its line terminator mode is ignored.
  `CUSTOM:*FOREIGN-ENCODING*`
    is the encoding for characters and strings passed through the “FFI” (some plaforms only). Its value must be a 1:1 encoding, i.e., an encoding in which every character is represented by one byte.

The default encoding objects are initialized as described in -Edomain encoding

### 29.4.7. Converting between strings and byte vectors

Encodings can also be used to convert directly between strings and their corresponding byte vector representation according to that encoding.

`(`EXT:CONVERT-STRING-FROM-BYTES` `byte-vector` `encoding` `&KEY` `:START` `:END`)`
  converts the subsequence of `byte-vector` from `start` to `end` to a `STRING`, according to the given `encoding`, and returns the resulting string.
`(`EXT:CONVERT-STRING-TO-BYTES` `string` `encoding` `&KEY` `:START` `:END`)`
  converts the subsequence of `string` from `start` to `end` to a `(`VECTOR` (`UNSIGNED-BYTE` 8))`, according to the given `encoding`, and returns the resulting byte vector.

## 29.5. Extensions-1.5. Defining new kinds of Streams

Two mechanisms are supported for creating new streams with user-defined behavior:

- You can create a new subclass of `GRAY:FUNDAMENTAL-STREAM` and define methods for the elementary stream operations on it. These generic functions all have a name starting with the prefix "stream-".
- You can create a new subclass of `GSTREAM:GENERIC-STREAM-CONTROLLER` and define methods for the elementary stream operations on it. These generic functions all have a name starting with the prefix "generic-stream-". The stream itself is a different object, created using the function `gstream:make-generic-stream`.

The `FUNDAMENTAL-STREAM` API is based on the STREAM-DEFINITION-BY-USER:GENERIC-FUNCTIONS proposal by David N. Gray and is supported by most Common Lisp implementations currently in use. The `GSTREAM:GENERIC-STREAM-CONTROLLER` API is CLISP-specific and is now obsolete.

### 29.5.1. Gray streams

This interface permits the definition of new classes of streams, and programming their behavior by defining methods for the elementary stream operations. It is based on the proposal STREAM-DEFINITION-BY-USER:GENERIC-FUNCTIONS of David N. Gray to X3J13.

All symbols defined by this interface, starting with the prefix "fundamental-" or "stream-", are exported from the package “GRAY” and re-exported from “EXT”.

Defined classes

`GRAY:FUNDAMENTAL-STREAM`
  This is a superclass of all user-defined streams. It is a subclass of `STREAM` and of `STANDARD-OBJECT`. Its metaclass is `STANDARD-CLASS`.
`GRAY:FUNDAMENTAL-INPUT-STREAM`
  This is a superclass of all user-defined input `STREAM`s. It is a subclass of `GRAY:FUNDAMENTAL-STREAM`. The built-in function `INPUT-STREAM-P` returns true on instances of this class. This means that when you define a new stream class capable of doing input, you have to make it a subclass of `GRAY:FUNDAMENTAL-INPUT-STREAM`.
`GRAY:FUNDAMENTAL-OUTPUT-STREAM`
  This is a superclass of all user-defined output `STREAM`s. It is a subclass of `GRAY:FUNDAMENTAL-STREAM`. The built-in function `OUTPUT-STREAM-P` returns true on instances of this class. This means that when you define a new stream class capable of doing output, you have to make it a subclass of `GRAY:FUNDAMENTAL-OUTPUT-STREAM`.
`GRAY:FUNDAMENTAL-CHARACTER-STREAM`
  This is a superclass of all user-defined streams whose `STREAM-ELEMENT-TYPE` is `CHARACTER`. It is a subclass of `GRAY:FUNDAMENTAL-STREAM`. It defines a method on `STREAM-ELEMENT-TYPE` that returns `CHARACTER`.
`GRAY:FUNDAMENTAL-BINARY-STREAM`
  This is a superclass of all user-defined streams whose `STREAM-ELEMENT-TYPE` is a subtype of `INTEGER`. It is a subclass of `GRAY:FUNDAMENTAL-STREAM`. When you define a subclass of `GRAY:FUNDAMENTAL-BINARY-STREAM`, you have to provide a method on `STREAM-ELEMENT-TYPE`.
`GRAY:FUNDAMENTAL-CHARACTER-INPUT-STREAM`
  This is a convenience class inheriting from both `GRAY:FUNDAMENTAL-CHARACTER-STREAM` and `GRAY:FUNDAMENTAL-INPUT-STREAM`.
`GRAY:FUNDAMENTAL-CHARACTER-OUTPUT-STREAM`
  This is a convenience class inheriting from both `GRAY:FUNDAMENTAL-CHARACTER-STREAM` and `GRAY:FUNDAMENTAL-OUTPUT-STREAM`.
`GRAY:FUNDAMENTAL-BINARY-INPUT-STREAM`
  This is a convenience class inheriting from both `GRAY:FUNDAMENTAL-BINARY-STREAM` and `GRAY:FUNDAMENTAL-INPUT-STREAM`.
`GRAY:FUNDAMENTAL-BINARY-OUTPUT-STREAM`
  This is a convenience class inheriting from both `GRAY:FUNDAMENTAL-BINARY-STREAM` and `GRAY:FUNDAMENTAL-OUTPUT-STREAM`.

General generic functions defined on streams

`(`STREAM-ELEMENT-TYPE` `stream`)`

  Returns the stream's element type, normally a subtype of `CHARACTER` or `INTEGER`.

  The method for `GRAY:FUNDAMENTAL-CHARACTER-STREAM` returns `CHARACTER`.

`((`SETF` `STREAM-ELEMENT-TYPE`) `new-element-type` `stream`)`

  Changes the stream's element type.

  The default method `SIGNAL`s an `ERROR`.

  This function is a CLISP extension (see Section 21.3.1, “Function `STREAM-ELEMENT-TYPE`”).

`(`CLOSE` `stream` `&KEY` `:ABORT`)`

  Closes the stream and flushes any associated buffers.

  When you define a primary method on this function, do not forget to `CALL-NEXT-METHOD`.

`(`OPEN-STREAM-P` `stream`)`

  Returns true before the stream has been closed, and `NIL` after the stream has been closed.

  You do not need to add methods to this function.

`(`GRAY:STREAM-POSITION` `stream` `position`)`

  Just like `FILE-POSITION`, but `NIL` `position` means inquire.

  You must define a method for this function.

generic functions for character input

`(`GRAY:STREAM-READ-CHAR` `stream`)`

  If a character was pushed back using `GRAY:STREAM-UNREAD-CHAR`, returns and consumes it. Otherwise returns and consumes the next character from the stream. Returns `:EOF` if the `end-of-stream` is reached.

  You must define a method for this function.

`(`GRAY:STREAM-UNREAD-CHAR` `stream` `char`)`

  Pushes `char`, which must be the last character read from the `stream`, back onto the front of the `stream`.

  You must define a method for this function.

`(`GRAY:STREAM-READ-CHAR-NO-HANG` `stream`)`

  Returns a character or `:EOF`, like `GRAY:STREAM-READ-CHAR`, if that would return immediately. If `GRAY:STREAM-READ-CHAR`'s value is not available immediately, returns `NIL` instead of waiting.

  The default method simply calls `GRAY:STREAM-READ-CHAR`; this is sufficient for streams whose `GRAY:STREAM-READ-CHAR` method never blocks.

`(`GRAY:STREAM-PEEK-CHAR` `stream`)`

  If a character was pushed back using `GRAY:STREAM-UNREAD-CHAR`, returns it. Otherwise returns the next character from the stream, avoiding any side effects `GRAY:STREAM-READ-CHAR` would do. Returns `:EOF` if the `end-of-stream` is reached.

  The default method calls `GRAY:STREAM-READ-CHAR` and `GRAY:STREAM-UNREAD-CHAR`; this is sufficient for streams whose `GRAY:STREAM-READ-CHAR` method has no side-effects.

`(`GRAY:STREAM-LISTEN` `stream`)`

  If a character was pushed back using `GRAY:STREAM-UNREAD-CHAR`, returns it. Otherwise returns the next character from the stream, if already available. If no character is available immediately, or if `end-of-stream` is reached, returns `NIL`.

  The default method calls `GRAY:STREAM-READ-CHAR-NO-HANG` and `GRAY:STREAM-UNREAD-CHAR`; this is sufficient for streams whose `GRAY:STREAM-READ-CHAR` method has no side-effects.

`(`GRAY:STREAM-READ-CHAR-WILL-HANG-P` `stream`)`

  Returns `NIL` if `GRAY:STREAM-READ-CHAR` will return immediately. Otherwise it returns true.

  The default method calls `GRAY:STREAM-READ-CHAR-NO-HANG` and `GRAY:STREAM-UNREAD-CHAR`; this is sufficient for streams whose `GRAY:STREAM-READ-CHAR` method has no side-effects.

  This function is a CLISP extension (see `EXT:READ-CHAR-WILL-HANG-P`).

`(`GRAY:STREAM-READ-CHAR-SEQUENCE` `stream` `sequence` `&OPTIONAL` [`start` [`end`]])`

  Fills the subsequence of `sequence` specified by `:START` and `:END` with characters consecutively read from `stream`. Returns the index of the first element of `sequence` that was not updated (`=` `end`, or `<` `end` if the stream reached its end).

  `sequence` is an `ARRAY` of `CHARACTER`s, i.e. a `STRING`. `start` is a nonnegative `INTEGER` and defaults to `0`. `end` is a nonnegative `INTEGER` or `NIL` and defaults to `NIL`, which stands for `(`LENGTH` `sequence`)`.

  The default method repeatedly calls `GRAY:STREAM-READ-CHAR`; this is always sufficient if speed does not matter.

  This function is a CLISP extension (see `EXT:READ-CHAR-SEQUENCE`).

`(`GRAY:STREAM-READ-LINE` `stream`)`

  Reads a line of characters, and return two values: the line (a `STRING`, without the terminating #\Newline character), and a `BOOLEAN` value which is true if the line was terminated by `end-of-stream` instead of #\Newline.

  The default method repeatedly calls `GRAY:STREAM-READ-CHAR`; this is always sufficient.

`(`GRAY:STREAM-CLEAR-INPUT` `stream`)`

  Clears all pending interactive input from the `stream`, and returns true if some pending input was removed.

  The default method does nothing and returns `NIL`; this is sufficient for non-interactive streams.

generic functions for character output

`(`GRAY:STREAM-WRITE-CHAR` `stream` `char`)`

  Writes `char`.

  You must define a method for this function.

`(`GRAY:STREAM-LINE-COLUMN` `stream`)`

  Returns the column number where the next character would be written (`0` stands for the first column), or `NIL` if that is not meaningful for this stream.

  You must define a method for this function.

`(`GRAY:STREAM-START-LINE-P` `stream`)`

  Returns true if the next character would be written at the start of a new line.

  The default method calls `GRAY:STREAM-LINE-COLUMN` and compares its result with 0; this is sufficient for streams whose `GRAY:STREAM-LINE-COLUMN` never returns `NIL`.

`(`GRAY:STREAM-WRITE-CHAR-SEQUENCE` `stream` `sequence` `&OPTIONAL` [`start` [`end`]])`

  Outputs the subsequence of `sequence` specified by `:START` and `:END` to `stream`.

  `sequence` is an `ARRAY` of `CHARACTER`s, i.e. a `STRING`. `start` is a nonnegative `INTEGER` and defaults to 0. `end` is a nonnegative integer or `NIL` and defaults to `NIL`, which stands for `(`LENGTH` `sequence`)`.

  The default method repeatedly calls `GRAY:STREAM-WRITE-CHAR`; this is always sufficient if speed does not matter.

  This function is a CLISP extension (see `EXT:WRITE-CHAR-SEQUENCE`).

`(`GRAY:STREAM-WRITE-STRING` `stream` `string` `&OPTIONAL` [`start` [`end`]])`

  Outputs the subsequence of `string` specified by `:START` and `:END` to `stream`. Returns `string`.

  `string` is a string. `start` is a nonnegative integer and default to 0. `end` is a nonnegative integer or `NIL` and defaults to `NIL`, which stands for `(`LENGTH` `string`)`.

  The default method calls `GRAY:STREAM-WRITE-CHAR-SEQUENCE`; this is always sufficient.

`(`GRAY:STREAM-TERPRI` `stream`)`

  Outputs a #\Newline character.

  The default method calls `GRAY:STREAM-WRITE-CHAR`; this is always sufficient.

`(`GRAY:STREAM-FRESH-LINE` `stream`)`

  Possibly outputs a #\Newline character, so as to ensure that the next character would be written at the start of a new line. Returns true if it did output a #\Newline character.

  The default method calls `GRAY:STREAM-START-LINE-P` and then `GRAY:STREAM-TERPRI` if necessary; this is always sufficient.

`(`GRAY:STREAM-FINISH-OUTPUT` `stream`)`

  Ensures that any buffered output has reached its destination, and then returns.

  The default method does nothing.

`(`GRAY:STREAM-FORCE-OUTPUT` `stream`)`

  Brings any buffered output on its way towards its destination, and returns without waiting until it has reached its destination.

  The default method does nothing.

`(`GRAY:STREAM-CLEAR-OUTPUT` `stream`)`

  Attempts to discard any buffered output which has not yet reached its destination.

  The default method does nothing.

`(`GRAY:STREAM-ADVANCE-TO-COLUMN` `stream` `column`)`

  Ensures that the next character will be written at `column` at least.

  The default method outputs an appropriate amount of space characters; this is sufficient for non-proportional output.

generic functions for binary input

`(`GRAY:STREAM-READ-BYTE` `stream`)`

  Returns and consumes the next integer from the stream. Returns `:EOF` if the `end-of-stream` is reached.

  You must define a method for this function.

`(`GRAY:STREAM-READ-BYTE-LOOKAHEAD` `stream`)`

  To be called only if `stream`'s `STREAM-ELEMENT-TYPE` is `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`. Returns `T` if `GRAY:STREAM-READ-BYTE` would return immediately with an `INTEGER` result. Returns `:EOF` if the `end-of-stream` is already known to be reached. If `GRAY:STREAM-READ-BYTE`'s value is not available immediately, returns `NIL` instead of waiting.

  You must define a method for this function.

  This function is a CLISP extension (see `EXT:READ-BYTE-LOOKAHEAD`).

`(`GRAY:STREAM-READ-BYTE-WILL-HANG-P` `stream`)`

  To be called only if `stream`'s `STREAM-ELEMENT-TYPE` is `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`. Returns `NIL` if `GRAY:STREAM-READ-BYTE` will return immediately. Otherwise it returns true.

  The default method calls `GRAY:STREAM-READ-BYTE-LOOKAHEAD`; this is always sufficient.

  This function is a CLISP extension (see `EXT:READ-BYTE-WILL-HANG-P`).

`(`GRAY:STREAM-READ-BYTE-NO-HANG` `stream`)`

  To be called only if `stream`'s `STREAM-ELEMENT-TYPE` is `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`. Returns an `INTEGER` or `:EOF`, like `GRAY:STREAM-READ-BYTE`, if that would return immediately. If `GRAY:STREAM-READ-BYTE`'s value is not available immediately, returns `NIL` instead of waiting.

  The default method calls `GRAY:STREAM-READ-BYTE` if `GRAY:STREAM-READ-BYTE-LOOKAHEAD` returns true; this is always sufficient.

  This function is a CLISP extension (see `EXT:READ-BYTE-NO-HANG`).

`(`GRAY:STREAM-READ-BYTE-SEQUENCE` `stream` `sequence` `&OPTIONAL` [`start` [`end` [`no-hang`]]])`

  Fills the subsequence of `sequence` specified by `:START` and `:END` with integers consecutively read from `stream`. Returns the index of the first element of `sequence` that was not updated (`=` `end`, or `<` `end` if the stream reached its end).

  `sequence` is an `ARRAY` of `INTEGER`s. `start` is a nonnegative `INTEGER` and defaults to 0. `end` is a nonnegative `INTEGER` or `NIL` and defaults to `NIL`, which stands for `(`LENGTH` `sequence`)`.

  The default method repeatedly calls `GRAY:STREAM-READ-BYTE`; this is always sufficient if speed does not matter.

  This function is a CLISP extension (see `EXT:READ-BYTE-SEQUENCE`).

generic functions for binary output

`(`GRAY:STREAM-WRITE-BYTE` `stream` `integer`)`

  Writes `integer`.

  You must define a method for this function.

`(`GRAY:STREAM-WRITE-BYTE-SEQUENCE` `stream` `sequence` `&OPTIONAL` [`start` [`end` [`no-hang`]]])`

  Outputs the subsequence of `sequence` specified by `:START` and `:END` to `stream`

  `sequence` is an `ARRAY` of `INTEGER`s. `start` is a nonnegative `INTEGER` and defaults to 0. `end` is a nonnegative `INTEGER` or `NIL` and defaults to `NIL`, which stands for `(`LENGTH` `sequence`)`.

  The default method repeatedly calls `GRAY:STREAM-WRITE-BYTE`; this is always sufficient if speed does not matter.

  This function is a CLISP extension (see `EXT:WRITE-BYTE-SEQUENCE`).

### 29.5.2. Generic streams

This interface is CLISP-specific and now obsolete. Please use the Gray streams interface instead.

Generic streams are user programmable streams. The programmer interface:

`(`gstream:make-generic-stream` `controller`)`
  returns a generic stream.
`(`gstream: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 `gstream:make-generic-stream`.
`(`gstream:generic-stream-p` `stream`)`
  determines whether a stream is a generic stream, returning `T` if it is, `NIL` otherwise.

In order to specify the behavior of a generic stream, the user must define CLOS methods on the following CLOS generic functions. The function `gstream:generic-stream-`xyz`` corresponds to the Common Lisp function ``xyz``. They all take a controller and some number of arguments.

`(`gstream:generic-stream-read-char` `controller`)`
  Returns and consumes the next character, `NIL` at end of file. Takes one argument, the controller object.
`(`gstream:generic-stream-peek-char` `controller`)`
  Returns the next character, `NIL` at end of file. A second value indicates whether the side effects associated with consuming the character were executed: `T` means that a full `READ-CHAR` was done, `NIL` means that no side effects were done. Takes one argument, the controller object.
`(`gstream:generic-stream-read-byte` `controller`)`
  Returns and consumes the next integer, `NIL` at end of file. Takes one argument, the controller object.
`(`gstream:generic-stream-read-char-will-hang-p` `controller`)`
  This generic function is used to query the stream's input status. It returns `NIL` if `gstream:generic-stream-read-char` and `gstream:generic-stream-peek-char` will certainly return immediately. Otherwise it returns true.
`(`gstream:generic-stream-write-char` `controller` `char`)`
  The first argument is the controller object. The second argument is the character to be written.
`(`gstream:generic-stream-write-byte` `controller` `by`)`
  The first argument is the controller object. The second argument is the integer to be written.
`(`gstream:generic-stream-write-string` `controller` `string` `start` `length`)`
  Writes the subsequence of `string` starting from `start` of length `length`. The first argument is the controller object.
`(`gstream:generic-stream-clear-input` `controller`)`
`(`gstream:generic-stream-clear-output` `controller`)`
`(`gstream:generic-stream-finish-output` `controller`)`
`(`gstream:generic-stream-force-output` `controller`)`
`(`gstream:generic-stream-close` `controller`)`
  Take one argument, the controller object.

## 29.6. Extensions-1.6. Weak Pointers

A weak pointer is an object holding a reference to a given object, without keeping the latter from being garbage-collected.

`(`EXT:MAKE-WEAK-POINTER` `value`)`
  returns a fresh weak pointer referring to `value`.
`(`EXT:WEAK-POINTER-P` `object`)`
  returns true if the `object` is of type `EXT:WEAK-POINTER`.
`(`EXT:WEAK-POINTER-VALUE` `weak-pointer`)`
  returns two values: The original value and `T`, if the value has not yet been garbage-collected, else `NIL` and `NIL`. It is `SETF`-able: you can change the value that the weak pointer points to.

CLISP also has weak `HASH-TABLE`.

## 29.7. Extensions-1.7. Finalization

Calling `(`EXT:FINALIZE` `object` `function`)` has the effect that when the specified object is being garbage-collected, `(`FUNCALL` `function` `object`)` will be executed.

Calling `(`EXT: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 “the `object` is being garbage-collected” is not defined deterministically. (Actually, it might possibly never occur.) 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.

## 29.8. Extensions-1.8. The Prompt

CLISP prompt consists of 3 mandatory parts: “start”, “body”, and “finish”; and 2 optional parts: “break”, which appears only during debugging (after `BREAK` or `ERROR`), and “step”, which appears only during `STEP`ping. Each part is controlled by a custom variable, which can be either a `STRING` or a `FUNCTION` of no arguments returning a `STRING` (if it is something else - or if the return value was not a `STRING` - it is printed with `PRINC`). In the order of invocation:

`CUSTOM:*PROMPT-START*`
  Defaults to an empty string.
`CUSTOM:*PROMPT-STEP*`
  Used only during `STEP`ping. Defaults to `"Step n "`, where `n` is the stepping level as returned by `EXT:STEP-LEVEL`.
`CUSTOM:*PROMPT-BREAK*`
  Used only inside break loop (during debugging). Defaults to `"Break n "`, where `n` is the break level as returned by `EXT:BREAK-LEVEL`.
`CUSTOM:*PROMPT-BODY*`
  Defaults to `"package[n]"` where `package` is the shortest (nick)name (as returned by `EXT:PACKAGE-SHORT-NAME`) of the current package `*PACKAGE*` if it is not the same as it was in the beginning (determined by `EXT:PROMPT-NEW-PACKAGE`) or if it does not contain symbol `T`, (it is assumed that in the latter case you would want to keep in mind that your current package is something weird); and `n` is the index of the current prompt, kept in `EXT:*COMMAND-INDEX*`;
`CUSTOM:*PROMPT-FINISH*`
  Defaults to `>` .

To facilitate your own custom prompt creation, the following functions and variables are available:

`EXT:BREAK-LEVEL`
  This `FUNCTION` returns current `BREAK`/`ERROR` level.
`EXT:STEP-LEVEL`
  This `FUNCTION` returns current `STEP` level.
`EXT:PROMPT-NEW-PACKAGE`
  This `FUNCTION` returns `*PACKAGE*` or `NIL` if the current package is the same as it was initially.
`EXT:PACKAGE-SHORT-NAME`
  This `FUNCTION` takes one argument, a `PACKAGE`, and returns its shortest name or nickname.
`EXT:*COMMAND-INDEX*`
  contains the current prompt number; it is your responsibility to increment it (this variable is bound to 0 before saving the memory image).

## 29.9. Extensions-1.9. Maximum ANSI CL compliance

Some [ANSI CL standard] features are turned off by default for backwards compatibility. They can be switched on, all at once, by setting the `SYMBOL-MACRO` `CUSTOM:*ANSI*` to `T`, or they can be switched on individually. Setting `CUSTOM:*ANSI*` to `T` implies the following:

- Setting `CUSTOM:*PRINT-PATHNAMES-ANSI*` to `T`.
- Setting `CUSTOM:*COERCE-FIXNUM-CHAR-ANSI*` to `T`.
- Setting `CUSTOM:*SEQUENCE-COUNT-ANSI*` to `T`.
- Setting `CUSTOM:*MERGE-PATHNAMES-ANSI*` to `T`.
- Setting `CUSTOM:*PARSE-NAMESTRING-ANSI*` to `T`.
- Setting `CUSTOM:*FLOATING-POINT-CONTAGION-ANSI*` to `T`.

Note that if you run CLISP with the `-ansi` switch or set the `SYMBOL-MACRO` `CUSTOM:*ANSI*` to `T` and then save memory image, then all subsequent invocations of CLISP with this image will be as if with `-ansi` (regardless whether you actually supply the `-ansi` switch). You can always set the `SYMBOL-MACRO` `CUSTOM:*ANSI*` to `NIL`, or invoke CLISP with the `-traditional` switch, reversing the above settings, i.e.,

- Setting `CUSTOM:*PRINT-PATHNAMES-ANSI*` to `NIL`.
- Setting `CUSTOM:*COERCE-FIXNUM-CHAR-ANSI*` to `NIL`.
- Setting `CUSTOM:*SEQUENCE-COUNT-ANSI*` to `NIL`.
- Setting `CUSTOM:*MERGE-PATHNAMES-ANSI*` to `NIL`.
- Setting `CUSTOM:*PARSE-NAMESTRING-ANSI*` to `NIL`.
- Setting `CUSTOM:*FLOATING-POINT-CONTAGION-ANSI*` to `NIL`.

## 29.10. Extensions-1.10. Additional Fancy Macros

CLISP comes with some extension macros, mostly defined in the file `macros3.lisp` and loaded from the file `init.lisp` during make:

Macro `EXT:ETHE`. `(`EXT:ETHE` `value-type` `form`)` enforces a type check in both interpreted and compiled code.

Macros `EXT:LETF` & `EXT:LETF*`. These macros are similar to `LET` and `LET*`, respectively, 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 ...)

while

    (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)))

Macro `EXT:WITH-COLLECT`. Similar to the `LOOP`'s `collect` construct, except that it is looks more "Lispy" and can appear arbitrarily deep. It defines local macros (with `MACROLET`) which collect objects given to it into lists, which are then returned as multiple values. E.g.,

     (ext:with-collect (c0 c1)
       (dotimes (i 10) (if (oddp i) (c0 i) (c1 i))))

returns two lists `(1 3 5 7 9)` and `(0 2 4 6 8)` as multiple values.

Macro `EXT:WITH-GENSYMS`. Similar to its namesake from Paul Graham's book “On Lisp”, this macro is useful for writing other macros:

     (with-gensyms ("FOO-" bar baz zot) ...)

expands to

     (let ((bar (gensym "FOO-BAR-"))
           (baz (gensym "FOO-BAZ-"))
           (zot (gensym "FOO-ZOT-")))
       ...)

Function `EXT:REMOVE-PLIST`. Similar to `REMOVE` and `REMF`, this function removes some properties from a property list. It is non-destructve and thus can be used on `&REST` arguments to remove some keyword parameters, e.g.,

     (defmacro with-foo ((&KEY foo1 foo2) &BODY body)
       `(... ,foo1 ... ,foo2 ... ,@body))
     (defmacro with-foo-bar ((&REST opts &KEY bar1 bar2
                              &ALLOW-OTHER-KEYS)
                             &BODY body)
       `(with-foo (,@(remove-plist opts :bar1 :bar2)
          ... ,bar1 ... ,bar2 ... ,@body)))
     (defun foo-bar ()
       (with-foo-bar (:bar1 1 :foo2 2) ...))

here `WITH-FOO` does not receive the `:BAR1 1` argument from `FOO-BAR`.

Macros `EXT:WITH-HTML-OUTPUT` and `EXT:WITH-HTTP-OUTPUT`. Defined in `inspect.lisp`, these macros are useful for the rudimentary HTTP server defined there.

## 29.11. Extensions-1.11. Customizing CLISP behavior.

The user-customizable variables are located in the package “CUSTOM” and thus can be listed using `(`APROPOS` "" "CUSTOM")`:

`CUSTOM:*ANSI*` | `CUSTOM:*APPLYHOOK*`
`CUSTOM:*APROPOS-DO-MORE*` | `CUSTOM:*APROPOS-MATCHER*`
`CUSTOM:*BREAK-ON-WARNINGS*` | `CUSTOM:*BROWSER*`
`CUSTOM:*BROWSERS*` | `CUSTOM:*CLHS-ROOT-DEFAULT*`
`CUSTOM:*COERCE-FIXNUM-CHAR-ANSI*` | `CUSTOM:*COMPILE-WARNINGS*`
`CUSTOM:*COMPILED-FILE-TYPES*` | `CUSTOM:*CURRENT-LANGUAGE*`
`CUSTOM:*DEFAULT-FILE-ENCODING*` | `CUSTOM:*DEFAULT-FLOAT-FORMAT*`
`CUSTOM:*DEFAULT-TIME-ZONE*` | `CUSTOM:*DEFTYPE-DEPTH-LIMIT*`
`CUSTOM:*DEVICE-PREFIX*` | `CUSTOM:*EDITOR*`
`CUSTOM:*ERROR-HANDLER*` | `CUSTOM:*EVALHOOK*`
`CUSTOM:*FLOATING-POINT-CONTAGION-ANSI*` | `CUSTOM:*FOREIGN-ENCODING*`
`CUSTOM:*INSPECT-BROWSER*` | `CUSTOM:*INSPECT-FRONTEND*`
`CUSTOM:*INSPECT-LENGTH*` | `CUSTOM:*INSPECT-PRINT-LENGTH*`
`CUSTOM:*INSPECT-PRINT-LEVEL*` | `CUSTOM:*INSPECT-PRINT-LINES*`
`CUSTOM:*LIB-DIRECTORY*` | `CUSTOM:*LOAD-COMPILING*`
`CUSTOM:*LOAD-ECHO*` | `CUSTOM:*LOAD-LOGICAL-PATHNAME-TRANSLATIONS-DATABASE*`
`CUSTOM:*LOAD-OBSOLETE-ACTION*` | `CUSTOM:*LOAD-PATHS*`
`CUSTOM:*MERGE-PATHNAMES-ANSI*` | `CUSTOM:*MISC-ENCODING*`
`CUSTOM:*PACKAGE-TASKS-TREAT-SPECIALLY*` | `CUSTOM:*PARSE-NAMESTRING-ANSI*`
`CUSTOM:*PARSE-NAMESTRING-DOT-FILE*` | `CUSTOM:*PATHNAME-ENCODING*`
`CUSTOM:*PPRINT-FIRST-NEWLINE*` | `CUSTOM:*PRINT-CLOSURE*`
`CUSTOM:*PRINT-INDENT-LISTS*` | `CUSTOM:*PRINT-PATHNAMES-ANSI*`
`CUSTOM:*PRINT-PRETTY-FILL*` | `CUSTOM:*PRINT-RPARS*`
`CUSTOM:*PRINT-SYMBOLS-LONG*` | `CUSTOM:*PROMPT-BODY*`
`CUSTOM:*PROMPT-BREAK*` | `CUSTOM:*PROMPT-FINISH*`
`CUSTOM:*PROMPT-START*` | `CUSTOM:*PROMPT-STEP*`
`CUSTOM:*SEQUENCE-COUNT-ANSI*` | `CUSTOM:*SOURCE-FILE-TYPES*`
`CUSTOM:*SUPPRESS-CHECK-REDEFINITION*` | `CUSTOM:*SYSTEM-PACKAGE-LIST*`
`CUSTOM:*TERMINAL-ENCODING*` | `CUSTOM:*TRACE-INDENT*`
`CUSTOM:*USER-MAIL-ADDRESS*` | `CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION*`
`CUSTOM:*WITH-HTML-OUTPUT-DOCTYPE*` |

### Note

Some of these variables are platform-specific.

You should set these variables (and do whatever other customization you see fit) in the file `#P"config.lisp"` in the build directory before building CLISP. Alternatively, after building CLISP, or if you are using a binary distribution of CLISP, you can modify `#P"config.lisp"`, compile and load it, and then save the memory image. Finally, you can create an “RC” (run control) file which is loaded whenever CLISP is started (see the documentation for option `-norc` in your platform-specific copy of the manual page).

## 29.12. Extensions-1.12. Code Walker

You can use `EXT:EXPAND-FORM` to expand all the macros, `SYMBOL-MACRO`s, etc, in a single form:

     (expand-form '(macrolet ((bar (x) `(print ,x)))
                     (macrolet ((baz (x) `(bar ,x)))
                       (symbol-macrolet ((z 3))
                         (baz z)))))

returns two values: `(locally (print 3))` (the expansion) and `T` (an indicator that some expansion has actually been done).

This is sometimes called a “code walker”, except that the code walker would probably leave the `MACROLET` and `SYMBOL-MACROLET` forms intact and just do the expansion.

## Chapter 30. Extensions-2: Platform specific Extensions

## 30.1. Extensions-2.1. Random Screen Access

### Platform dependent: UNIX, Win32 platforms only.

`(`SCREEN:MAKE-WINDOW`)`
  returns a WINDOW-STREAM. As long as this stream is open, the terminal is in cbreak/noecho mode. `*TERMINAL-IO*` should not be used for input or output during this time. (Use `EXT:WITH-KEYBOARD` and `EXT:*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*` should not 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.

## 30.2. Extensions-2.2. External Modules

### Platform dependent: UNIX and Win32 platforms only.

### Modules on Win32.

Everything described in the section will work verbatim on Win32 when using Cygwin or MinGW, except for one thing - you will need to replace the `run` extension in `lisp.run` with the Win32 executable extension `exe`.

For historical reasons, all examples appear to assume UNIX and use the `run` file type (“extension”) for the CLISP run-time. This does not mean that they will not work on Win32.

### 30.2.1. Overview

CLISP has a facility for adding external modules (written in C, for example). It is invoked through clisp-link.

A module is a piece of external code which defines extra Lisp objects, symbols and functions. A module name must consist of the characters `A`-`Z`, `a`-`z`, `_`, `0`-`9`. The module name “clisp” is reserved. Normally a module name is derived from the corresponding file name.

clisp-link needs a directory containing:

- `modules.d`
- `modules.c`
- `clisp.h`

clisp-link expects to find these files in a subdirectory `linkkit/` of the current directory. This can be overridden by the environment variable `CLISP_LINKKIT`.

clisp-link operates on CLISP linking sets and on module sets.

linking set. A linking set is a directory containing:

`makevars`

  some /bin/sh commands, setting the variables

  `CC`
    the C compiler
  `CPPFLAGS`
    flags for the C compiler, when preprocessing or compiling
  `CFLAGS`
    flags for the C compiler, when compiling or linking
  `CLFLAGS`
    flags for the C compiler, when linking
  `LIBS`
    libraries to use when linking
  `X_LIBS`
    additional X Window System libraries to use
  `RANLIB`
    the ranlib command
  `FILES`
    the list of files needed when linking
`modules.h`
  the list of modules contained in this linking set
`modules.o`
  the compiled list of modules contained in this linking set
all the `FILES`
  listed in `makevars`
`lisp.run`
  the executable
`#P"lispinit.mem"`
  the memory image

To run a CLISP contained in some linking set `dir`, call `dir`/lisp.run -M `dir`/lispinit.mem

module set. A module set is a directory containing:

link.sh
  some /bin/sh commands, which prepare the directory before linking, and set the variables `NEW_FILES`, `NEW_LIBS`, `NEW_MODULES`, `TO_LOAD` and optionally `TO_PRELOAD`
and any other files
  needed by link.sh

Note that in link.sh the module set directory is referred to as `$modulename/`.

`NEW_FILES`
  the space-separated list of files that belong to the module set and will belong to every new linking set.
`NEW_LIBS`
  the space-separated list of files or C compiler switches that need to be passed to the C compiler when linking the lisp.run belonging to a new linking set.
`NEW_MODULES`
  the space-separated list of the module names belonging to the module set. Normally, every `#P".c"` file in the module set defines a module of its own. The module name is derived from the file name.
`TO_LOAD`
  the space-separated list of Lisp files to load before building the `#P"lispinit.mem"` belonging to a new linking set.
`TO_PRELOAD` (optional)
  the space-separated list of Lisp files to load into an intermediate `#P"lispinit.mem"` file, before building the `#P"lispinit.mem"` belonging to a new linking set. This variable is usually used for defining Lisp packages which must be present when the new `#P".c"` files are initialized. E.g., the `FFI:DEF-CALL-IN` functions must reside in already defined packages; see Example 30.9, “Calling Lisp from C”.

The command clisp-link create-module-set `module-dir` `file1.c` ... creates a module set in `module-dir` which refers (via symbolic links) to `file1.c` etc. The files are expected to be modules of their own.

The command clisp-link add-module-set `module-dir` `source-dir` `destination-dir` combines a linking set in `source-dir` and a module in `module-dir` to a new linking set, in a directory `destination-dir` which is newly created.

The command clisp-link run `source-dir` `module-dir` ... runs the linking set in `source-dir`, with the module in `module-dir` loaded. More than one module can be specified. If CLISP has been built with the configuration option `--with-dynamic-modules`, the loading will be performed through dynamic loading. Otherwise - this is much slower - a temporary linking set will be created and deleted afterwards. Note that dynamic loading does not work on all operating systems, and that `--with-dynamic-modules` precludes some efficiency optimizations which are enabled by default.

### 30.2.2. Function `EXT:MODULE-INFO`

Function `(`EXT:MODULE-INFO` `&OPTIONAL` `name` `verbose`)` allows one to inquire about what modules are available in the currently running image. When called without arguments, it returns the list of module names, starting with “clisp”. When `name` is supplied and names a module, 3 values are returned - `name`, `subr-count`, `object-count`. When `verbose` is non-`NIL`, the full list of module lisp function names written in C (Subrs) and the full list of internal lisp objects available in C code are additionally returned for the total of 5 values.

### 30.2.3. Function `SYS::DYNLOAD-MODULES`

#### Platform dependent: some UNIX platforms only, compiled with compile-time flag `--with-dynamic-modules`.

### Note

Note that dynamic loading does not work on all operating systems (`dlopen` is required), and that `--with-dynamic-modules` precludes some efficiency optimizations which are on by default.

Function `(`SYS::DYNLOAD-MODULES` `filename` ({`name`}+))` loads a shared object file or library containing a number of named external CLISP modules. This facility cannot be used to `dlopen` and access arbitrary shared libraries.

External modules for CLISP are those which contain a `module__`name`__subr_tab`, among others. This serves to register external functions which operate on Lisp-level structures with CLISP.

To use `dlopen` with modules, you should add `-fPIC` to the module's compilation options. Something like cc -shared -o `name`.so `name`.o may be needed to produce the shared object file.

### 30.2.4. Example

To link in the “FFI” bindings for the GNU/Linux operating system, the following steps are needed. (Step 1 and step 2 need not be executed in this order.)

1. Create a new module set:

       $ clisp-link create-module-set linux /somewhere/bindings/linux.c

   Modify the newly created `linux/link.sh` to add `-lm`; to the libraries: replace

       NEW_LIBS="$file_list"

   with

       NEW_LIBS="$file_list -lm"

   Modify the newly created `linux/link.sh` to load `linux.fas` before saving the memory image: replace

       TO_LOAD=''

   with

       TO_LOAD='/somewhere/bindings/linux.fas'

2. Compile `linux.lisp`, creating `linux.c`:

       $ clisp -c /somewhere/bindings/linux.lisp

3. Create a new linking set:

       $ clisp-link add-module-set linux base base+linux

4. Run and try it:

       $ base+linux/lisp.run -M base+linux/lispinit.mem -x '(linux:stat "/tmp")'

### 30.2.5. Module tools

There are some tools to facilitate easy module writing.

#### 30.2.5.1. Modprep

If your module is written in C, you can pre-process your sources with `modprep.lisp` in the CLISP distribution and define lisp functions with the `DEFUN` macro:

    DEFUN(MY-PACKAGE:MY-FUNCTION-NAME, arg1 arg2 &KEY FOO BAR) {
      if (!boundp(STACK_0)) STACK_0 = fixnum(0); /* BAR */
      if (!boundp(STACK_1)) STACK_1 = fixnum(1); /* FOO */
      pushSTACK(`MY-PACKAGE::SOME-SYMBOL`); /* create a symbol in the package */
      pushSTACK(`#(:THIS :IS :A :VECTOR)`); /* some vector, created once */
      pushSTACK(``MY-PACKAGE::MY-FUNCTION-NAME``); /* double `` means FUNCTION */
      VALUES1(listof(7)); /* cons up a new list and clean up the STACK */
    }

Then `(MY-PACKAGE:MY-FUNCTION-NAME 'A 12 :FOO T)` will return `(A 12 T 0 MY-PACKAGE::SOME-SYMBOL #(:THIS :IS :A :VECTOR) #<ADD-ON-SYSTEM-FUNCTION MY-PACKAGE:MY-FUNCTION-NAME>)` (assuming you `EXPORT`ed `MY-FUNCTION-NAME` from “MY-PACKAGE”).

Another useful macro is `DEFVAR` which lets you create a GC-visible object.

See `modules/syscalls` and other included modules for more examples and file `modprep.lisp` for full documentation.

### Warning

If you manipulate Lisp objects, you need to watch for GC-safety.

#### 30.2.5.2. Exporting

If your module uses “FFI” to interface to a C library, you might want to make your module package case-sensitive and use `exporting.lisp` in the CLISP distribution to make all “FFI” forms export the symbols they define. See `modules/netica` and `modules/bindings/*` for examples.

### 30.2.6. Modules included in the distribution.

The following modules come with the distribution of CLISP:

bindings

  Call the operating system functions from CLISP. The following platforms are supported:

  - Linux/GNU libc
  - Win32
CLX

  Call Xlib functions from CLISP. Two implementations are supplied:

  - mit-clx, from MIT ftp://ftp.x.org/R5contrib/CLX.R5.02.tar.Z - the standard implementation
  - new-clx, by Gilbert Baumann - faster, with additional features, but not quite complete yet.
oracle
  Access Oracle from CLISP; by John Hinsdale.
fastcgi
  Access FastCGI from CLISP; by John Hinsdale.
netica
  Work with Bayesian belief networks and influence diagrams using Netica.
postgresql
  Access PostgreSQL from CLISP.
queens
  Compute the number of solutions to the n-queens problem on a n*n checkboard (a toy example for the users to explore).
dirkey
  Directory Access
berkeley-db
  Berkeley DB from Sleepycat Software interface
regexp
  The POSIX Regular Expressions matching, compiling, executing.
pcre
  The Perl Compatible Regular Expressions matching, compiling, executing.
syscalls
  Use some system calls in a platform-independent way.
wildcard
  Shell (/bin/sh) globbing

#### 30.2.6.1. Netica Interface

This is an interface to the Netica C API. The package “NETICA” is case-sensitive, you would write `(netica:GetNodeExpectedUtils_bn ...)` when you need to call `GetNodeExpectedUtils_bn()`

Additionally, some higher level functionality is available (see `modules/netica/demo.lisp` for a sample usage):

`(netica:start-netica `&KEY` :license :verbose)`
  Call `NewNeticaEnviron_ns()` and `InitNetica_bn()` and print some statistics; initialize `netica:*env*`.
`(netica:check-errors `&KEY` :env :clear :severity)`
  Show and, optionally, clear, the errors of the given severity and above. You should call this function after every call to a Netica function. Every wrapper function in this list calls it, so you do not need to call it after a call to a wrapper function.
`(netica:error-message error)`
  Convert netica error to a `STRING` containing error category, error severity, error number, error message.
`(netica:close-netica `&KEY` :env :verbose)`
  Terminate the netica session. Sets `netica:*env*` to `NIL` when it was closed.
`(netica:make-net `&KEY` :name :comment :title :env :verbose)`
  Make a new network with a given name, title and comment and return it.
`(netica:net-info net)`
  Print some information about the net (name, title, comment, file name and nodes).
`(netica:make-node `&KEY` :name :net :kind :levels :states :num-states :title :comment :parents :cpt :x :y :env :verbose)`
  Make a new node with the given name and many other parameters.
`(netica:node-info node `&KEY` :header)`
  Print some information about the node, preceded by the header.
`(netica:get-beliefs node `&KEY` :env :verbose)`
  Get the belief vector for the node.
`(netica:enter-finding net node state `&KEY` :env :verbose)`
  Enter a finding by node and state names.
`(netica:save-net net `&KEY` :file :env :verbose)`
  Write a network to a file.
`(netica:read-net file `&KEY` :env :verbose)`
  Read a network from a file.
`(netica:with-open-dne-file (var file `&REST` opts) `&BODY` body)`
  Open a netica stream, execute `body`, close the stream - just like `WITH-OPEN-FILE`.
`netica:*verbose*`
  The log `STREAM` or `NIL`; the default value for the `:VERBOSE` argument.
`netica:*license*`
  The license key provided by Norsys; the default value for the `:LICENSE` argument.
`netica:*env*`
  The Netica environment object; the default value for the `:ENV` argument.

#### 30.2.6.2. Directory Access

This module provides some directory access from lisp, in package “LDAP”. 3 types of directory keys may exist, depending on the compilation environment.

valid directory key types

:win32
  Win32 registry access
:gnome
  gnome-config access
:ldap
  LDAP interface via OpenLDAP or compatible

The following functions and macros are exported (please note that these features are experimental and the API may be modified in the future).

`(`LDAP:DIR-KEY-OPEN` `dkey` `pathname` `&KEY` (`:DIRECTION` `:INPUT`) `:IF-DOES-NOT-EXIST`)`
  Open the directory key under `dkey`, which should be either an open directory key or a valid directory key type. The meaning of the `:DIRECTION` and `:IF-DOES-NOT-EXIST` keyword arguments is the same as for `OPEN`.
`(`LDAP:DIR-KEY-CLOSE` `dkey`)`
  Close the directory key. The preferred way is to use the `LDAP:WITH-DIR-KEY-OPEN` macro.
`(`LDAP:WITH-DIR-KEY-OPEN` (`variable` `dkey` `pathname` `&REST` {`option`}*) `&BODY` `body`)`
  Open the directory key (by calling `LDAP:DIR-KEY-OPEN` on `dkey`, `pathname` and `option`s), bind it to `variable`, execute `body`, then close it with `LDAP:DIR-KEY-CLOSE`.
`(`LDAP:DIR-KEY-TYPE` `dkey`)`
  Return the directory key type of the directory key
`(`LDAP:DIR-KEY-PATH` `dkey`)`
  Return the path of this directory key, which is the `pathname` argument of `LDAP:DIR-KEY-OPEN` if `dkey` was a directory key type or the concatenation of the `pathname` argument and the `ldap:dir-key-path` of `dkey`.
`(`LDAP:DIR-KEY-DIRECTION` `dkey`)`
  One of `:INPUT`, `:OUTPUT` and `:IO`, indicating the permitted operation on this key and its derivatives.
`(`LDAP:DIR-KEY-CLOSED-P` `dkey`)`
  Check whether the key has been closed. It is not an error to close a closed key.
`(`LDAP:DIR-KEY-SUBKEY-DELETE` `dkey` `subkey`)` `(`LDAP:DIR-KEY-VALUE-DELETE` `dkey` `attribute`)`
  Delete the specified subkey or attribute.
`(`LDAP:DIR-KEY-SUBKEY` `dkey`)` `(`LDAP:DIR-KEY-ATTRIBUTES` `dkey`)`
  Return the list of the subkeys or attributes.
`(`LDAP:DIR-KEY-VALUE` `dkey` `attribute` `&OPTIONAL` `default`)`
  Return the value of the specified attribute, similar to `GETHASH` and `SETF`able just like `GETHASH`.
`(`LDAP:DIR-KEY-INFO` `dkey`)`
  Return some information about the directory key. This is highly platform-dependent and will probably be removed or replaced or modified in the future.
`(`LDAP:WITH-DIR-KEY-SEARCH` (`key-iter` `atribute-iter` `dkey` `pathname` `&KEY` `:scope`) `&BODY` `body`)`

  This is the main way to iterate over the subtree under the key `dkey`+`pathname`.

  `key-iter` is a non-`NIL` symbol and is bound via `MACROLET` to a macro, each call of which returns the next subkey.

  `atribute-iter` is a symbol and is bound, when non-`NIL`, to a macro, each call of which returns two values - the next attribute and its value.

  The `:scope` keyword argument specifies the scope of the search and can be

  `:self`
    iterate over the key itself
  `:level`
    iterate over the children of the key
  `:tree`
    iterate over the subtree

  `LDAP:WITH-DIR-KEY-SEARCH` is used to implement `LDAP:DIR-KEY-VALUES`, `LDAP:DIR-KEY-CHILDREN` and `LDAP:DIR-KEY-DUMP-TREE` in `dirkey.lisp`.

#### 30.2.6.3. Berkeley DB access.

This interface to Berkeley DB from Sleepycat Software exports almost all functions in the official C API.

##### 30.2.6.3.1. Database Environment

`(BDB:DB-VERSION)`
  Return version information as 4 values: descriptive `STRING` and 3 `FIXNUM`s: major, minor and patch number (`db_version`).
`(BDB:ENV-CREATE `&KEY` :PASSWORD :ENCRYPT :HOST :CLIENT-TIMEOUT :SERVER-TIMEOUT)`
  Create an environment handle (`db_env_create`), possibly connecting to a remote host (`DB_ENV->set_rpc_server`) and possibly using encryption with password (`DB_ENV->set_encrypt`).
`(BDB:ENV-CLOSE dbe)`
  Close an environment (`DB_ENV->close`).
`(BDB:DBREMOVE dbe file database `&KEY` :TRANSACTION :AUTO-COMMIT)`
  Remove a database (`DB_ENV->dbremove`).
`(BDB:DBREMOVE dbe file database newname `&KEY` :TRANSACTION :AUTO-COMMIT)`
  Rename a database (`DB_ENV->dbrename`).
`(BDB:ENV-OPEN dbe `&KEY` :HOME :JOIN :INIT-CDB :INIT-LOCK :INIT-LOG :INIT-MPOOL :INIT-TXN :RECOVER :RECOVER-FATAL :USE-ENVIRON :USE-ENVIRON-ROOT :CREATE :LOCKDOWN :PRIVATE :SYSTEM-MEM :THREAD :MODE)`
  Open an environment (`DB_ENV->open`).
`(BDB:ENV-REMOVE dbe `&KEY` :HOME :FORCE :USE-ENVIRON :USE-ENVIRON-ROOT)`
  Destroy an environment (`DB_ENV->remove`).

##### 30.2.6.3.2. Environment Configuration

`(BDB:ENV-SET-OPTIONS dbe `&KEY` :DATA-DIR :TMP-DIR :AUTO-COMMIT :CDB-ALLDB :DIRECT-DB :DIRECT-LOG :NOLOCKING :NOMMAP :NOPANIC :OVERWRITE :PANIC-ENVIRONMENT :REGION-INIT :TXN-NOSYNC :TXN-WRITE-NOSYNC :YIELDCPU :VERB-CHKPOINT :VERB-DEADLOCK :VERB-RECOVERY :VERB-REPLICATION :VERB-WAITSFOR :VERBOSE)`
  Set some environment options using `DB_ENV->set_flags`, `DB_ENV->set_verbose`, `DB_ENV->set_tmp_dir` and `DB_ENV->set_data_dir`.

##### 30.2.6.3.3. Database Operations

`(BDB:DB-CREATE dbe `&KEY` :XA)`
  Create a database handle (`db_create`).
`(BDB:DB-CLOSE dbe `&KEY` :NOSYNC)`
  Close a database (`DB->close`).
`(BDB:DB-DEL dbe key `&KEY` :TRANSACTION :AUTO-COMMIT)`
  Delete items from a database (`DB->del`).
`(BDB:DB-FD db)`
  Return a file descriptor from a database (`DB->fd`).
`(BDB:DB-GET db key `&KEY` :CONSUME :CONSUME-WAIT :DIRTY-READ :RMW :TRANSACTION)`
  Get items from a database (`DB->get`).
`(BDB:DB-PUT db key val `&KEY` :APPEND :NODUPDATA :NOOVERWRITE :AUTO-COMMIT :TRANSACTION)`
  Store items into a database (`DB->put`).
`(BDB:DB-STAT db `&KEY` :FAST-STAT)`
  Return database statistics (`DB->get_byteswapped`, `DB->get_type`, `DB->stat`).
`(BDB:DB-OPEN db file `&KEY` :DATABASE :TYPE :MODE :CREATE :DIRTY-READ :EXCL :NOMMAP :RDONLY :THREAD :TRUNCATE :AUTO-COMMIT :TRANSACTION)`
  Open a database (`DB->open`).
`(BDB:DB-SYNC db)`
  Flush a database to stable storage (`DB->sync`).
`(BDB:DB-TRUNCATE db `&KEY` :TRANSACTION :AUTO-COMMIT)`
  Empty a database (`DB->truncate`).
`(BDB:DB-UPGRADE, db file `&KEY` :DUPSORT)`
  Upgrade a database (`DB->upgrade`).
`(BDB:DB-RENAME db file database newname)`
  Rename a database (`DB->rename`).
`(BDB:DB-REMOVE db file database)`
  Remove a database (`DB->remove`).

##### 30.2.6.3.4. Database Configuration

`()`

##### 30.2.6.3.5. Btree/Recno Configuration

`()`

##### 30.2.6.3.6. Hash/Queue Configuration

`()`

##### 30.2.6.3.7. Database Cursor Operations

`()`

##### 30.2.6.3.8. Lock Subsystem

`()`

##### 30.2.6.3.9. Log Subsystem

`()`

##### 30.2.6.3.10. Log Cursor Operations

`()`

##### 30.2.6.3.11. Log Sequence Numbers

`()`

##### 30.2.6.3.12. Memory Pool Subsystem

`()`

##### 30.2.6.3.13. Transaction Subsystem

`(BDB:TXN-BEGIN dbe `&KEY` :PARENT :DIRTY-READ :NOSYNC :NOWAIT :SYNC)`
  Begin a transaction (`DB_ENV->txn_begin`).
`(BDB:TXN-ABORT txn)`
  Abort a transaction (`DB_TXN->abort`).
`(BDB:TXN-COMMIT txn `&KEY` :NOSYNC :SYNC)`
  Commit a transaction (`DB_TXN->commit`).
`(BDB:TXN-DISCARD txn)`
  Discard a transaction (`DB_TXN->discard`).

##### 30.2.6.3.14. Replication

`()`

#### 30.2.6.4. CLISP “REGEXP” module

The “REGEXP” module implements the POSIX regular expressions by calling the standard C system facilities. The syntax of these regular expressions is described in many places, such as your local `regex.h` manual and Emacs info pages.

When this module is present, `*FEATURES*` contains the symbol `:REGEXP`.

API

`(`REGEXP:MATCH` `pattern` `string` `&KEY` (`:START` 0) `:END` `:EXTENDED` `:IGNORE-CASE` `:NEWLINE` `:NOSUB` `:NOTBOL` `:NOTEOL`)`

  This macro returns as first value a `REGEXP:MATCH` structure containing the indices of the start and end of the first match for the regular expression `pattern` in `string`; or `NIL` if there is no match. Additionally, a `REGEXP:MATCH` structure is returned for every matched `"\(...\)"` group in `pattern`, in the order that the open parentheses appear in `pattern`. If `start` is non-`NIL`, the search starts at that index in `string`. If `end` is non-`NIL`, only `(`SUBSEQ` `string` `start` `end`)` is considered.

  Example 30.1. `REGEXP:MATCH`

          (REGEXP:MATCH "quick" "The quick brown fox jumped quickly.")
           #S(REGEXP:MATCH :START 4 :END 9)
          (REGEXP:MATCH "quick" "The quick brown fox jumped quickly." :start 8)
           #S(REGEXP:MATCH :START 27 :END 32)
          (REGEXP:MATCH "quick" "The quick brown fox jumped quickly." :start 8 :end 30)
           NIL
          (REGEXP:MATCH "\\([a-z]*\\)[0-9]*\\(bar\\)" "foo12bar")
           #S(REGEXP:MATCH :START 0 :END 8) ;
           #S(REGEXP:MATCH :START 0 :END 3) ;
           #S(REGEXP:MATCH :START 5 :END 8)

`(`REGEXP:MATCH-START` `match`)`
`(`REGEXP:MATCH-END` `match`)`
  Return the start and end the `match`; `SETF`-able.
`(`REGEXP:MATCH-STRING` `string` `match`)`
  Extracts the substring of `string` corresponding to the given pair of start and end indices of `match`. The result is shared with `string`. If you want a freshly consed `STRING`, use `COPY-SEQ` or `(`COERCE` (`REGEXP:MATCH-STRING` ...) '`SIMPLE-STRING`)`.
`(`REGEXP:REGEXP-QUOTE` `string` `&OPTIONAL` `extended`)`

  This function returns a regular expression `STRING` that matches exactly `string` and nothing else. This allows you to request an exact string match when calling a function that wants a regular expression.

  Example 30.2. `REGEXP:REGEXP-QUOTE`

          (regexp-quote "^The cat$")
           "\\^The cat\\$"

  One use of `REGEXP:REGEXP-QUOTE` is to combine an exact string match with context described as a regular expression. When `extended` is non-`NIL`, also quote #\+ and #\?.

`(`REGEXP:REGEXP-COMPILE` `string` `&KEY` `:EXTENDED` `:IGNORE-CASE` `:NEWLINE` `:NOSUB`)`
  Compile the regular expression `string` into an object suitable for `REGEXP:REGEXP-EXEC`.
`(`REGEXP:REGEXP-EXEC` `pattern` `string` `&KEY` (`:START` 0) `:END` `:NOTBOL` `:NOTEOL`)`

  Execute the `pattern`, which must be a compiled regular expression returned by `REGEXP:REGEXP-COMPILE`, against the appropriate portion of the `string`.

  Negative `end` means `(`+` (`LENGTH` `string`) `end`)`

  Returns `REGEXP:MATCH` structures as multiple values (one for each subexpression which successfully matched and one for the whole pattern), unless `:BOOLEAN` was non-`NIL`, in which case return `T` as an indicator of success, but do not allocate anything.

`(`REGEXP:REGEXP-SPLIT` `pattern` `string` `&KEY` (`:START` 0) `:END` `:EXTENDED` `:IGNORE-CASE` `:NEWLINE` `:NOSUB` `:NOTBOL` `:NOTEOL`)`
  Return a list of substrings of `string` (all sharing the structure with `string`) separated by `pattern` (a regular expression `STRING` or a return value of `REGEXP:REGEXP-COMPILE`)
`(`REGEXP:WITH-LOOP-SPLIT` (`variable` `stream` `pattern` `&KEY` (`:START` 0) `:END` `:EXTENDED` `:IGNORE-CASE` `:NEWLINE` `:NOSUB` `:NOTBOL` `:NOTEOL`) `&BODY` `body`)`
  Read lines from `stream`, split them with `REGEXP:REGEXP-SPLIT` on `pattern`, and bind the resulting list to `variable`.
`:EXTENDED` `:IGNORE-CASE` `:NEWLINE` `:NOSUB`
  These options control compilation of a pattern. See `regex.h` for their meaning.
`:NOTBOL` `:NOTEOL`
  These options constrol execution of a pattern. See `regex.h` for their meaning.
`REGEXP:REGEXP-MATCHER`
  A valid value for `CUSTOM:*APROPOS-MATCHER*`. This will work only when your locale is `CHARSET:UTF-8` because CLISP uses `CHARSET:UTF-8` internally and POSIX constrains `regex.h` to use the current locale.

##### 30.2.6.4.1. Example

The following code computes the number of people who use a particular shell:

Example 30.3. shell-count.lisp

    #!/usr/local/bin/clisp -C
    (DEFPACKAGE "REGEXP-TEST" (:use "LISP" "REGEXP"))
    (IN-PACKAGE "REGEXP-TEST")
    (let ((h (make-hash-table :test #'equal :size 10)) (n 0))
      (with-open-file (f "/etc/passwd")
        (with-loop-split (s f ":")
          (incf (gethash (seventh s) h 0))))
      (with-hash-table-iterator (i h)
        (loop (multiple-value-bind (r k v) (i)
                (unless r (return))
                (format t "[~d] ~s~30t== ~5:d~%" (incf n) k v)))))

For comparison, the same can be done by the following Perl:

Example 30.4. shell-count.perl

    #!/usr/local/bin/perl -w

    use diagnostics;
    use strict;

    my $IN = $ARGV[0];
    open(INF,"< $IN") || die "$0: cannot read file [$IN]: $!\n;";
    my %hash;
    while (<INF>) {
      chop;
      my @all = split($ARGV[1]);
      my $shell = ($#all >= 6 ? $all[6] : "");
      if ($hash{$shell}) { $hash{$shell} ++; }
      else { $hash{$shell} = 1; }
    }
    my $ii = 0;
    for my $kk (keys(%hash)) {
      print "[",++$ii,"] \"",$kk,"\"  --  ",$hash{$kk},"\n";
    }
    close(INF);

#### 30.2.6.5. Perl Compatible Regular Expressions.

This is an interface to Perl Compatible Regular Expressions.

When this module is present, `*FEATURES*` contains the symbol `:PCRE`.

PCRE module API

`(PCRE:PCRE-VERSION)`
  Return version information as 3 values: descriptive `STRING` and 2 `FIXNUM`s: major and minor numbers.
`(PCRE:PCRE-CONFIG `type`)`
  Return some information about the PCRE build configuration (`type` is one of `:UTF8` `:NEWLINE` `:LINK-SIZE` `:POSIX-MALLOC-THRESHOLD` `:MATCH-LIMIT`).
`(PCRE:PCRE-COMPILE `string` `&KEY` :STUDY :IGNORE-CASE :MULTILINE :DOTALL :EXTENDED :ANCHORED :DOLLAR-ENDONLY :EXTRA :NOTBOL :NOTEOL :UNGREADY :NOTEMPTY :NO-AUTO-CAPTURE)`
  Compile a pattern, optionally study it.
`(PCRE:PATTERN-INFO `pattern` request)`
  Return some information about the `pattern`, such as `:OPTIONS` `:SIZE` `:CAPTURECOUNT` `:BACKREFMAX` `:FIRSTBYTE` `:FIRSTTABLE` `:LASTLITERAL` `:NAMEENTRYSIZE` `:NAMECOUNT` `:NAMETABLE` `:STUDYSIZE`.
`(PCRE:PCRE-NAME-TO-INDEX `pattern` `name`)`
  Convert the name of the sub-pattern to an index in the return vector.
`(PCRE:PCRE-EXEC `pattern` `string` `&KEY` :BOOLEAN :OFFSET :ANCHORED :NOTBOL :NOTEOL :NOTEMPTY)`
  Execute the compiled `pattern` against the `string` at the given `offset` with the given options. Returns `NIL` if no matches or a `VECTOR` of `LENGTH` `CAPTURECOUNT+1` of PCRE:MATCH structures, unless `:BOOLEAN` was non-`NIL`, in which case return `T` as an indicator of success, but do not allocate anything.
`(PCRE:MATCH-START `match`)`
`(PCRE:MATCH-END `match`)`
  Return the start and end of the `match`. `SETF`-able.
`(PCRE:MATCH-SUBSTRING `match` `string`)`
  Return the substring of `string` bounded by `match`.
`(PCRE:MATCH-STRINGS return-vector `string`)`
  Return all substrings for all matches found by `PCRE:PCRE-EXEC`.
`(PCRE:MATCH-STRING return-vector which `string` `&OPTIONAL` `pattern`)`
  Return the substring that matches the given sub-pattern. If `which` is a name of the sub-pattern (as opposed to its number), `pattern` must be supplied.
`(PCRE:PCRE-MATCHER `pattern`)`
  A valid value for `CUSTOM:*APROPOS-MATCHER*`.

#### 30.2.6.6. System Calls

The “POSIX” module makes some system calls available from lisp. Not all of these system calls are actually POSIX, so this package has a nickname “OS”.

When this module is present, `*FEATURES*` contains the symbol `:SYSCALLS`.

`(`POSIX:RESOLVE-HOST-IPADDR` `&OPTIONAL` `host`)`
  Returns the HOSTENT structure (name, list of aliases, list of IP addresses as dotted quads (for IPv4) or coloned octets (for IPv6), address type - IPv4 or IPv6). When `host` is omitted or `:DEFAULT`, return the data for the current host. When `host` is given and is `NIL`, all the host database is returned as a list (this would be the contents of the `/etc/hosts` file on a UNIX system or `${windir}/system32/etc/hosts` on a Win32 system). This is an interface to `gethostbyname`/`gethostbyaddr`.
`(`POSIX:FILE-STAT` `pathname` `&OPTIONAL` `link-p`)`

  Return the FILE-STAT structure. `pathname` can be a `STREAM`, a `PATHNAME`, a `STRING` or a `NUMBER` (on a UNIX system, meaning file descriptor). The first slot of the structure returned is the string or the number on which `stat`/`fstat`/`lstat` was called. The other slots are numbers, members of the struct stat:

  dev
    Device ID of device containing file.
  ino
    File serial number.
  mode
    Mode of file.
  nlink
    Number of hard links to the file.
  uid
    User ID of file.
  gid
    Group ID of file.
  rdev
    Device ID (if file is character or block special).
  size
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. For a shared memory object, the length in bytes. For a typed memory object, the length in bytes. For other file types, the use of this field is unspecified.
  atime
    Time of last access (as the number of seconds since 1900-01-01).
  mtime
    Time of last data modification (as the number of seconds since 1900-01-01).
  ctime
    Time of last status change (as the number of seconds since 1900-01-01).
  blksize
    A file system-specific preferred I/O block size for this object. In some file system types, this may vary from file to file.
  blocks
    Number of blocks allocated for this object.

  All slots are read-only.

  If the system does not support a particular field (e.g., Win32 prior to 2000 does not have hard links), `NIL` (or the default, like 1 for the number of hard links for old Win32) is returned.

  [UNIX systems only at this time, patches are welcome.]

`(`POSIX:STAT-VFS` `pathname`)`

  Return the STAT-VFS structure. `pathname` can be a `STREAM`, a `PATHNAME`, a `STRING` or a `NUMBER` (on a UNIX system, meaning file descriptor). The first slot of the structure returned is the string or the number on which `statvfs`/`fstatvfs` was called. The other slots are members of the struct statvfs:

  bsize
    File system block size.
  frsize
    Fundamental file system block size.
  blocks
    Total number of blocks on file system in units of `frsize`.
  bfree
    Total number of free blocks.
  bavail
    Number of free blocks available to non-privileged processes.
  files
    Total number of file serial numbers.
  ffree
    Total number of free file serial numbers.
  favail
    Number of file serial numbers available to non-privileged processes.
  fsid
    File system ID.
  flag
    List of platform-dependent values, such as `:READ-ONLY`.
  namemax
    Maximum filename length.

  All slots are read-only.

  [UNIX systems only at this time, patches are welcome.]

`(`OS:FILE-INFO` `pathname`)`

  Return the FILE-INFO structure. `pathname` should be a pathname designator. The 8 slots are attributes, ctime, atime, wtime, high and low sizes, name and short name.

  [Win32 systems only at this time, patches are welcome.]

`(`POSIX:USER-DATA` `&OPTIONAL` `user`)`

  Return the PASSWD structure (name, encoded password, UID, GID, full name, home directory, shell). When `user` is `NIL`, return all users. When `user` is `:DEFAULT` or not supplied, return the information about the current user. If the system does not support a particular field (e.g., Win32 does not have a concept of a shell), `NIL` (or the default, like `c:\command.com` for DOS) is returned.

  [UNIX systems only at this time, patches are welcome.]

`(`POSIX:UNAME`)`
  Return a structure describing the OS, derived from `uname`.
`(`POSIX:SYSCONF`)`
`(`POSIX:CONFSTR`)`
  Return a structure describing the system configuration, derived from `sysconf` and `confstr` respectively.
`(`POSIX:LIMITS`)`
  Return a structure describing the resource limits, derived from `getrlimit`.
`(`POSIX:USAGE`)`
  Return 2 structures describing the resource usage by the lisp process and its children, derived from `getrusage`.
`(`POSIX:ERF` `real`)`
`(`POSIX:ERFC` `real`)`
`(`POSIX:J0` `real`)`
`(`POSIX:J1` `real`)`
`(`POSIX:JN` `integer` `real`)`
`(`POSIX:Y0` `real`)`
`(`POSIX:Y1` `real`)`
`(`POSIX:YN` `integer` `real`)`
`(`POSIX:GAMMA` `real`)`
`(`POSIX:LGAMMA` `real`)`
  Compute the error functions, Bessel functions and Gamma. These functions are required by the POSIX standard and should be available in libm.so. Please note that these functions do not provide lisp-style error handling and precision, and do all the computations at the double float level.
`(`POSIX:STREAM-LOCK` `stream` `lock-p` `&KEY` (:BLOCK `T`) (:SHARED `NIL`) (:START 0) (:END `NIL`))`
  This is an interface to the `fcntl` system call. It sets or removes a file lock for the (portion of the) file associated with `stream`, depending on `lock-p`. When `block` is `NIL`, the call is non-blocking, and when the file is already locked, it `SIGNAL`s an `ERROR`. When `shared` is non-`NIL`, then lock can be shared between several callers. Several processes can set a `shared` (i.e., read) lock, but only one can set an exclusive (i.e., write, or non-`shared`) lock.
`(`POSIX:COPY-FILE` `source-path` `destination-path` `&KEY` :METHOD :PRESERVE :IF-EXISTS :IF-DOES-NOT-EXIST)`

  This is an interface to the `symlink` (when `method` is `:SYMLINK`), `link` (when it is `:HARDLINK`), and `rename` (when it is `:RENAME`) system calls, as well as, you guessed it, a generic file copy utility (when `method` is `:COPY`).

  Both `source-path` and `destination-path` may be wild.

`(`POSIX:DUPLICATE-HANDLE` `fd1` `&OPTIONAL` `fd2`)`
  This is an interface to the `dup/dup2` system calls on UNIX systems and to `DuplicateHandle` system call on Win32.
`(OS:SHORTCUT-INFO `pathname`)`
  Return information about a Win32 shortcut (`#P".lnk"`) file contents in a SHORTCUT-INFO structure.
`(OS:MAKE-SHORTCUT `pathname` `&KEY` :WORKING-DIRECTORY :ARGUMENTS :SHOW-COMMAND :ICON :DESCRIPTION :HOT-KEY :PATH)`
  Create (or modify the properties of an existing one) a Win32 shortcut (`#P".lnk"`) file.
`(OS:SYSTEM-INFO)`
  Return Win32 system information in a SYSTEM-INFO structure.
`(OS:VERSION)`
  Return Win32 version information in a VERSION structure.

#### 30.2.6.7. Oracle Interface

The Oracle module allows a CLISP program to act as client to an Oracle database server. The module includes full SQL support, transactions (including auto-commit), support for most Oracle data types (LONG, BLOB, CLOB, RAW, etc.), automatic conversion between Oracle and Common Lisp data types, database connection caching and retry, concurrent connections to multiple databases, proper handling of Oracle errors, and more.

The module can be used to build sophisticated Oracle database applications in Common Lisp.

When this module is present, `*FEATURES*` contains the symbol `:ORACLE`.

##### 30.2.6.7.1. Functions and Macros in package “ORACLE”

Access to Oracle is via these functions and macros in package “ORACLE”. When any Oracle function fails, the general Lisp function `ERROR` is called, with the condition string set to include the Oracle error number, the Oracle message text, and other context of the error (e.g., the text and parse location of a SQL query).

`(ORACLE:CONNECT `user` `password` `server` `&OPTIONAL` `schema` `auto-commit` `prefetch-buffer-bytes` `long-len` `truncate-ok`)`

  Connect to an Oracle database. All subsequent operations will affect this database until the next call to `CONNECT`. A single program can access different Oracle schemas concurrently by repeated calls to `CONNECT`. Database connections are cached and re-used: if you call `CONNECT` again with the same `user`, `schema`, and `server`, the previous Oracle connection will be re-used. `CONNECT` may not be called inside `WITH-TRANSACTION`. Returns: `T` if a cached connection was re-used, `NIL` if a new connection was created (and cached). The meaning of the arguments is as follows:

  Arguments for `CONNECT`

  `user`
    Oracle user ID
  `password`
    Password for user, or `NIL` if `user` has no password (!).
  `server`
    Oracle server ID (SID).
  `schema`
    Oracle default schema (default: `NIL`). If `NIL`, same as user. This allows you to log on with one user's id/password but see the database as if you were some other user.
  `auto-commit`
    Flag: whether to commit after every operation (default: `T`). Set this to `NIL` if you intend to do transactions and call `COMMIT` explicitly. However, `WITH-TRANSACTION` is probably easier.
  `prefetch-buffer-bytes`
    Number of bytes to cache from SQL SELECT fetches (default: 64 Kbytes) If you are very short of memory, or have a slow connection to Oracle, you can reduce this to 10k or so. Alternatively, if you have a fast connection to Oracle and regularly do large queries, you can increase throughput by increasing this value.
  `long-len`
    Number of bytes to fetch for "long" (LONG, [BC]LOB) types. Long data that exceeds this size will raise an error, or be truncated depending on the value of `truncate-ok` (below). Setting `long-len` to zero and `truncate-ok` to `NIL` will disable long fetching entirely. If `long-len` is `NIL` or negative, defaults to 500k bytes.
  `truncate-ok`
    Flag: if set, allow truncation of LONG columns to `long-len` bytes on fetch; otherwise, fetches of LONG columns exceeding `long-len` bytes will raise an error. Default: `NIL`.
`(ORACLE:DISCONNECT)`
  Disconnect from the database currently connected. No more calls can be made until `CONNECT` is called again. The connection is closed and removed from the connection cache. Does nothing if there is no connection. `DISCONNECT` may not be called inside `WITH-TRANSACTION`. Returns `NIL`.
`(ORACLE:RUN-SQL `sql` `&OPTIONAL` `params` `is-select`)`

  Execute a SQL statement. Must be `CONNECT`ed to a database. Returns the number of rows affected by the SQL operation, for non-SELECT statements, zero for SELECT statements. For destructive database operations (INSERT, UPDATE, DELETE), the results are committed to the database immediately if `auto-commit` when establishing the current connection; see `CONNECT`. The meaning of the arguments is as follows:

  Arguments for `RUN-SQL`

  `sql`
    Text of SQL statement, as a string. The `sql` statement may contain Oracle "named parameters," e.g. ":myparam" whose values will be substituted from the parameters given in `params`.
  `params`
    A mapping of the names of the bind-parameters in the query to their values. The set of named parameters in the query must match exactly the keys mapped by `params`. The mapping may be passed as either (1) a hash table whose keys are the named parameters or (2) a list of pairs, ((name value) (name value) ...). Parameter values passed from Lisp are converted to the appropriate Oracle data types (see `FETCH`).
  `is-select`
    Flag: whether the statement is a SELECT query. You usually do not need to set this as it is detected by default based on the SQL text. However, there are situations, such as when a SELECT query begins with comment, that you need to specify it explicitly.
`(ORACLE:DO-ROWS `vars` `&BODY` `body`)`

  Macro which loops over a SQL SELECT result, evaluating, for each row in the result, the forms in `body`, binding symbols given in `vars` to corresponding database columns in the SELECT result. The argument `vars` must be a non-empty list of symbols matching a subset of the columns of an active SELECT query. If a SELECT column is an Oracle expression such as `SUBSTR(mycol, 1, 10)`, it is recommended to use a column alias, e.g., `SELECT SUBSTR(mycol, 1, 10) AS myvar`, in which case the column alias will be used as the symbol bound to the column value.

  As `DO-ROWS` expands into a `DO*` loop, it may be terminated prematurely, before all rows are fetched, by using `RETURN` anywhere in `body`.

  It is allowed to call `CONNECT` in the `body` of the loop, but only to switch the connection to a database other than the one that was used to do the SELECT. This is useful for reading from one database while writing to another.

  In `vars`, instead of a single symbol, a pair (`bound-var` `"column-name"`) may be specified, which will cause values from the SELECTed column or alias , `column-name`, to be bound to Lisp variable, `bound-var`. This is for unusual cases where a Lisp variable cannot be created with the same name as the column (e.g., a column named "T"), or when it is inconvenient or impossible to alias the column with `SELECT ... AS`.

`(ORACLE:FETCH `&OPTIONAL` `result-type`)`

  Fetch a single row of data. Returns a row of values corresponding to the columns of an active SELECT statment. The row data is returned in one of three different forms, depending on the value of the symbol `result-type`:

  Return values for `FETCH`

  `ARRAY`
    Values will be returned in an `ARRAY` with the same number of columns as in the SELECT statement, in the same order. This is the default.
  `PAIRS`
    A list of pairs, `((column, value) ...)` is be returned. The number and order of pairs is the same as the columns in the SELECT statement.
  `HASH`
    A `HASH-TABLE` whose keys are the column names and whose values are the column values in the row. The SELECT columns must be unique and be valid Lisp symbols to use this option. If you are SELECTing an expression, you probably want to use a column alias: `SELECT <expr> AS some_alias ...`

  The following data type conversions are done between Oracle datatypes and Common Lisp data types:

  Oracle type | Converts to/from Common Lisp type
  --- | ---
  Numeric (NUMBER, INTEGER, FLOAT) | The appropriate Common Lisp numeric type (`FIXNUM`, `BIGNUM`, `FLOAT`)
  String (CHAR, VARCHAR, VARCHAR2) | A Common Lisp `STRING`. Note that CHAR will be padded out to its full, fixed length as defined in Oracle; VARCHAR will be a string of variable length. Also note that Oracle has no "zero-length string" value - it returns the SQL special value `NULL` which is converted to `NIL` (see below).
  DATE | A string of the form "YYYY-MM-DD HH:MM:SS" where HH is 24-hour form. If you want dates formatted differently, convert them to strings in Oracle using `SELECT TO_CHAR(mydate, '`template`') AS mydate`; the result will then be returned as a string, formatted as per `template`.
  RAW, LONG RAW | A hexadecimal string, with two hex digits for each byte of Oracle data. Note that this means the Lisp string will be twice the size, in bytes, as the Oracle data.
  "Large" types (LONG, BLOB, CLOB) | A Lisp string of (arbitrary, possibly binary) data. Note that truncation may occur; see the `CONNECT` parameters `long-len` and `truncate-ok`.
  `NULL` | The Common Lisp value `NIL`

`(ORACLE:FETCH-ALL `&OPTIONAL` `max-rows` `result-type` `item-type`)`

  Fetch some or all the rows from a query and return result as a sequence of sequences. Arguments are all optional: `max-rows` limits the result to that numbers of rows; `result-type` is the type of sequence of the rows, either '`ARRAY` (the default) or '`LIST`; `item-type` is the type of sequence of the column values for each row, either '`ARRAY` (the default) or '`LIST`. Each row fetched always contains the full set of column values SELECTed.

  `FETCH-ALL` is often useful in conjunction with `MAP` or `REDUCE` to iterate over an entire SELECT result to construct a single Lisp value.

`(ORACLE:PEEK `&OPTIONAL` `result-type`)`
  Peek at next row of data (without fetching it). Returns a row ala `FETCH`, except does not advance to the next row. Repeated calls to `PEEK` will thus return the same row of data. Returns `NIL` if at EOF. If data is available, returns row data just as `FETCH` (see `FETCH` for data format and conversions done). Optional argument `result-type` is the type of sequence of the column values for the returned row, either '`ARRAY` (the default) or '`LIST`. `PEEK` is a useful look-ahead for database reporting functions that may need to "break" on changes in data to print headers, summaries, etc.
`(ORACLE:COLUMNS)`

  Returns information on the columns of a SELECT result, in the form of an array of SQLCOL structures, one for each result column in the most recent SELECT statement. It is not necessary to have called `FETCH` before requesting column information on the query, however the query must have been compiled and executed with `RUN-SQL`. Each SQLCOL structure has these slots:

  Slots of `SQLCOL`

  NAME
    The Oracle column name or the expression selected. If the query used a column alias, `SELECT `expr` AS `alias``, then `alias` will be returned as the column name.
  TYPE
    Oracle data type (VARCHAR, NUMBER, DATE, ...)
  SIZE
    Oracle data length (useful mostly for character types)
  SCALE
    For numeric types, number of digits to right of decimal
  PRECISION
    For numeric types, total number of significant digits
  NULL_OK
    `T` if `NULL`s allowed, `NIL` if `NULL`s are not allowed.

  To access the values of the SQLCOL structures, use the standard accessor functions, e.g., `(ORACLE:SQLCOL-NAME (elt (ORACLE:COLUMNS) 0))`

`(ORACLE:EOF)`
  Returns EOF status. A SELECT query cursor is considered at EOF if the next FETCH would return no data. Must be connected to a database, and have an active SELECT statement.
`(ORACLE:INSERT-ROW `table` `values`)`
  Inserts a single row into `table`. Second argument `values` is a map of column names to values: either a hash table whose keys are the column names, or a list of (name, value) pairs. Columns missing from the map will be given the default Oracle value, or `NULL`. Returns the number of rows inserted (i.e., always 1).
`(ORACLE:UPDATE-ROW `table` `condition` `vals` `&OPTIONAL` `params`)`
  Updates rows in `table`. Second argument `condition` is a string expression for a WHERE clause (without the "WHERE") which determines which rows are updated. Third argument `vals` is a map of columns to be updated to their new values: a hash table whose keys are column names, or list of (name, value) pairs. Optional `params` specifies values for named parameters that may occur in `condition`, e.g., when the condition is a match on a primary key, e.g.: `"pk_column = :pk_val"`. Returns the number of rows updated.
`(ORACLE:ROW-COUNT)`
  For SELECT statements, returns the number of rows `FETCH`ed (not `PEEK`ed) so far. For other statements (e.g., INSERT, UPDATE, DELETE), returns the number of rows affected by the last operation (e.g., inserted, updated, deleted). Must be connected to a database and have an active SQL statement.
`(ORACLE:WITH-TRANSACTION `&BODY` `body`)`
  Evaluates the forms in `body` atomically as a database transaction, ensuring that either all the database operations done in `body` complete successfully, or none of them do. If pending (un-committed) changes exist when this macro is entered, they are rolled back (undone), so that the database is affected only by the subsequent updates inside `body`. Nesting of `WITH-TRANSACTION` blocks is not allowed and will raise an error. There is no effect on the status of `auto-commit` given in `CONNECT`; it resumes its previous state when the macro exits. The value of the `WITH-TRANSACTION` expression is that of the last form in `body`.
`(ORACLE:COMMIT)`
  Commits (makes permanent) any pending changes to the database. The `auto-commit` parameter to `CONNECT` must not have been set to use this function, nor can it be called inside a `WITH-TRANSACTION` block. Always returns NIL.
`(ORACLE:ROLLBACK)`
  Rolls back (undoes and abandons) any pending changes to the database. The `auto-commit` parameter to `CONNECT` must not have been set to use this function, nor can it be called inside a `WITH-TRANSACTION` block. Always returns NIL.
`(ORACLE:AUTO-COMMIT)`
  Toggles the state of `auto-commit` initially given to `CONNECT` for the current connection. With `auto-commit` enabled, modifications to the database are committed (made permanent) after each destructive SQL operation made with calls to `RUN-SQL`, `INSERT-ROW`, `UPDATE_ROW`, etc. With `auto-commit` disabled, transactional integrity is under the programmer's control and is managed either by (1) explicitly calling `COMMIT` or `ROLLBACK` to commit or undo the pending operations, or (2) wrapping code blocks with database operations inside the `WITH-TRANSACTION` macro. `AUTO-COMMIT` returns the previous status of `auto-commit`. `AUTO-COMMIT` may not be called inside `WITH-TRANSACTION`.

##### 30.2.6.7.2. Oracle Example

Below is a simple example script which uses Oracle's demo database schema, `SCOTT`.

    (setf server "orcl") ; Change this to your server's SID
    (oracle:connect "scott" "tiger" server)

    (oracle:run-sql "SELECT deptno, dname, loc FROM dept ORDER BY DNAME")
    (oracle:do-rows (deptno dname loc)
      (format t "Dept. no is '~A', " deptno)
      (format t "Dept. name is '~A', " dname)
      (format t "Dept. loc is '~A'~%" loc))

    (oracle:update-row "dept" "dname = :acctval" '(("dname" "NEWACCT")) '(("acctval" "ACCOUNTING")))

    (oracle:run-sql "SELECT deptno, dname, loc FROM dept ORDER BY DNAME")
    (oracle:do-rows (deptno dname loc)
      (format t "Dept. no is '~A', " deptno)
      (format t "Dept. name is '~A', " dname)
      (format t "Dept. loc is '~A'~%" loc))

    (oracle:update-row "dept" "dname = :acctval" '(("dname" "ACCOUNTING")) '(("acctval" "NEWACCT")))

##### 30.2.6.7.3. Oracle Configuration

Obviously, a working Oracle environment is required. It is recommended that you first be able to log on and use the Oracle SQL*Plus application to test your environment before attempting Oracle access via the CLISP module. At a minimum you will need to set environment variables `ORACLE_HOME` to the Oracle base directory and `LD_LIBRARY_PATH` to include `$`ORACLE_HOME`/lib` and possibly other directories.

##### 30.2.6.7.4. Building the Oracle Interface

The module uses the Oracle Call Interface (OCI) C library. To build the module you will need the Oracle OCI headers and link libraries; as a quick check, make sure you have the file `oci.h` somewhere under `ORACLE_HOME`, probably in `$`ORACLE_HOME`/rdbms/demo/oci.h`.

To build the module into CLISP, specify ./configure ... --with-module=oracle ... at build time. Thereafter, to load the CLISP linking set which contains the module, you need to run CLISP with the option `-K full`. You can test that you really have the Oracle-enabled CLISP by evaluating `(`DESCRIBE` 'oracle:connect)` It may be necessary to edit the Makefile in the `modules/oracle` subdirectory of the distribution prior to running ./configure.

#### 30.2.6.8. The FastCGI Interface

The FastCGI module speeds up CLISP CGI scripts launched by a Web server. Working with a FastCGI-enabled Web server such as Apache with mod_fastcgi, a CLISP program using the FastCGI protocol will run many times faster than a conventional CGI program. The performance improvements stem from the fact that the script's process remains running across HTTP requests, eliminating startup overhead and allowing for caching of data structures and other resources. This is the same approach used is in other languages (e.g., mod_perl for Perl).

When this module is present, `*FEATURES*` contains the symbol `:FASTCGI`.

##### 30.2.6.8.1. Overview of FastCGI

Traditional CGI programs work by doing input/output with the Web server via the following channels:

1. Examining environment variables; e.g., `HTTP_USER_AGENT` is the variable set by the Web server to name the browser used
2. Reading from standard input. E.g., to get input data in a "method=POST" request
3. Writing an HTTP response document (usually "Content-type: text/html") to the standard output, for eventual transmission back to the browser client
4. Writing error messages to the standard error, usually captured by the Web server and logged in its log files.

FastCGI involves replacing calls the standard routines to do the above with calls in the “FASTCGI” package. These calls will then work exactly as before when the program is invoked as a CGI, but will also work when invoked by a FastCGI-enabled Web server.

FastCGI programs persist across HTTP requests, and thus incur startup overhead costs only once. For Lisp Web programs, this overhead can be substantial: code must be compiled and loaded, files and databases must be opened, etc. Further, because the program stays running from HTTP request to HTTP request, it can cache information in memory such as database connections or large in-memory data structures.

##### 30.2.6.8.2. Functions in Package “FASTCGI”

Access to FastCGI is via these functions in package “FASTCGI”.

`(FASTCGI:IS-CGI)`
  Returns `T` if the CLISP program has been launched as a traditional CGI rather than in FastCGI. In traditional CGI, program I/O is via operating system environment variables and standard file streams. Under FastCGI, I/O is done directly with the Web server via the FastCGI protocol.
`(FASTCGI:ACCEPT)` `cgi-forms` `(FASTCGI:FINISH)`

  In FastCGI mode, the program loops, `ACCEPT`ing to begin the execution of an HTTP request, and `FINISH`ing to signal that the script is finished writing its response to the HTTP request. `ACCEPT` blocks until the next HTTP request comes in, returning `T` if there is a new request to handle, and `NIL` if no more HTTP requests will occur, usually because the Web server itself has terminated, in which case the FastCGI server loop should also exit.

  A typical FastCGI top-level server loop looks like:

          (do ()
      	((not (fastcgi:accept)))
      	(run-my-script)
              (fastcgi:finish))

`(FASTCGI:GETENV `varname`)`
  Use in place of `EXT:GETENV` to get the value of the environment variable named `varname`, which should be a string. Unlike `EXT:GETENV`, which accesses the actual host operating system environment, `FASTCGI:GETENV` obtains its environment via the Web server, over its FastCGI communications channel. For more information, see the FastCGI Web site. Returns `NIL` if `varname` is not defined in the operating system environment. See here for a list of useful variables. You must first have called `ACCEPT` and not yet have called `FINISH`.
`(FASTCGI:WRITE-STDOUT `string`)`
  Use in place of standard Lisp calls which print to standard output (i.e., as part of the HTTP response). You must first have called `ACCEPT` and not yet have called `FINISH`.
`(FASTCGI:WRITE-STDERR `string`)`
  Use in place of standard Lisp calls which print to standard error. Rather than being part of the HTTP response, data written to standard error are usually collected by the Web server in its error log. This is useful for diagnostic purposes.
`(FASTCGI:SLURP-STDIN)`
  Reads in the entirety of standard input and returns it as a string. This is usually done for HTTP requests with `METHOD="post"`, when the data are passed to the CGI script via standard input rather than via the environment variable `QUERY_STRING`. There is no way to read standard input in pieces, which could be a problem, say, for HTTP uploads of very large files.
`(FASTCGI:OUT `tree`)`
  Like `WRITE-STDOUT`, except that `tree` may be an arbitrarily nested list structure containing (at the leaves) numbers and strings. For example, `(FASTCGI:OUT '("foo" (" " 10 " " 20)))` will write the string `"foo 10 20"`. This function is useful when building strings in memory for display.

##### 30.2.6.8.3. FastCGI Example

Below is a simple example CGI script using FastCGI.

    #!/usr/local/bin/clisp -q -K full

    (defun newline () (format nil "~%"))
    (do ((count 1 (1+ count)))
    	((not (fastcgi:accept)) nil)

        (fastcgi:out "Content-type: text/plain" (newline) (newline))
        (fastcgi:out
         "I am running in mode: " (if (fastcgi:is-cgi) "CGI" "FastCGI") (newline)
         "This is execution no.: " count (newline)
         "The browser string is '" (fastcgi:getenv "HTTP_USER_AGENT") "'" (newline))

        (fastcgi:finish))

##### 30.2.6.8.4. Building and configuring the FastCGI Interface

It is necessary to download the FastCGI developers' kit, build it, and install it, before building CLISP with FastCGI support. You also need to upgrade your Web server to speak the FastCGI protocol. For Apache this means building in mod_fastcgi, either statically or dynamically, and then adding a line to your Apache config like:

        Addhandler fastcgi-script .fcgi

After that, you can convert `foo.cgi` by linking it to a script names `foo.fcgi`. Since a FastCGI script is also a valid CGI script, it can be run unmodified in either mode.

## 30.3. Extensions-2.3. The Foreign Function Call Facility

### Platform dependent: many UNIX, Win32 platforms only.

A foreign function description is written as a Lisp file, and when compiled it produces a `#P".c"` file which is then compiled by the C compiler and may be linked together with `lisp.a`.

All symbols relating to the foreign function interface are exported from the package “FFI”. To use them, `(`USE-PACKAGE` "FFI")`.

Special “FFI” forms may appear anywhere in the Lisp file.

### 30.3.1. Overview

These are the special “FFI” forms. We have taken a pragmatic approach: the only foreign languages we support for now are C and ANSI C.

special “FFI” forms; `name` is any Lisp `SYMBOL`; `c-name` is a `STRING`.

`(`FFI:DEF-C-TYPE` `name` `c-type`)`
  This form makes `name` a shortcut for `c-type`. Note that `c-type` may already refer to name. Forward declarations of types are not possible, however.
`(`FFI:DEF-C-VAR` `name` {`option`}*)`

  This form defines a `FFI:FOREIGN-VARIABLE`. `name` is the Lisp name, a regular Lisp `SYMBOL`.

  Options for `FFI:DEF-C-VAR`

  `(`:NAME` `c-name`)`
    specifies the name as seen from C, as a string. If not specified, it is derived from the print name of the Lisp name.
  `(`:TYPE` `c-type`)`
    specifies the variable's foreign type.
  `(`:READ-ONLY` `BOOLEAN`)`
    If this option is specified and non-`NIL`, it will be impossible to change the variable's value from within Lisp (using `SETQ` or similar).
  `(:ALLOC `ALLOCATION`)`
    This option can be either `:NONE` or `:MALLOC-FREE` and defaults to `:NONE`. If it is `:MALLOC-FREE`, any values of type FFI:C-STRING, FFI:C-PTR, FFI:C-PTR-NULL, FFI:C-ARRAY-PTR within the foreign value are assumed to be pointers to `malloc`-allocated storage, and when `SETQ` replaces an old value by a new one, the old storage is freed using `free` and the new storage allocated using `malloc`. If it is `:NONE`, `SETQ` assumes that the pointers point to good storage (not `NULL`!) and overwrites the old values by the new ones. This is dangerous (just think of overwriting a string with a longer one or storing some data in a `NULL` pointer...) and deprecated.
  `(`:LIBRARY` `STRING`)`
    Specifies the (optional) dynamic library which contains the variable.
`(`FFI:DEF-CALL-OUT` `name` {`option`}*)`

  This form defines a named call-out function (a foreign function called from Lisp: control flow temporarily leaves Lisp).

  Options for `FFI:DEF-CALL-OUT`

  `(`:NAME` `c-name`)`
    Any Lisp function call to `#'`name`` is redirected to call the C function `c-name`.
  `(`:ARGUMENTS` {(`argument` `c-type` [`PARAM-MODE` [`ALLOCATION`]])}*)`
  `(`:RETURN-TYPE` `c-type` [`ALLOCATION`])`
    Argument list and return value, see Section 30.3.7, “Argument and result passing conventions” and Section 30.3.8, “Parameter Mode”.
  `(`:LANGUAGE` `language`)`
    See Section 30.3.3, “The choice of the C flavor.”.
  `(:BUILT-IN `BOOLEAN`)`
    When the function is a C built-in, the full prototype will be output (unless suppressed by `FFI:*OUTPUT-C-FUNCTIONS*`).
  `(`:LIBRARY` `STRING`)`
    Specifies the (optional) dynamic library which contains the variable.
`(`FFI:DEF-CALL-IN` `name` {`option`}*)`

  This form defines a named call-in function (i.e., a Lisp function called from the foreign language: control flow temporary enters Lisp)

  Options for `FFI:DEF-CALL-IN`

  `(`:NAME` `c-name`)`
    Any C function call to the C function `c-name` is redirected to call the Common Lisp function `#'`name``.
  `(`:ARGUMENTS` {(`argument` `c-type` [`PARAM-MODE` [`ALLOCATION`]])}*)`
  `(`:RETURN-TYPE` `c-type` [`ALLOCATION`])`
    Argument list and return value, see Section 30.3.7, “Argument and result passing conventions” and Section 30.3.8, “Parameter Mode”.
  `(`:LANGUAGE` `language`)`
    See Section 30.3.3, “The choice of the C flavor.”.
`(`FFI:DEF-C-CALL-OUT` `name` {`option`}*)`
  This is equivalent to `FFI:DEF-CALL-OUT` with `:LANGUAGE` `:STDC`. deprecated.
`(`FFI:DEF-C-CALL-IN` `name` {`option`}*)`
  This is equivalent to `FFI:DEF-CALL-IN` with `:LANGUAGE` `:STDC`. deprecated.
`(`FFI:DEF-C-STRUCT` `name` (`symbol` `c-type`)*)`

  This form defines `name` to be both a `STRUCTURE-CLASS` and a foreign C type with the given slots. `name` is a `SYMBOL` (structure name) or a `LIST` whose `FIRST` element is the structure name and the `REST` is options. Two options are supported at this time:

  Options for `FFI:DEF-C-STRUCT`

  `:TYPEDEF`
    means that the name of this structure is a C type defined with `typedef` elsewhere.
  `:EXTERNAL`
    means that this structure is defined in a `#P".c"` file that you include with, e.g., `(`FFI:C-LINES` "#include <filename.h>")`.

  These options determine how the struct is written to the `#P".c"`.

`(`FFI:DEF-C-ENUM` `name` {`symbol` | (`symbol` [`value`])}*)`

  This form defines `symbol`s as constants, similarly to the C declaration enum { `symbol` [= `value`], ... };

  You can use `(`FFI:ENUM-FROM-VALUE` `name` `value`)` and `(`FFI:ENUM-TO-VALUE` `name` `symbol`)` to convert between the numeric and symbolic representations (of course, the latter function boils down to `SYMBOL-VALUE` plus a check that the `symbol` is indeed a constant defined in the `FFI:DEF-C-ENUM` `name`).

`(`FFI:C-LINES` `format-string` {`argument`}*)`
  This form outputs the string `(`FORMAT` `NIL` `format-string` {`argument`}*)` to the C output file. This is a rarely needed low-level facility.
`(`FFI:ELEMENT` `c-place` `index1` ... `indexn`)`
  Array element: If `c-place` is of foreign type `(FFI:C-ARRAY `c-type` (`dim1` ... `dimn`))` and 0 ≤ `index1` < `dim1`, ..., 0 ≤ `indexn` < `dimn`, this will be the place corresponding to `(`AREF` `c-place` `index1` ... `indexn`)` or ``c-place`[`index1`]...[`indexn`]`. It is a place of type `c-type`. If `c-place` is of foreign type `(FFI:C-ARRAY-MAX `c-type` `dim`)` and 0 ≤ `index` < `dim`, this will be the place corresponding to `(`AREF` `c-place` `index`)` or ``c-place`[`index`]`. It is a place of type `c-type`.
`(`FFI:DEREF` `c-place`)`
  Dereference pointer: If `c-place` is of foreign type `(FFI:C-PTR `c-type`)` or `(FFI:C-PTR-NULL `c-type`)`, this will be the place the pointer points to. It is a place of type `c-type`. For `(FFI:C-PTR-NULL `c-type`)`, the `c-place` may not be `NULL`.
`(`FFI:SLOT` `c-place` `slot-name`)`
  Struct or union component: If `c-place` is of foreign type `(FFI:C-STRUCT `class` ... (`slot-name` `c-type`) ...)` or of type `(FFI:C-UNION ... (`slot-name` `c-type`) ...)`, this will be of type `c-type`.
`(`FFI:CAST` `c-place` `c-type`)`
  Type change: A place denoting the same memory locations as the original `c-place`, but of type `c-type`.
`(`FFI:OFFSET` `c-place` `offset` `c-type`)`
  Type change and displacement: return a place denoting a memory locations displaced from the original `c-place` by an `offset` counted in bytes, with type `c-type`. This can be used to resize an array, e.g. of `c-type` `(FFI:C-ARRAY uint16 `n`)` via `(`FFI:OFFSET` `c-place` 0 '(FFI:C-ARRAY uint16 `k`))`.
`(`FFI:C-VAR-ADDRESS` `c-place`)`
  Return the address of `c-place` as a Lisp object of type `FFI:FOREIGN-ADDRESS`. This is useful as an argument to foreign functions expecting a parameter of C type FFI:C-POINTER.
`(`FFI:C-VAR-OBJECT` `c-place`)`
  Return the `FFI:FOREIGN-VARIABLE` object underlying the `c-place`. This is also an acceptable argument type to a FFI:C-POINTER declaration.
`(`FFI:TYPEOF` `c-place`)`
  returns the `c-type` corresponding to the `c-place`.
`(`FFI:SIZEOF` `c-type`)`
`(`FFI:SIZEOF` `c-place`)`

  The first form returns the size and alignment of the C type `c-type`, measured in bytes.

  The second form returns the size and alignment of the C type of `c-place`, measured in bytes.

`(`FFI:BITSIZEOF` `c-type`)`
`(`FFI:BITSIZEOF` `c-place`)`

  The first form returns the size and alignment of the C type `c-type`, measured in bits.

  The second form returns the size and alignment of the C type of `c-place`, measured in bits.

`(`FFI:FOREIGN-ADDRESS-NULL` `foreign-entity`)`
  This predicate returns `T` if the `foreign-entity` refers to the `NULL` address (and thus `foreign-entity` should probably not be passed to most foreign functions).
`(`FFI:FOREIGN-ADDRESS-UNSIGNED` `foreign-entity`)`
`(`FFI:UNSIGNED-FOREIGN-ADDRESS` `number`)`

  `FFI:FOREIGN-ADDRESS-UNSIGNED` returns the `INTEGER` address embodied in the Lisp object of type `FFI:FOREIGN-ADDRESS`, `FFI:FOREIGN-POINTER`, `FFI:FOREIGN-VARIABLE` or `FFI:FOREIGN-FUNCTION`.

  `FFI:UNSIGNED-FOREIGN-ADDRESS` returns a `FFI:FOREIGN-ADDRESS` object pointing to the given `INTEGER` address.

`(`FFI:FOREIGN-ADDRESS` `foreign-entity`)`

  `FFI:FOREIGN-ADDRESS` is both a type name and a selector/constructor function. It is the Lisp object type corresponding to a FFI:C-POINTER external type declaration, e.g. a call-out function with `(`:RETURN-TYPE` FFI:C-POINTER)` yields a Lisp object of type `FFI:FOREIGN-ADDRESS`.

  The function extracts the object of type `FFI:FOREIGN-ADDRESS` living within any `FFI:FOREIGN-VARIABLE` or `FFI:FOREIGN-FUNCTION` object. If the `foreign-entity` already is a `FFI:FOREIGN-ADDRESS`, it returns it. If it is a `FFI:FOREIGN-POINTER` (e.g. a base foreign library address), it encapsulates it into a `FFI:FOREIGN-ADDRESS` object, as suitable for use with a FFI:C-POINTER external type declaration. It does not construct addresses out of `NUMBER`s, `FFI:UNSIGNED-FOREIGN-ADDRESS` must be used for that purpose.

`(`FFI:VALIDP` `foreign-entity`)`
`(`SETF` (`FFI:VALIDP` `foreign-entity`) `value`)`

  This predicate returns `NIL` if the `foreign-entity` (e.g. the Lisp equivalent of a FFI:C-POINTER) refers to a pointer which is invalid because it comes from a previous Lisp session. It returns `T` if `foreign-entity` can be used within the current Lisp process (thus it returns `T` for all non-foreign arguments).

  You can invalidate a foreign object using `(`SETF` `FFI:VALIDP`)`. You cannot resurrect a zombie, nor can you kill a non-foreign object.

`(`FFI:FOREIGN-POINTER` `foreign-entity`)`
`(`SETF` (`FFI:FOREIGN-POINTER` `foreign-entity`) `foreign-pointer`)`

  `FFI:FOREIGN-POINTER` returns the `FFI:FOREIGN-POINTER` associated with the Lisp object of type `FFI:FOREIGN-ADDRESS`, `FFI:FOREIGN-POINTER`, `FFI:FOREIGN-VARIABLE` or `FFI:FOREIGN-FUNCTION`.

  `(`SETF` `FFI:FOREIGN-POINTER`)` changes the `FFI:FOREIGN-POINTER` associated with the Lisp object of type `FFI:FOREIGN-ADDRESS`, `FFI:FOREIGN-VARIABLE` or `FFI:FOREIGN-FUNCTION` to that of the other entity. When `foreign-pointer` is `:COPY`, a fresh `FFI:FOREIGN-POINTER` is allocated. `foreign-entity` still points to the same object. This is particularly useful with `(`SETF` `FFI:VALIDP`)`.

`(`FFI:WITH-FOREIGN-OBJECT` (`variable` `c-type` [`initarg`]) `body`)`
`(`FFI:WITH-C-VAR` (`variable` `c-type` [`initarg`]) `body`)`

  These forms allocate space on the C execution stack, bind respectively a `FFI:FOREIGN-VARIABLE` object or a local `SYMBOL-MACRO` to `variable` and execute `body`.

  When `initarg` is not supplied, they allocate space only for `(`FFI:SIZEOF` `c-type`)` bytes. This space is filled with zeroes. E.g., using a `c-type` of FFI:C-STRING or even `(FFI:C-PTR (FFI:C-ARRAY uint8 32))` (!) both allocate place for a single pointer, initialized to `NULL`.

  When `initarg` is supplied, they allocate space for an arbitrarily complex set of structures rooted in `c-type`. Therefore, FFI:C-ARRAY-MAX, `#()` and `""` are your friends for creating a pointer to the empty arrays:

      (with-c-var (v '(c-ptr (c-array-max uint8 32)) #())
        (setf (element (deref v) 0) 127) v)

  `c-type` is evaluated, making creation of variable sized buffers easy:

      (with-c-var (fv `(c-array uint8 ,(length my-vector)) my-vector)
        (print fv))

`(`FFI:WITH-FOREIGN-STRING` (`foreign-address` `char-count` `byte-count` `string` `&KEY` `encoding` `null-terminated-p` `start` `end`) `&BODY` `body`)`

  This forms converts a Lisp `string` according to the `encoding`, allocating space on the C execution stack. `encoding` can be any `EXT:ENCODING`, e.g. `CHARSET:UTF-16` or `CHARSET:UTF-8`, circumventing the usual 1:1 limit imposed on `CUSTOM:*FOREIGN-ENCODING*`.

  `body` is then executed with the three variables `foreign-address`, `char-count` and `byte-count` respectively bound to an untyped `FFI:FOREIGN-ADDRESS` (as known from the FFI:C-POINTER foreign type specification) pointing to the stack location, the number of `CHARACTER`s of the Lisp `string` that were considered and the number of `(`UNSIGNED-BYTE` 8)` bytes that were allocated for it on the C stack.

  When `null-terminated-p` is true, which is the default, a variable number of zero bytes is appended, depending on the encoding, e.g. 2 for `CHARSET:UTF-8`, and accounted for in `byte-count`, and `char-count` is incremented by one.

  The `FFI:FOREIGN-ADDRESS` object bound to `foreign-address` is invalidated upon the exit from the form.

  A stupid example (a quite costly interface to `mblen`):

      (with-foreign-string (fv elems bytes string
                            :encoding charset:jis... :null-terminated-p nil
                            :end 5)
       (declare (ignore fv elems))
       (format t "This string would take ~D bytes." bytes))

`(`FFI:PARSE-C-TYPE` `c-type`)`
`(`FFI:DEPARSE-C-TYPE` `c-type-internal`)`
  Convert between the external (`LIST`) and internal (`VECTOR`) C type representations (used by `DESCRIBE`).
`(`FFI:ALLOCATE-SHALLOW` `c-type` `&KEY` `:COUNT` `:READ-ONLY`)`
`(`FFI:ALLOCATE-DEEP` `c-type` `contents` `&KEY` `:COUNT` `:READ-ONLY`)`
`(`FFI:FOREIGN-FREE` `foreign-entity` `&KEY` :FULL)`
`(`FFI:FOREIGN-ALLOCATE` `c-type-internal` `&KEY` :INITIAL-CONTENTS `:COUNT` `:READ-ONLY`)`

  Macro `FFI:ALLOCATE-SHALLOW` allocates `(`FFI:SIZEOF` `c-type`)` bytes on the C heap and zeroes them out (like `calloc`). When `:COUNT` is supplied, `c-type` is substituted with `(FFI:C-ARRAY `c-type` `count`)`, except when `c-type` is `CHARACTER`, in which case `(FFI:C-ARRAY-MAX `CHARACTER` `count`)` is used instead. When `:READ-ONLY` is supplied, the Lisp side is prevented from modifying the memory contents. This can be used as an indication that some foreign side is going to fill this memory (e.g. via `read`).

  Returns a `FFI:FOREIGN-VARIABLE` object of the actual `c-type`, whose address part points to the newly allocated memory.

  `FFI:ALLOCATE-DEEP` will call C `malloc` as many times as necessary to build a structure on the C heap of the given `c-type`, initialized from the given `contents`.

  E.g., `(`FFI:ALLOCATE-DEEP` 'FFI:C-STRING "ABCDE")` performs 2 allocations: one for a C pointer to a string, another for the contents of that string. This would be useful in conjunction with a char** C type declaration. `(`FFI:ALLOCATE-SHALLOW` 'FFI:C-STRING)` allocates room for a single pointer (probably 4 bytes).

  `(`FFI:ALLOCATE-DEEP` '`CHARACTER` "ABCDEF" :count 10)` allocates and initializes room for the type `(FFI:C-ARRAY-MAX `CHARACTER` 10)`, corresponding to char* or, more specifically, char[10] in C.

  Function `FFI:FOREIGN-FREE` deallocates memory at the address held by the given `foreign-entity`. If `:FULL` is supplied and the argument is of type `FFI:FOREIGN-VARIABLE`, recursively frees the whole complex stucture pointed to by this variable.

  If given a `FFI:FOREIGN-FUNCTION` object that corresponds to a CLISP callback, deallocates it. Callbacks are automatically created each time you pass a Lisp function via the “FFI”.

  Use `(`SETF` `FFI:VALIDP`)` to disable further references to this address from Lisp. This is currently not done automatically. If the given pointer is already invalid, `FFI:FOREIGN-FREE` (currently) signals an `ERROR`. This may change to make it easier to integrate with `EXT:FINALIZE`.

  Function `FFI:FOREIGN-ALLOCATE` is a lower-level interface as it requires an internal C type descriptor as returned by `FFI:PARSE-C-TYPE`.

`(`FFI:WITH-C-PLACE` (`variable` `foreign-entity`) `body`)`

  Create a place out of the given `FFI:FOREIGN-VARIABLE` object so operations on places (e.g. `FFI:CAST`, `FFI:DEREF`, `FFI:SLOT` etc.) can be used within `body`. `FFI:WITH-C-VAR` appears as a composition of `FFI:WITH-FOREIGN-OBJECT` and `FFI:WITH-C-PLACE`.

  Such a place can be used to access memory referenced by a `foreign-entity` object:

      (setq foo (allocate-deep '(c-array uint8 3) rgb))
      (with-c-place (place foo) (element place 0))

`FFI:*OUTPUT-C-FUNCTIONS*`
`FFI:*OUTPUT-C-VARIABLES*`
  CLISP will write the extern declarations for foreign functions (defined with `FFI:DEF-CALL-OUT`) and foreign variables (defined with `FFI:DEF-C-VAR`) into the output `#P".c"` (when the Lisp file is compiled with `COMPILE-FILE`) unless these variables are `NIL`. They are `NIL` by default, so the extern declarations are not written; you are encouraged to use `FFI:C-LINES` to include the appropriate C headers. Set these variables to non-`NIL` if the headers are not available or not usable.

### 30.3.2. (Foreign) C types

Foreign C types are used in the “FFI”. They are not regular Common Lisp types or CLOS classes.

A `c-type` is either a predefined C type or the name of a type defined by `FFI:DEF-C-TYPE`.

the predefined C types (`c-type`)

`simple-c-type`

  the simple C types

  Lisp name | Lisp equivalent | C equivalent | ILU equivalent | Comment
  --- | --- | --- | --- | ---
  `NIL` | `NIL` | void |  | as a result type only
  `BOOLEAN` | `BOOLEAN` | int | BOOLEAN |
  `CHARACTER` | `CHARACTER` | char | SHORT CHARACTER |
  char | `INTEGER` | signed char |  |
  uchar | `INTEGER` | unsigned char |  |
  short | `INTEGER` | short |  |
  ushort | `INTEGER` | unsigned short |  |
  int | `INTEGER` | int |  |
  uint | `INTEGER` | unsigned int |  |
  long | `INTEGER` | long |  |
  ulong | `INTEGER` | unsigned long |  |
  uint8 | `(`UNSIGNED-BYTE` 8)` | uint8 | BYTE |
  sint8 | `(`SIGNED-BYTE` 8)` | sint8 |  |
  uint16 | `(`UNSIGNED-BYTE` 16)` | uint16 | SHORT CARDINAL |
  sint16 | `(`SIGNED-BYTE` 16)` | sint16 | SHORT INTEGER |
  uint32 | `(`UNSIGNED-BYTE` 32)` | uint32 | CARDINAL |
  sint32 | `(`SIGNED-BYTE` 32)` | sint32 | INTEGER |
  uint64 | `(`UNSIGNED-BYTE` 64)` | uint64 | LONG CARDINAL | does not work on all platforms
  sint64 | `(`SIGNED-BYTE` 64)` | sint64 | LONG INTEGER | does not work on all platforms
  `SINGLE-FLOAT` | `SINGLE-FLOAT` | float |  |
  `DOUBLE-FLOAT` | `DOUBLE-FLOAT` | double |  |

FFI:C-POINTER
  This type corresponds to what C calls void*, an opaque pointer. When used as an argument, `NIL` is accepted as a FFI:C-POINTER and treated as `NULL`; when a function wants to return a `NULL` FFI:C-POINTER, it actually returns `NIL`.
FFI:C-STRING
  This type corresponds to what C calls char*, a zero-terminated string. Its Lisp equivalent is a string, without the trailing zero character.
`(FFI:C-STRUCT `class` (`ident1` `c-type1`) ... (`identn` `c-typen`))`

  This type is equivalent to what C calls struct { `c-type1` `ident1`; ...; `c-typen` `identn`; }. Its Lisp equivalent is: if `class` is `VECTOR`, a `SIMPLE-VECTOR`; if `class` is `LIST`, a proper list; if `class` is a symbol naming a structure or CLOS class, an instance of this class, with slots of names `ident1`, ..., `identn`.

  `class` may also be a `CONS` of a `SYMBOL` (as above) and a `LIST` of `FFI:DEF-C-STRUCT` options.

`(FFI:C-UNION (`ident1` `c-type1`) ... (`identn` `c-typen`))`
  This type is equivalent to what C calls union { `c-type1` `ident1`; ...; `c-typen` `identn`; }. Conversion to and from Lisp assumes that a value is to be viewed as being of `c-type1`.
`(FFI:C-ARRAY `c-type` `dim1`)`
`(FFI:C-ARRAY `c-type` (`dim1` ... `dimn`))`
  This type is equivalent to what C calls `c-type` [`dim1`] ... [`dimn`]. Note that when an array is passed as an argument to a function in C, it is actually passed as a pointer; you therefore have to write `(FFI:C-PTR (FFI:C-ARRAY ...))` for this argument's type.
`(FFI:C-ARRAY-MAX `c-type` `maxdimension`)`
  This type is equivalent to what C calls `c-type` [`maxdimension`], an array containing up to `maxdimension` elements. The array is zero-terminated if it contains less than `maxdimension` elements. Conversion from Lisp of an array with more than `maxdimension` elements silently ignores the superfluous elements.
`(FFI:C-FUNCTION (`:ARGUMENTS` {(`argument` `a-c-type` [`PARAM-MODE` [`ALLOCATION`]])}*) (`:RETURN-TYPE` `r-c-type` [`ALLOCATION`]) (`:LANGUAGE` `language`))`
  This type designates a C function that can be called according to the given prototype `(`r-c-type` (*) (`a-c-type1`, ...))`. Conversion between C functions and Lisp functions is transparent, and `NULL`/`NIL` is recognized and accepted.
`(FFI:C-PTR `c-type`)`
  This type is equivalent to what C calls `c-type` *: a pointer to a single item of the given `c-type`.
`(FFI:C-PTR-NULL `c-type`)`
  This type is also equivalent to what C calls `c-type` *: a pointer to a single item of the given `c-type`, with the exception that C `NULL` corresponds to Lisp `NIL`.
`(FFI:C-ARRAY-PTR `c-type`)`
  This type is equivalent to what C calls `c-type` (*)[]: a pointer to a zero-terminated array of items of the given `c-type`.

`CUSTOM:*FOREIGN-ENCODING*` governs conversion for any `c-type` involving FFI:C-STRING or `CHARACTER` (but not char).

### 30.3.3. The choice of the C flavor.

FFI:C-FUNCTION, `FFI:DEF-CALL-IN`, `FFI:DEF-CALL-OUT` take `:LANGUAGE` argument. The `language` is either `:C` (denotes K&R C) or `:STDC` (denotes ANSI C) or `:STDC-STDCALL` (denotes ANSI C with the stdcall calling convention). It specifies whether the C function (caller or callee) has been compiled by a K&R C compiler or by an ANSI C compiler, and possibly the calling convention.

The default language is set using the macro `FFI:DEFAULT-FOREIGN-LANGUAGE`. If this macro has not been called in the current compilation unit (usually a file), a warning is issued and `:STDC` is used for the rest of the unit.

### 30.3.4. Foreign variables

Foreign variables are variables whose storage is allocated in the foreign language module. They can nevertheless be evaluated and modified through `SETQ`, just as normal variables can, except that the range of allowed values is limited according to the variable's foreign type. Note that for a foreign variable `x` the form `(`EQL` `x` `x`)` is not necessarily true, since every time `x` is evaluated its foreign value is converted to a fresh Lisp value. Foreign variables are defined using `FFI:DEF-C-VAR`.

### 30.3.5. Operations on foreign places

A `FFI:FOREIGN-VARIABLE` `name` defined by `FFI:DEF-C-VAR`, `FFI:WITH-C-VAR` or `FFI:WITH-C-PLACE` defines a place, i.e., a form which can also be used as argument to `SETF`. (An "lvalue" in C terminology.) The following operations are available on foreign places: `FFI:ELEMENT`, `FFI:DEREF`, `FFI:SLOT`, `FFI:CAST`, `FFI:OFFSET`, `FFI:C-VAR-ADDRESS`, `FFI:C-VAR-OBJECT`, `FFI:TYPEOF`, `FFI:SIZEOF`, `FFI:BITSIZEOF`.

### 30.3.6. Foreign functions

Foreign functions are functions which are defined in the foreign language. There are named foreign functions (imported via `FFI:DEF-CALL-OUT` or created via `FFI:DEF-CALL-IN`) and anonymous foreign functions; they arise through conversion of function pointers.

A "call-out" function is a foreign function called from Lisp: control flow temporarily leaves Lisp. A "call-in" function is a Lisp function called from the foreign language: control flow temporary enters Lisp.

The following forms define foreign functions: `FFI:DEF-CALL-IN`, `FFI:DEF-CALL-OUT`, `FFI:DEF-C-CALL-IN`, `FFI:DEF-C-CALL-OUT`.

### 30.3.7. Argument and result passing conventions

When passed to and from functions, allocation of arguments and results is handled as follows:

Values of `SIMPLE-C-TYPE`, FFI:C-POINTER are passed on the stack, with dynamic extent. The `ALLOCATION` is effectively ignored.

Values of type FFI:C-STRING, FFI:C-PTR, FFI:C-PTR-NULL, FFI:C-ARRAY-PTR need storage. The `ALLOCATION` specifies the allocation policy:

`:NONE`
  no storage is allocated.
`:ALLOCA`
  allocation of storage on the stack, which has dynamic extent.
`:MALLOC-FREE`
  storage will be allocated via `malloc` and freed via `free`.

If no `ALLOCATION` is specified, the default `ALLOCATION` is `:NONE` for most types, but `:ALLOCA` for FFI:C-STRING and FFI:C-PTR and FFI:C-PTR-NULL and FFI:C-ARRAY-PTR and for `:OUT` arguments. [Subject to change!] The `:MALLOC-FREE` policy provides the ability to pass arbitrarily nested structs containing pointers pointing to structs ... within a single conversion.

For call-out functions:
  For arguments passed from Lisp to C:
    If `ALLOCATION` is `:MALLOC-FREE`:
      Lisp allocates the storage using `malloc` and never deallocates it. The C function is supposed to call `free` when done with it.
    If `ALLOCATION` is `:ALLOCA`:
      Lisp allocates the storage on the stack, with dynamic extent. It is freed when the C function returns.
    If `ALLOCATION` is `:NONE`:
      Lisp assumes that the pointer already points to a valid area of the proper size and puts the result value there. This is dangerous! and deprecated.
  For results passed from C to Lisp:
    If `ALLOCATION` is `:MALLOC-FREE`:
      Lisp calls `free` on it when done.
    If `ALLOCATION` is `:NONE`:
      Lisp does nothing.
For call-in functions:
  For arguments passed from C to Lisp:
    If `ALLOCATION` is `:MALLOC-FREE`:
      Lisp calls `free` on it when done.
    If `ALLOCATION` is `:ALLOCA` or `:NONE`:
      Lisp does nothing.
  For results passed from Lisp to C:
    If `ALLOCATION` is `:MALLOC-FREE`:
      Lisp allocates the storage using `malloc` and never deallocates it. The C function is supposed to call `free` when done with it.
    If `ALLOCATION` is `:NONE`:
      Lisp assumes that the pointer already points to a valid area of the proper size and puts the result value there. This is dangerous! and deprecated.

### Warning

Passing FFI:C-STRUCT, FFI:C-UNION, FFI:C-ARRAY, FFI:C-ARRAY-MAX values as arguments (not via pointers) is only possible to the extent the C compiler supports it. Most C compilers do it right, but some C compilers (such as gcc on hppa and Win32) have problems with this. The recommended workaround is to pass pointers; this is fully supported. See also this `<clisp-list@sf.net>` message.

### 30.3.8. Parameter Mode

A function parameter's `PARAM-MODE` may be

`:IN` (means: read-only):
  The caller passes information to the callee.
`:OUT` (means: write-only):
  The callee passes information back to the caller on return. When viewed as a Lisp function, there is no Lisp argument corresponding to this, instead it means an additional return value.
`:IN-OUT` (means: read-write):
  Information is passed from the caller to the callee and then back to the caller. When viewed as a Lisp function, the `:OUT` value is returned as an additional multiple value.

The default is `:IN`.

[Currently, only `:IN` is fully implemented. `:OUT` works only with `ALLOCATION` = `:ALLOCA`.]

### 30.3.9. Examples

Example 30.5. Simple declarations and access

The C declaration

    struct foo {
        int a;
        struct foo * b[100];
    };

corresponds to

    (def-c-struct foo
      (a int)
      (b (c-array (c-ptr foo) 100)))

The element access

    struct foo f;
    f.b[7].a

corresponds to

    (declare (type foo f))
    (foo-a (aref (foo-b f) 7)) or (slot-value (aref (slot-value f 'b) 7) 'a)

Example 30.6. external C variable and some accesses

    struct bar {
        short x, y;
        char a, b;
        int z;
        struct bar * n;
    };

    extern struct bar * my_struct;

    my_struct->x++;
    my_struct->a = 5;
    my_struct = my_struct->n;

corresponds to

    (def-c-struct bar
      (x short)
      (y short)
      (a char)
      (b char) ; or (b character) if it represents a character, not a number
      (z int)
      (n (c-ptr bar)))

    (def-c-var my_struct (:type (c-ptr bar)))

    (setq my_struct (let ((s my_struct)) (incf (slot-value s 'x)) s))
    or (incf (slot my_struct 'x))
    (setq my_struct (let ((s my_struct)) (setf (slot-value s 'a) 5) s))
    or (setf (slot my_struct 'a) 5)
    (setq my_struct (slot-value my_struct 'n))
    or (setq my_struct (deref (slot my_struct 'n)))

Example 30.7. Calling an external function

On ANSI C systems, `stdlib.h` contains the declarations:

    typedef struct {
      int quot;   /* Quotient */
      int rem;    /* Remainder */
    } div_t;
    extern div_t div (int numer, int denom);

This translates to

    (def-c-struct (div_t :typedef)
      (quot int)
      (rem int))
    (default-foreign-language :stdc)
    (def-call-out div (:arguments (numer int) (denom int))
      (:return-type div_t))

Sample call from within Lisp:

    (div 20 3)
    #S(DIV_T :QUOT 6 :REM 2)

Example 30.8. Another example for calling an external function

Suppose the following is defined in a file `cfun.c`:

    struct cfunr { int x; char *s; };
    struct cfunr * cfun (int i,char *s,struct cfunr * r,int a[10]) {
      int j;
      struct cfunr * r2;
      printf("i = %d\n", i);
      printf("s = %s\n", s);
      printf("r->x = %d\n", r->x);
      printf("r->s = %s\n", r->s);
      for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
      r2 = (struct cfunr *) malloc (sizeof (struct cfunr));
      r2->x = i+5;
      r2->s = "A C string";
      return r2;
    }

It is possible to call this function from Lisp using the file `callcfun.lisp` (do not call it `cfun.lisp` - `COMPILE-FILE` would overwrite `cfun.c`) whose contents is:

    (DEFPACKAGE "TEST-C-CALL" (:use "LISP" "FFI"))
    (IN-PACKAGE "TEST-C-CALL")
    (eval-when (compile) (setq FFI:*OUTPUT-C-FUNCTIONS* t))
    (def-c-struct cfunr (x int) (s c-string))
    (default-foreign-language :stdc)
    (def-call-out cfun
        (:arguments (i int)
                    (s c-string)
                    (r (c-ptr cfunr) :in :alloca)
                    (a (c-ptr (c-array int 10)) :in :alloca))
      (:return-type (c-ptr cfunr)))
    (defun call-cfun ()
      (cfun 5 "A Lisp string" (make-cfunr :x 10 :s "Another Lisp string")
            '#(0 1 2 3 4 5 6 7 8 9)))

Use the module facility:

    $ clisp-link create-module-set cfun callcfun.c
    $ cc -O -c cfun.c
    $ cd cfun
    $ ln -s ../cfun.o cfun.o
    Add cfun.o to NEW_LIBS and NEW_FILES in link.sh.
    $ cd ..
    $ base/lisp.run -M base/lispinit.mem -c callcfun.lisp
    $ clisp-link add-module-set cfun base base+cfun
    $ base+cfun/lisp.run -M base+cfun/lispinit.mem -i callcfun
    > (test-c-call::call-cfun)
    i = 5
    s = A Lisp string
    r->x = 10
    r->s = Another Lisp string
    a[0] = 0.
    a[1] = 1.
    a[2] = 2.
    a[3] = 3.
    a[4] = 4.
    a[5] = 5.
    a[6] = 6.
    a[7] = 7.
    a[8] = 8.
    a[9] = 9.
    #S(TEST-C-CALL::CFUNR :X 10 :S "A C string")
    >
    $ rm -r base+cfun

Note that there is a memory leak here: The return value `r2` of `cfun()` is `malloc`ed but never `free`d. Specifying

    (:return-type (c-ptr cfunr) :malloc-free)

is not an alternative because this would also `free(r2->x)` but `r2->x` is a pointer to static data.

Example 30.9. Calling Lisp from C

To sort an array of double-floats using the Lisp function `SORT` instead of the C library function `qsort`, one can use the following interface code `sort1.c`. The main problem is to pass a variable-sized array.

    extern void lispsort_begin (int);
    void* lispsort_function;
    void lispsort_double (int n, double * array) {
        double * sorted_array;
        int i;
        lispsort_begin(n); /* store #'sort2 in lispsort_function */
        sorted_array = ((double * (*) (double *)) lispsort_function) (array);
        for (i = 0; i < n; i++) array[i] = sorted_array[i];
        free(sorted_array);
    }

This is accompanied by `sort2.lisp`:

    (DEFPACKAGE "FFI-TEST" (:use "LISP" "FFI"))
    (IN-PACKAGE "FFI-TEST")
    (eval-when (compile) (setq FFI:*OUTPUT-C-FUNCTIONS* t))
    (def-call-in lispsort_begin (:arguments (n int))
      (:return-type nil)
      (:language :stdc))
    (def-c-var lispsort_function (:type c-pointer))
    (defun lispsort_begin (n)
      (setf (cast lispsort_function
                  `(c-function
                     (:arguments (v (c-ptr (c-array double-float ,n))))
                     (:return-type (c-ptr (c-array double-float ,n))
                                   :malloc-free)))
            #'sort2))
    (defun sort2 (v)
      (declare (type vector v))
      (sort v #'<))

To test this, use the following test file `sorttest.lisp`:

    (eval-when (compile) (setq FFI:*OUTPUT-C-FUNCTIONS* t))
    (def-call-out sort10
      (:name "lispsort_double")
      (:language :stdc)
      (:arguments (n int)
                  (array (c-ptr (c-array double-float 10)) :in-out)))

Now try

    $ clisp-link create-module-set sort sort2.c sorttest.c
    $ cc -O -c sort1.c
    $ cd sort
    $ ln -s ../sort1.o sort1.o

Add `sort1.o` to `NEW_LIBS` and `NEW_FILES` in `link.sh`. Create a file `package.lisp` containing the form `(`DEFPACKAGE` "FFI-TEST" (:use "LISP" "FFI"))` and add `package.lisp` to `TO_PRELOAD` in `link.sh`. Proceed:

    $ cd ..
    $ base/lisp.run -M base/lispinit.mem -c sort2.lisp sorttest.lisp
    $ clisp-link add-module-set sort base base+sort
    $ base+sort/lisp.run -M base+sort/lispinit.mem -i sort2 sorttest
    > (sort10 10 '#(0.501d0 0.528d0 0.615d0 0.550d0 0.711d0
                    0.523d0 0.585d0 0.670d0 0.271d0 0.063d0))
    #(0.063d0 0.271d0 0.501d0 0.523d0 0.528d0 0.55d0 0.585d0 0.615d0 0.67d0 0.711d0)
    $ rm -r base+sort

Example 30.10. Calling Lisp from C dynamically

Create a dynamic library `lispdll` (`#P".dll"` on Win32, `#P".so"` on UNIX) with the following function:

    typedef int (*LispFunc)(int parameter);
    int CallInFunc(LispFunc f) {
      return f(5)+11;
    }

and call it from Lisp:

    (ffi:def-call-out callout
      (:name "CallInFunc")
      (:library "lispdll.dll")
      (:arguments (function-arg
                   (ffi:c-function (:arguments (number ffi:int))
                                   (:return-type ffi:int) (:language :stdc))))
      (:return-type ffi:int)
      (:language :stdc))
    (defun f (x) (* x 2))
    F
    (callout #'f)
    21

Example 30.11. Variable size arguments: calling `gethostname` from CLISP

`int gethostname(`name, namelen`)`;
`char*` `name`;
`size_t` `namelen`;

follows a typical pattern of C "out"-parameter convention - it expects a pointer to a buffer it is going to fill. So you must view this parameter as either `:OUT` or `:IN-OUT`. Additionaly, one must tell the function the size of the buffer. Here `namelen` is just an `:IN` parameter. Sometimes this will be an `:IN-OUT` parameter, returning the number of bytes actually filled in.

So `name` is actually a pointer to an array of up to `namelen` characters, regardless of what the poor char* C prototype says, to be used like a C string (`NULL`-termination). UNIX specifies that “host names are limited to `HOST_NAME_MAX` bytes”, which is, of course, system dependent, but it appears that 256 is sufficient.

In the present example, you can use allocation `:ALLOCA`, like you would do in C: stack-allocate a temporary.

    (FFI:DEF-C-CALL-OUT gethostname
      (:arguments (name (FFI:C-PTR (FFI:C-ARRAY-MAX ffi:char 256))
    		    :OUT :ALLOCA)
    	      (len ffi:int))
      (:return-type ffi:int))

    (defun myhostname ()
      (multiple-value-bind (success name)
          ;; :OUT and :IN-OUT parameters are returned as multiple values
          (gethostname 256)
        (if (zerop success) name
    	(error ...)))) ;; strerror(errno)

    (defvar hostname (myhostname))

Example 30.12. Accessing variables in shared libraries.

Suppose one wants to access and modify variables that reside in shared libraries:

    struct bar {
      double x, y;
      double out;
    };

    struct bar my_struct = {10.0, 20.5, 0.0};

    double test_dll(struct bar *ptr)
    {
      return ptr->out = ptr->out + ptr->x + ptr->y;
    }

This is compiled to `libtest.so` (or `libtest.dll`, depending on your platform).

Use the following lisp code:

    (USE-PACKAGE "FFI")

    (FFI:DEF-C-STRUCT bar
      (x double-float)
      (y double-float)
      (out double-float))

    (FFI:DEF-CALL-OUT get-own-c-float
      (:library "libtest.so")
      (:language :stdc)
      (:name "test_dll")
      (:arguments (ptr c-pointer :in :alloca))
      (:return-type double-float))

    (FFI:DEF-C-VAR my-c-var (:name "my_struct")
      (:library "libtest.so") (:type (c-ptr bar)))

Note that `get-own-c-float` takes a FFI:C-POINTER, not a `(FFI:C-PTR bar)` as the argument.

Now you can access call `get-own-c-float` on `my-c-var`:

    (FFI:C-VAR-ADDRESS my-c-var)
    #<FOREIGN-ADDRESS #x282935D8>
    (get-own-c-float (FFI:C-VAR-ADDRESS my-c-var))
    30.5d0
    (get-own-c-float (FFI:C-VAR-ADDRESS my-c-var))
    61.0d0
    (get-own-c-float (FFI:C-VAR-ADDRESS my-c-var))
    91.5d0
    (get-own-c-float (FFI:C-VAR-ADDRESS my-c-var))
    122.0d0

#### 30.3.9.1. More examples

You can find more information and examples of the CLISP “FFI” in the following `<clisp-list@sf.net>` messages:

- "variable size values"
- "variable length arrays"

## 30.4. Extensions-2.4. The Amiga Foreign Function Call Facility

### Platform dependent: no platform supports this currently.

Another Foreign Function Interface. All symbols relating to the simple foreign function interface are exported from the package “AFFI”. To use them, `(`USE-PACKAGE` "AFFI")`.

### 30.4.1. Design issues

“AFFI” was designed to be small in size but powerful enough to use most library functions. Lisp files may be compiled to `#P".fas"` files without the need to load function definition files at run-time and without external C or linker support. memory images can be created, provided that the function libraries are opened at run-time.

Therefore, “AFFI” supports only primitive C types (integers 8, 16 and 32 bits wide, signed or unsigned, pointers) and defines no new types or classes. Foreign functions are not first-class objects (you can define a λ yourself), name spaces are separate.

The “AFFI” does no tracking of resources. Use `EXT:FINALIZE`.

### 30.4.2. Overview

These are the “AFFI” forms:

`(declare-library-base `keyword-base` `library-name`)`

`(require-library-functions `library-name` [(:import {`string-name`}*)])`

`(open-library `base-symbol`)`

`(close-library `base-symbol`)`

`(with-open-library (`base-symbol` | `library-name`) {`form`}*)`

`(defflibfun `function-name` `base-symbol` `offset` `mask` `result-type` {`argument-type`}*)`

`(declare-library-function `function-name` `library-name` {`option`}*)`

`(flibcall `function-name` {`argument`}*)`

`(mlibcall `function-name` {`argument`}*)`

`(mem-read `address` `result-type` [`offset`])`

`(mem-write `address` `type` `value` [`offset`])`

`(mem-write-vector `address` `vector` [`offset`])`

`(nzero-pointer-p `value`)`

Except for `with-open-library`, `declare-library-function` and `mlibcall`, all of the above are functions.

A library contains a collection of functions. The library is referred to by a symbol referred as library-base at the “AFFI” level. This symbol is created in the package “AFFI”. The link between this symbol and the OS-level library name is established by `declare-library-base`. To avoid multiple package conflicts, this and only this function requires the symbol-name to be in the “KEYWORD” package. The function returns the library-base.

A library may be opened by `open-library` and closed by `close-library`. An opened library must be closed. `with-open-library` is provided to automatically close the library for you, thus it is much safer to use.

A function is contained in a library. Every function is referred to by a symbol. A function is defined through `defflibfun` or `declare-library-function` by giving the function name, the library-base, an offset into the library, a mask (or `NIL`) for register-based library calls, the result type and all parameter-types. `require-library-functions` loads the complete set of functions defined in a library file. Symbols are created in the package “AFFI” and imported into the current package.

`flibcall` and `mlibcall` call library functions. `mlibcall` is a macro that does a few checks at macroexpansion time and allows the compiler to inline the call, not requiring the foreign function to be defined again at load or execution time. The use of this macro is advertised wherever possible.

`mem-read` reads an arbitrary address (with offset for structure references) and returns the given type.

`mem-write` writes an arbitrary address. `mem-write-vector` copies the content of a Lisp `STRING` or `(`VECTOR` (`UNSIGNED-BYTE` 8))` into memory.

`nzero-pointer-p` tests for non-`NULL` pointers in all recognized representations (`NULL`, `UNSIGNED-BYTE` and `FFI:FOREIGN-POINTER`).

### 30.4.3. Foreign Libraries

`declare-library-base` ought to be wrapped in an `(`EVAL-WHEN` (compile eval load) ...)` form and come before any function is referenced, because the library base symbol must be known.

`open-library` tries to open the library referenced by the base symbol. Therefore it must have been preceded with `declare-library-base`. The call returns `NIL` on failure. `open-library` calls nest. Every successful call must be matched by `close-library`. `with-open-library` does this for you and also allows you to specify the library by name, provided that its base has been declared. It is recommended to use this macro and to reference the library by name.

CLISP will not close libraries for you at program exit. [A previous version did so but now “AFFI” is a module and there are no module exit functions.] Programmers, watch `AFFI::*LIBRARIES-ALIST*`.

### 30.4.4. (Foreign) C types

The following foreign C types are used in “AFFI”. They are not regular Common Lisp types or CLOS classes.

“AFFI” name | Lisp equivalent | C equivalent | Comment |
`NIL` | `NIL` | void | as a result type for functions only |
4 | `(`UNSIGNED-BYTE` 32)` | unsigned long |  |
2 | `(`UNSIGNED-BYTE` 16)` | unsigned short |  |
1 | `(`UNSIGNED-BYTE` 8)` | unsigned char |  |
-4 | `(`SIGNED-BYTE` 32)` | long |  |
-2 | `(`SIGNED-BYTE` 16)` | short |  |
-1 | `(`SIGNED-BYTE` 8)` | signed char |  |
0 | `BOOLEAN` | BOOL | as a result type for functions only |
* | opaque | void* |  |
`:EXTERNAL` | opaque | void* |  |
`STRING` | `STRING` or `VECTOR` | char* |  |
`:IO` | `STRING` or `VECTOR` | char* |  |

Objects of type `STRING` are copied and passed `NULL`-terminated on the execution stack. On return, a Lisp string is allocated and filled from the address returned (unless `NULL`). Functions with `:IO` parameters are passed the address of the Lisp string or unsigned byte vector. These are not `NULL`-terminated! This is useful for functions like like `read` which do not need an array at a constant address longer than the dynamic extent of the call (it is dangerous to define callback functions with `:IO` (or `STRING`) type parameters). Arguments of type `INTEGER` and `FFI:FOREIGN-POINTER` are always acceptable where a `STRING` or `:IO` type is specified.

See also `CUSTOM:*FOREIGN-ENCODING*`.

To meet the design goals, predefined types and objects were used. As such, pointers were represented as integers. Now that there is the `FFI:FOREIGN-POINTER` type, both representations may be used on input. The pointer type should be therefore considered as opaque. Use `nzero-pointer-p` for `NULL` tests.

### 30.4.5. Foreign functions

Foreign Functions are declared either through `defflibfun` or `declare-library-function`. The former is closer to the low-level implementation of the interface, the latter is closer to the other “FFI”.

`defflibfun` requires the library base symbol and register mask to be specified, `declare-library-function` requires the library name and computes the mask from the declaration of the arguments.

The value of mask is implementation-dependent.

The “AFFI” type `0` is only acceptable as a function result type and yields either `T` or `NIL`. The difference between `*` and `:EXTERNAL` is the following: `*` uses integers, `:EXTERNAL` uses `FFI:FOREIGN-POINTER` as function result-type (except from `NIL` for a `NULL` pointer) and refuses objects of type `STRING` or `(`VECTOR` (`UNSIGNED-BYTE` 8))` as input. Thus `:EXTERNAL` provides some security on the input and the ability to use `EXT:FINALIZE` for resource-tracking on the output side.

`(declare-library-function `name` `library-name` {`option`}*)`

`option` ::==

  | `(:offset `library-offset`)`
  | | `(`:ARGUMENTS` {(`argument` `“AFFI”-type` `register`)}*)`
  | | `(:return-type `“AFFI”-type`)`

`register` ::==
  `:d0` | `:d1` | ... | `:d7` | `:a0` | ... | `:a6`

declares a named library function for further reference through `flibcall` and `mlibcall`.

`mlibcall` should be the preferred way of calling foreign functions (when they are known at compile-time) as macroexpansion-time checks may be performed and the call can be sort of inlined.

### 30.4.6. Memory access

`(affi:mem-read `address` `type` `offset`)` can read 8, 16 and 32 bit signed or unsigned integers (“AFFI” types -4, -2, -1, 1, 2, 4), a pointer (*), a `NULL`-terminated string (string) or, if the type argument is of type `STRING` or `(`VECTOR` (`UNSIGNED-BYTE` 8))`, it can fill this vector. `:EXTERNAL` is not an acceptable type as no object can be created by using `affi:mem-read`.

`(affi:mem-write `address` `type` `value` [`offset`])` writes integers (“AFFI” type -4, -2, -1, 1, 2 and 4) or pointer values (type *), but not vectors to the specified memory address.

`(affi:mem-write-vector `address` `vector` [`offset`])` can write memory from the given vector (of type `STRING` or `(`VECTOR` (`UNSIGNED-BYTE` 8))`).

### 30.4.7. Function Definition Files

`affi:require-library-functions` will `REQUIRE` a file of name derived from thelibrary name and with type `affi`. It may be used to import all names into the current package or only a given subset identified by string names, using the `:import` keyword (recommended use). Some definition files for standard Amiga libraries are provided. See Example 30.13, “Using a predefined library function file” below.

As `affi:require-library-functions` loads a global file which you, the programmer, may have not defined, you may consider declaring every function yourself to be certain what the return and argument types are. See Example 30.16, “Some sample function definitions” below.

The file `read-fd.lisp` defines the function `make-partial-fd-file` with which the provided `.affi` files have been prepared from the original Amiga FD files (located in the directory `FD:`). They must still be edited as the function cannot know whether a function accepts a `*`, `:IO`, `string` or `:EXTERNAL` argument and because files in `FD:` only contain a register specification, not the width of integer arguments (`-4`, `-2`, `-1`, `1`, `2`, or `4`).

### 30.4.8. Hints

By using appropriate `EVAL-WHEN` forms for `affi:declare-library-base` and `affi:require-library-functions` and not using `affi:flibcall`, it is possible to write code that only loads library function definition files at compile-time. See Example 30.13, “Using a predefined library function file” below.

Do not rely on `EXT:FINALIZE` to free resources for you, as CLISP does not call finalizers when it exits, use `UNWIND-PROTECT`.

### 30.4.9. Caveats

You can consider the library bases being symbols in need of being imported from the package “AFFI” originating from a brain-damage, causing the usual symbol headaches when using foreign functions calls within macros. Luckily, even if the high-level interface (or its implementation in `affi1.lisp`) were to change, the low-level part (`affi.d`) should remain untouched as all it knows are `INTEGER`s and `FFI:FOREIGN-POINTER`s, no `SYMBOL`s. The difficulty is just to get the library base value at run-time. Feel free to suggest enhancements to this facility!

### 30.4.10. Examples

#### NB: These examples are somewhat specific to the Amiga.

Example 30.13. Using a predefined library function file

    (DEFPACKAGE "AFFI-TEST" (:use "LISP" "AFFI"))
    (IN-PACKAGE "AFFI-TEST")

    ;; SysBase is the conventional name for exec.library
    ;; It is only enforced by the file loaded by REQUIRE-LIBRARY-FUNCTIONS
    (eval-when (compile eval load)
      (declare-library-base :SysBase "exec.library")) ;keyword avoids name conflicts

    ;; using only MLIBCALL allows not to load definitions at load-time
    (eval-when (compile eval)
      (require-library-functions "exec.library"
        :import '("FindTask")))

    (with-open-library ("exec.library")
      (print (mlibcall FindTask 0)))

This file can be used in interpreted and compiled mode. Compiled, it will have inlined the library function calls.

Example 30.14. Using flibcall

    (DEFPACKAGE "AFFI-TEST" (:use "LISP" "AFFI"))
    (IN-PACKAGE "AFFI-TEST")

    (eval-when (compile eval load)
      ;; keyword avoids name conflicts
      (declare-library-base :SysBase "exec.library"))

    ;; The load situation permits the use of flibcall
    (eval-when (eval compile load)
      (require-library-functions "exec.library"))

    (unless (open-library 'SysBase) (error "No library for SysBase"))
    (flibcall (if t 'FindTask 'Debug) 0)
    (close-library 'SysBase)

Example 30.15. Be fully dynamic, defining library bases ourselves

    (DEFPACKAGE "AFFI-TEST" (:use "LISP" "AFFI"))
    (IN-PACKAGE "AFFI-TEST")

    (eval-when (compile eval load)
      (defvar mylib (declare-library-base :foobase "foo.library")))
    (eval-when (eval compile load)          ;eval allows mlibcall, load flibcall
      (defflibfun 'foo1 mylib -30 '#xA '* 'string)
      (defflibfun 'foo2 mylib -36 '#x21 0 * 4))

    (defun foo (name)
      (when (open-library mylib)
        (list (mlibcall foo1 name) (flibcall 'foo2 name 123213))
        (close-library mylib)))

Example 30.16. Some sample function definitions

    (defflibfun 'FindTask 'SysBase -294 #xA '* 'string)
    (eval-library-function FindTask "exec.library"
      (:offset -294)
      (:return-type *)
      (:arguments
       (name   string   :A1)))
    (declare-library-function NameFromLock "dos.library"
      (:offset -402)
      (:return-type 0)
      (:arguments
       (lock   4   :D1)
       (buffer :io :D2)
       (len    4   :D3)))

    (eval-when (compile eval)
      (defconstant GVF_LOCAL_ONLY (ash 1 9))
      (defflibfun 'SetVar 'DosBase -900 #x5432 0 'string 'string -4 4))
    (defun setvar (name value)
      (with-open-library (DosBase)
        ;; length of -1 means find length of NULL-terminated-string
        (mlibcall SetVar name value -1 GVF_LOCAL_ONLY)))

## 30.5. Extensions-2.5. Socket Streams

### Platform dependent: UNIX, Win32 platforms only.

`(`SOCKET:SOCKET-SERVER` `&OPTIONAL` [`port-or-socket`])`
  This function creates a socket an binds a port to the socket. The server exists to watch for client connect attempts. The optional argument is either a port (positive `FIXNUM`) or a `SOCKET:SOCKET-STREAM` (from whose peer the connections will be made).
`(`SOCKET:SOCKET-SERVER-CLOSE` `socket-server`)`
  Closes down the server socket. Just like streams, `SOCKET:SOCKET-SERVER`s are closed at garbage-collection. You should not rely on this however, because garbage-collection times are not deterministic.
`(`SOCKET:SOCKET-SERVER-HOST` `socket-server`)`
`(`SOCKET:SOCKET-SERVER-PORT` `socket-server`)`
  Returns the host mask indicating which hosts can connect to this server and the port which was bound using `SOCKET:SOCKET-SERVER`.
`(`SOCKET:SOCKET-WAIT` `socket-server` `&OPTIONAL` [`seconds` [`microseconds`]])`
  Wait for a fixed time for a connection on the `socket-server` (a `SOCKET:SOCKET-SERVER`). Without a timeout argument, `SOCKET:SOCKET-WAIT` blocks indefinitely. When timeout is zero, poll. Returns `T` when a connection is available (i.e., `SOCKET:SOCKET-ACCEPT` will not block) and `NIL` on timeout.
`(`SOCKET:SOCKET-ACCEPT` `socket-server` `&KEY` `:ELEMENT-TYPE` `:EXTERNAL-FORMAT` `:BUFFERED` `:TIMEOUT`)`
  Creates the server-side two-way `SOCKET:SOCKET-STREAM` for the connection. Waits for an attempt to connect to the server for no more than `:TIMEOUT` seconds (which may be a non-negative real number or a list `(sec usec)` or a pair `(sec . usec)`). `SIGNAL`s an `ERROR` if no connection is made in that time.
`(`SOCKET:SOCKET-CONNECT` `port` `&OPTIONAL` [`host`] `&KEY` `:ELEMENT-TYPE` `:EXTERNAL-FORMAT` `:BUFFERED` `:TIMEOUT`)`
  Attempts to create a client-side two-way `SOCKET:SOCKET-STREAM`. Blocks until the server accepts the connection, for no more than `:TIMEOUT` seconds. If it is 0, returns immediately and (probably) blocks on the next i/o operation (you can use `SOCKET:SOCKET-STATUS` to check whether it will actually block).
`(`SOCKET:SOCKET-STATUS` `socket-stream-or-list` `&OPTIONAL` [`seconds` [`microseconds`]])`

  Checks whether it is possible to read from or write to a `SOCKET:SOCKET-STREAM` or whether a connection is available on a `SOCKET:SOCKET-SERVER` without blocking.

  For the cognoscenti: this is the interface to `select`, so it will work for any CLISP `STREAM` which is based on a file descriptor, e.g., file/pipe/socket and `EXT:*KEYBOARD-INPUT*`.

  This is similar to `LISTEN`, which checks only one `STREAM` and only for input, and `SOCKET:SOCKET-WAIT`, which works only with `SOCKET:SOCKET-SERVER`s.

  We define “status” for a `SOCKET:SOCKET-SERVER` or a `SOCKET:SOCKET-STREAM` to be `:ERROR` if any i/o operation will cause an error.

  Additionally, for a `SOCKET:SOCKET-SERVER`, we define “status” to be `T` if a connection is available, i.e., is `SOCKET:SOCKET-ACCEPT` will not block, and `NIL` otherwise.

  Additionally, for a `SOCKET:SOCKET-STREAM`, we define “status” in the given `direction` (one of `:INPUT`, `:OUTPUT`, and `:IO`) to be

  Possible status values for various directions:

  `:INPUT` status:
    `NIL`
      reading will block
    `:INPUT`
      some input is available
    `:EOF`
      the stream has reached its end
  `:OUTPUT` status:
    `NIL`
      writing will block
    `:OUTPUT`
      output to the stream will not block
  `:IO` status:

    output status | input status
    --- | ---
    `NIL` | `:INPUT` | `:EOF`
    `NIL` | `NIL` | `:INPUT` | `:EOF`
    `:OUTPUT` | `:OUTPUT` | `:IO` | `:APPEND`

  Possible values of `socket-stream-or-list`:

  `SOCKET:SOCKET-STREAM` or `SOCKET:SOCKET-SERVER`
    Returns the appropriate status, as defined above (`:IO` status for `SOCKET:SOCKET-STREAM`)
  `(`SOCKET:SOCKET-STREAM` . `direction`)`
    Return the status in the specified direction
  a list of the above
    Return a list of values, one for each element of the argument list (a la `MAPCAR`)

  If you want to avoid `CONS`ing up a fresh list, you can make the elements of `socket-stream-or-list` to be `(`socket-stream` `direction` . `x`)` or `(`socket-server` . `x`)`. Then `SOCKET:SOCKET-STATUS` will destructively modify its argument and replace `x` or `NIL` with the status and return the modified list. You can pass this modified list to `SOCKET:SOCKET-STATUS` again.

  The optional arguments specify the timeout. `NIL` means wait forever, `0` means poll.

  The second value returned is the number of objects with non-`NIL` status, i.e., “actionable” objects. `SOCKET:SOCKET-STATUS` returns either due to a timeout or when this number is positive, i.e., if the timeout was `NIL` and `SOCKET:SOCKET-STATUS` did return, then the second value is positive.

`(`SOCKET:SOCKET-STREAM-HOST` `socket-stream`)`
`(`SOCKET:SOCKET-STREAM-PORT` `socket-stream`)`
  These two functions return information about the `SOCKET:SOCKET-STREAM`.
`(`SOCKET:SOCKET-SERVICE-PORT` `&OPTIONAL` `service-name` (`protocol` "tcp"))`
  A convenience function for looking up a port given the service name. It returns the servent struct as multiple values (name, list of aliases, port, protocol) for the given `service-name` and `protocol`, or all services as the list of `(`SIMPLE-VECTOR` 4)` if `service-name` is not given or is `:DEFAULT` or `NIL`.
`(`SOCKET:SOCKET-STREAM-PEER` `socket-stream` [`do-not-resolve-p`])`

  Given a socket stream, this function returns the name of the host on the opposite side of the connection and its port number; the server-side can use this to see who connected.

  When the optional second argument is non-`NIL`, the hostname resolution is disabled and just the IP address is returned, without the FQDN (Fully Qualified Domain Name).

`(`SOCKET:SOCKET-STREAM-LOCAL` `socket-stream` [`do-not-resolve-p`])`
  The dual to `SOCKET:SOCKET-STREAM-PEER` - same information, host name and port number, but for the local host. The difference from `SOCKET:SOCKET-STREAM-HOST` and `SOCKET:SOCKET-STREAM-PORT` is that this function asks the OS (and thus returns the correct trusted values) while the other two are just accessors to the internal data structure, and basically return the arguments given to the function which created the `socket-stream`.
`(`SOCKET:SOCKET-STREAM-SHUTDOWN` `socket-stream` `direction`)`

  Some Internet protocols, such as HTTP, provide for closing the connection in one `direction` using `shutdown`. This function provides an interface to this UNIX system call. `direction` should be `:INPUT` or `:OUTPUT`. Note that you should still call `CLOSE` after you are done with your `socket-stream`; this is best accomplished by using `WITH-OPEN-STREAM`.

  All `SOCKET:SOCKET-STREAM`s are bidirectional `STREAM`s (i.e., both `INPUT-STREAM-P` and `OUTPUT-STREAM-P` return `T` for them). `SOCKET:SOCKET-STREAM-SHUTDOWN` breaks this and turns its argument stream into an input `STREAM` (if `direction` is `:OUTPUT`) or output `STREAM` (if `direction` is `:INPUT`). Thus, the following important invariant is preserved: whenever

  - a `STREAM` is open (i.e., `OPEN-STREAM-P` returns `T`) and
  - a `STREAM` is an input `STREAM` (i.e., `INPUT-STREAM-P` returns `T`)

  the `STREAM` can be read from (e.g., with `READ-CHAR` or `READ-BYTE`).

`(`SOCKET:SOCKET-OPTIONS` `socket-server` `&REST` {`option`}*)`
  Query and, optionally, set socket options using `getsockopt` and `setsockopt`. An `option` is a keyword, optionally followed by the new value. When the new value is not supplied, `setsockopt` is not called. For each option the old (or current, if new value was not supplied) value is returned. E.g., `(`SOCKET:SOCKET-OPTIONS` `socket-server` :SO-LINGER 1 :SO-RCVLOWAT)` returns 2 values: `NIL`, the old value of the `:SO-LINGER` option, and 1, the current value of the `:SO-RCVLOWAT` option.

## 30.6. Extensions-2.6. Quickstarting delivery with CLISP

This section describes three ways to turn CLISP programs into executable programs, which can be started as quickly as executables written in other languages.

UNIX
  CLISP can act as a script interpreter.
Desktop environments such as KDE, GNOME, or Windows.
  Files created with CLISP can be associated with the CLISP executable so that clicking on them would make CLISP execute the appropriate code.
Linux kernel with `CONFIG_BINFMT_MISC=y`
  Associate the extensions `#P".fas"` and `#P".lisp"` with CLISP; then you can make the files executable and run them from the command line.

These three techniques apply to a single `#P".lisp"` or `#P".fas"` file. If your application is made up of several `#P".lisp"` or `#P".fas"` files, you can simply concatenate them (using cat) into one file; the techniques then apply to that concatenated file.

Platform dependent: UNIX platforms only.

  On Unix, a text file (`#P".fas"` or `#P".lisp"`) can be made executable by adding a first line of the form

      #!interpreter [interpreter-arguments]

  and using chmod to make the script executable. CLISP can be used as a script interpreter under the following circumstances:

  - The `interpreter` must be the full pathname of CLISP. The recommended path is `/usr/local/bin/clisp`, and if CLISP is actually installed elsewhere, making `/usr/local/bin/clisp` be a symbolic link to the real CLISP.
  - The `interpreter` must be a real executable, not a script. Unfortunately, in the binary distributions of CLISP on Solaris, clisp is a shell script because a C compiler cannot be assumed to be installed on this platform. If you do have a C compiler installed, build CLISP from the source yourself; make install will install clisp as a real executable.

  - On some platforms, the first line which specifies the interpreter is limited in length:

    - max. 32 characters on SunOS 4,
    - max. 80 characters on HP-UX,
    - max. 127 characters on Linux.

    Characters exceeding this limit are simply cut off by the system. At least 128 characters are accepted on Solaris, IRIX, AIX, OSF/1. There is no workaround: You have to keep the interpreter pathname and arguments short.

  - On Solaris and HP-UX, only the first `interpreter-arg` is passed to the `interpreter`. In order to pass more than one option (for example, `-Msomewhere.mem` and `-C`) to CLISP, separate them by hard spaces (ISO Latin-1 character 160) instead of normal spaces. (But the separator between `interpreter` and `interpreter-arguments` must still be a normal space!) CLISP will split the `interpreter-arguments` at hard spaces and at normal spaces.

  Script execution.

  - The script should contain Lisp forms, except in the `#!` line.
  - The file is loaded normally, through the function `LOAD` (in particular, the name of the script file, which is `$0` in /bin/sh, can be found in `*LOAD-TRUENAME*` and `*LOAD-PATHNAME*`).
  - Before it is loaded, the variable `EXT:*ARGS*` is bound to a list of strings, representing the arguments given to the Lisp script (i.e., `$1` in /bin/sh becomes `(`CAR` `EXT:*ARGS*`)` etc).
  - `*STANDARD-INPUT*` and `*STANDARD-OUTPUT*` are bound, as usual, to the Unix standard input and output. `*ERROR-OUTPUT*` is bound to the Unix error output.
  - Continuable errors will be turned to warnings (using `EXT:APPEASE-CERRORS`).
  - Non-continuable errors and Control-C interrupts will terminate the execution of the Lisp script with an error status (using `EXT:EXIT-ON-ERROR`).
  - If you wish the script's contents to be compiled during loading, add `-C` to the `interpreter-arguments`.

  See also the manual.

  If nothing works. Another, quite inferior, alternative is to put the following into a file:

      #!/bin/sh
      exec clisp <<EOF
      (lisp-form)
      (another-lisp-form)
      (yet-another-lisp-form)
      EOF

  The problem with this approach is that the return values of each form will be printed to the standard output. Another problem is that no user input will be available.

Platform dependent: Win32 platforms only.

  There are two different ways to make CLISP "executables" for Windows platforms.

  - Associate the `#P".mem"` extension with c:\clisp\lisp.exe -B c:\clisp -M %s.
  - Associate the `#P".fas"` extension with c:\clisp\lisp.exe -B c:\clisp -M c:\clisp\lispinit.mem -i %s. Alternatively, you may want to have a function `main` in your `#P".fas"` files and associate the `#P".fas"` extension with c:\clisp\lisp.exe -B c:\clisp -M c:\clisp\lispinit.mem -i %s -x (main).

  Then clicking on the compiled lisp file (with `#P".fas"` extension) will load the file (thus executing all the code in the file), while the clicking on a CLISP memory image (with `#P".mem"` extension) will start clisp with the given memory image.

  Note that CLISP is distributed with a file `install.bat`, which creates a file `clisp.lnk` on your desktop and also associates `#P".fas"`, `#P".lisp"`, and `#P".mem"` files with CLISP.

Platform dependent: Linux platforms only.

  You have to build your kernel with `CONFIG_BINFMT_MISC=y` and `CONFIG_PROC_FS=y`. Then you will have a `/proc/sys/fs/binfmt_misc/` directory and you will be able to do (as `root`; you might want to put these lines into `/etc/rc.d/rc.local`):

      bash# echo ":CLISP:E::fas::/usr/local/bin/clisp:" >> /proc/sys/fs/binfmt_misc/register
      bash# echo ":CLISP:E::lisp::/usr/local/bin/clisp:" >> /proc/sys/fs/binfmt_misc/register

  Then you can do the following:

      bash$ cat << EOF > hello.lisp
      (print "hello, world!")
      EOF
      bash$ clisp -c hello.lisp

      Compiling file hello.lisp ...

      Compilation of file hello.lisp is finished.
      0 errors, 0 warnings
      bash$ chmod +x hello.fas
      bash$ hello.fas

      "hello, world!"
      bash$

  Please read `/usr/src/linux/Documentation/binfmt_misc.txt` for details.

## 30.7. Extensions-2.7. Application delivery with CLISP

Some ways of packaging CLISP programs are discussed in the section Quickstarting delivery with CLISP.

CLISP is Free Software, covered by the GNU GPL, with special terms governing the distribution of applications that run in CLISP. The precise terms can be found in the `COPYRIGHT` file contained in the source and binary distributions of CLISP. Here is an informal clarification what these terms mean in practice. Please refer to the said `COPYRIGHT` file when in doubt.

In many cases, CLISP does not force an application to be covered by the GNU GPL. Nevertheless, we encourage you to release your software under an open source license. The benefits of such a license for your users are numerous, in particular they are free to modify the application when their needs/requirements change, and they are free to recompile the application when they upgrade their machine or operating system.

CLISP extensions, i.e. programs which need to access non-portable CLISP internal symbols (in the packages “SYSTEM”, “CLOS”, “FFI”, ...), must be covered by GNU GPL as well.

Other programs running in CLISP have to or need not to be placed under GNU GPL, depending on their distribution form:

- Programs distributed as Lisp source or `#P".fas"` files can be distributed without restrictions coming from CLISP.
- Programs distributed as CLISP memory images can be distributed only if accompanied with the non-CLISP `#P".fas"` files which make up the memory image, and a `#P"Makefile"` for rebuilding the memory image.
- If you need to distribute a modified CLISP executable (for example, incorporating additional modules written in C), you must distribute its full source under GNU GPL. If you are not satisfied with this, you can instead put the additional modules into a separate (non-CLISP) program, with which your Lisp program will communicate via `SOCKET:SOCKET-STREAM`s.

## 30.8. Extensions-2.8. Shell, Pipes and Printing

### 30.8.1. Shell

Platform dependent: UNIX platforms only.
  `(`EXT:EXECUTE` `program` `arg1` `arg2` ...)` executes an external program. Its name is `program` (a full pathname). It is given the strings `arg1`, `arg2`, ... as arguments.
Platform dependent: UNIX, Win32 platforms only.
  `(`EXT:SHELL` [`command`])` calls the operating system's shell, the value of the environment variable `SHELL` on UNIX and `COMSPEC` on Win32. `(`EXT:SHELL`)` calls the shell for interactive use. `(`EXT:SHELL` `command`)` calls the shell only for execution of the one given `command`.
Platform dependent: UNIX, Win32 platforms only.

  The functions `EXT:RUN-SHELL-COMMAND` and `EXT:RUN-PROGRAM` are the general interface to `EXT:SHELL` and the above:

  `(`EXT:RUN-SHELL-COMMAND` `command` `&KEY` `:INPUT` `:OUTPUT` `:IF-OUTPUT-EXISTS` `:WAIT`)` runs a shell command (including shell built-in commands, like DIR on Win32 and for/do/done on UNIX).

  `(`EXT:RUN-PROGRAM` `program` `&KEY` `:ARGUMENTS` `:INPUT` `:OUTPUT` `:IF-OUTPUT-EXISTS` `:WAIT`)` runs an external program.

  `command`

    the shell command.

    Platform dependent: UNIX platforms only.
      The shell the command is passed to is the value of the environment variable `SHELL`, which normally is /bin/sh. The command should be a “simple command”; a “command list” should be enclosed in "{ ... ; }" (for /bin/sh) or "( ... )" (for `/bin/csh`).
  `program`
    the program. The directories listed in the environment variable `PATH` will be searched for it.
  `:ARGUMENTS`
    a list of arguments (strings) that are given to the program.
  `:INPUT`
    where the program's input is to come from: either `:TERMINAL` (the standard input, default) or `:STREAM` (a Lisp stream to be created) or a pathname (an input file) or `NIL` (no input at all).
  `:OUTPUT`
    where the program's output is to be sent to: either `:TERMINAL` (the standard output, default) or `:STREAM` (a Lisp stream to be created) or a pathname (an output file) or `NIL` (ignore the output).
  `:IF-OUTPUT-EXISTS`
    what to do if the `:OUTPUT` file already exists. The possible values are `:OVERWRITE`, `:APPEND`, `:ERROR`, with the same meaning as for `OPEN`. The default is `:OVERWRITE`.
  `:WAIT`
    whether to wait for program termination or not (this is useful when no i/o to the process is needed); the default is `T`, i.e., synchronous execution.
  `:MAY-EXEC`
    pass exec to the underlying shell (UNIX only).
  `:INDIRECTP`
    use a shell to run the command, e.g., `(`EXT:RUN-PROGRAM` "dir" :indirectp `T`)` will run the shell built-in command DIR. (Win32 only).

  If `:STREAM` was specified for `:INPUT` or `:OUTPUT`, a Lisp `STREAM` is returned. If `:STREAM` was specified for both `:INPUT` and `:OUTPUT`, three Lisp `STREAM`s are returned, as for the function `EXT:MAKE-PIPE-IO-STREAM`. This use of `EXT:RUN-PROGRAM` can cause deadlocks, see `EXT:MAKE-PIPE-IO-STREAM`.

### 30.8.2. Pipes

Platform dependent: UNIX, Win32 platforms only.
  `(`EXT:MAKE-PIPE-INPUT-STREAM` `command` `&KEY` `:ELEMENT-TYPE` `:EXTERNAL-FORMAT` `:BUFFERED`)`
    returns an input `STREAM` that will supply the output from the execution of the given operating system command.
  `(`EXT:MAKE-PIPE-OUTPUT-STREAM` `command` `&KEY` `:ELEMENT-TYPE` `:EXTERNAL-FORMAT` `:BUFFERED`)`
    returns an output `STREAM` that will pass its output as input to the execution of the given operating system command.
  `(`EXT:MAKE-PIPE-IO-STREAM` `command` `&KEY` `:ELEMENT-TYPE` `:EXTERNAL-FORMAT` `:BUFFERED`)`

    returns three values. The first value is a bidirectional `STREAM` that will simultaneously pass its output as input to the execution of the given operating system command and supply the output from this command as input. The second and third value will be the input `STREAM` and the output `STREAM` that make up the bidirectional `STREAM`, respectively.

    ### Warning

    Note that these three streams must be closed individually.

    ### Warning

    Note that improper use of this function can lead to deadlocks. Use it at your own risk!

    A deadlock occurs if the command and your Lisp program either both try to read from each other at the same time or both try to write to each other at the same time.

    To avoid deadlocks, it is recommended that you fix a protocol between the command and your program and avoid any hidden buffering: use `READ-CHAR`, `READ-CHAR-NO-HANG`, `LISTEN`, `SOCKET:SOCKET-STATUS` instead of `READ-LINE` and `READ` on the input side, and complete every output operation by a `FINISH-OUTPUT`. The same precautions must apply to the called command as well.

### 30.8.3. Printing

The macro `EXT:WITH-OUTPUT-TO-PRINTER`:

    (EXT:WITH-OUTPUT-TO-PRINTER (variable [:EXTERNAL-FORMAT])
      {declaration}*
      {form}*)

binds the variable `variable` to an output `STREAM` that sends its output to the printer.

## 30.9. Extensions-2.9. Operating System Environment.

Most modern operating systems support environment variables that associate strings (“variables”) with other strings (“values”). These variables are somewhat similar to the `SPECIAL` variables in Common Lisp: their values are inherited by the processes from their parent process.

You can access your OS environment variables using the function `(`EXT:GETENV` `&OPTIONAL` `string`)`, where `string` is the name of the environment variable. When `string` is omitted or `NIL`, all the environment variables and their values are returned in an alist.

You can change the value of existing environment variables or create new ones using `(`SETF` (`EXT:GETENV` `string`) `new-value`)`.

## 30.10. Extensions-2.10. Other

Platform dependent: UNIX platforms only.

  When running under the X Window System, you can create a bidirectional `STREAM`, which uses a new dedicated xterm, using the function `EXT:MAKE-XTERM-IO-STREAM`:

        (SETQ *ERROR-OUTPUT*
          (SETQ *DEBUG-IO*
            (EXT:MAKE-XTERM-IO-STREAM)))

# Internals of the CLISP Implementation

## Chapter 31. Overview of CLISP's Garbage Collection

### These are internals, which are of interest only to the CLISP developers. If you are not subscribed to `<clisp-devel@sf.net>`, this chapter is probably not for you.

## 31.1. Introduction

Knowing that most `malloc` implementations are buggy and/or slow, and because CLISP needs to perform garbage collection, CLISP has its own memory management subsystem in files `#P"spvw*.d"`.

## 31.2. Lisp objects in CLISP

Three kinds of storage are distinguished:

- CLISP data (the "heap"), i.e. storage which contains Lisp objects and is managed by the garbage collector.
- CLISP stack (called `STACK`), contains CLISP objects
- C data (including program text, data, `malloc`ed memory)

A CLISP object is one word, containing a tag (partial type information) and either immediate data (e.g. `FIXNUM`s or `SHORT-FLOAT`s) or a pointer to storage. Pointers to C data have tag = `machine_type` = 0, pointers to CLISP stack have tag = `system_type`, most other pointers point to CLISP data.

Let us turn to these CLISP objects that consume regular CLISP memory. Every CLISP object has a size which is determined when the object is allocated (using one of the `allocate_*()` routines). The size can be computed from the type tag and - if necessary - the length field of the object's header. The length field always contains the number of elements of the object. The number of bytes is given by the function `objsize()`.

CLISP objects which contain exactly 2 CLISP objects (i.e. `CONS`es, `COMPLEX` numbers, `RATIO`s) are stored in a separate area and occupy 2 words each. All other CLISP objects have "varying length" (more precisely, not a fixed length) and include a word for garbage collection purposes at their beginning.

The garbage collector is invoked by `allocate_*()` calls according to certain heuristics. It marks all objects which are "live" (may be reached from the "roots"), compacts these objects and unmarks them. Non-live objects are lost; their storage is reclaimed.

2-pointer objects are compacted by a simple hole-filling algorithm: fill the left-most object into the right-most hole, and so on, until the objects are contiguous at the right and the hole is contiguous at the left.

Variable-length objects are compacted by sliding them down (their address decreases).

## 31.3. Memory Models

There are 6 memory models. Which one is used, depends on the operating system and is determined at build time.

Memory Models

SPVW_MIXED_BLOCKS_OPPOSITE

  The heap consists of one block of fixed length (allocated at startup). The variable-length objects are allocated from the left, the 2-pointer objects are allocated from the right. There is a hole between them. When the hole shrinks to 0, garbage-collect is invoked. garbage-collect slides the variable-length objects to the left and concentrates the 2-pointer objects at the right end of the block again. When no more room is available, some reserve area beyond the right end of the block is halved, and the 2-pointer objects are moved to the right accordingly.

  overview

  (+)
    Simple management.
  (+)
    No fragmentation at all.
  (-)
    The total heap size is limited.

SPVW_MIXED_BLOCKS_OPPOSITE & TRIVIALMAP_MEMORY

  The heap consists of two big blocks, one for variable-length objects and one for 2-pointer objects. The former one has a hole to the right and is extensible to the right, the latter one has a hole to the left and is extensible to the left. Similar to the previous model, except that the hole is unmapped.

  overview

  (+)
    Total heap size grows depending on the application's needs.
  (+)
    No fragmentation at all.
  (*)
    Works only when SINGLEMAP_MEMORY is possible as well.

SPVW_MIXED_BLOCKS_STAGGERED & TRIVIALMAP_MEMORY

  The heap consists of two big blocks, one for variable-length objects and one for 2-pointer objects. Both have a hole to the right, but are extensible to the right.

  overview

  (+)
    Total heap size grows depending on the application's needs.
  (+)
    No fragmentation at all.
  (*)
    Works only when SINGLEMAP_MEMORY is possible as well.

SPVW_MIXED_PAGES

  The heap consists of many small pages (usually around 8 KB). There are two kinds of pages: one for 2-pointer objects, one for variable-length objects. The set of all pages of a fixed kind is called a "Heap". Each page has its hole (free space) at its end. For every heap, the pages are kept sorted according to the size of their hole, using AVL trees. Garbage collection is invoked when the used space has grown by 25% since the last GC; until that point new pages are allocated from the operating system. The GC compacts the data in each page separately: data is moved to the left. Emptied pages are given back to the OS. If the holes then make up more than 25% of the occupied storage, a second GC turn moves objects across pages, from nearly empty ones to nearly full ones, with the aim to free as many pages as possible.

  overview

  (-)
    every allocation requires AVL tree operations, thus slower
  (+)
    Total heap size grows depending on the application's needs.
  (+)
    Works on operating systems which do not provide large contiguous areas.

SPVW_PURE_PAGES

  Just like SPVW_MIXED_PAGES, except that every page contains data of only a single type tag, i.e. there is a Heap for every type tag.

  overview

  (-)
    every allocation requires AVL tree operations, thus slower
  (+)
    Total heap size grows depending on the application's needs.
  (+)
    Works on operating systems which do not provide large contiguous areas.
  (-)
    More fragmentation because objects of different type never fit into the same page.
SPVW_PURE_BLOCKS

  There is a big block of storage for each type tag. Each of these blocks has its data to the left and the hole to the right, but these blocks are extensible to the right (because there is enough room between them). A garbage collection is triggered when the allocation amount since the last GC reaches 50% of the amount of used space at the last GC, but at least 512 KB. The garbage collection cleans up each block separately: data is moved left.

  overview

  (+)
    Total heap size grows depending on the application's needs.
  (+)
    No 16 MB total size limit.
  (*)
    Works only in combination with SINGLEMAP_MEMORY.

In page based memory models, an object larger than a page is the only object carried by its pages. There are no small objects in pages belonging to a big object.

The following combinations of memory model and `mmap` tricks are possible (the number indicates the order in which the respective models have been developed):

Table 31.1. Memory models with TYPECODES

| no MAP_MEMORY | TRIVIALMAP_MEMORY | SINGLEMAP_MEMORY | MULTIMAP_MEMORY | GENERATIONAL_GC
--- | --- | --- | --- | --- | ---
SPVW_MIXED_BLOCKS_OPPOSITE | 1 | 10 |  | 2 | 9
SPVW_MIXED_BLOCKS_STAGGERED |  | 7 |  |  | 8
SPVW_PURE_BLOCKS |  |  | 5 |  | 6
SPVW_MIXED_PAGES | 3 |  |  |  |
SPVW_PURE_PAGES | 4 |  |  |  |

Table 31.2. Memory models with no TYPECODES

| no MAP_MEMORY | TRIVIALMAP_MEMORY | GENERATIONAL_GC
--- | --- | --- | ---
SPVW_MIXED_BLOCKS_OPPOSITE | * | * | *
SPVW_MIXED_BLOCKS_STAGGERED |  | * | *
SPVW_MIXED_PAGES | * |  |

## 31.4. The burden of garbage-collection upon the rest of CLISP

Every subroutine marked with can trigger GC may invoke garbage-collect. garbage-collect moves all the CLISP objects and updates the pointers. But the garbage-collect looks only on the `STACK` and not in the C variables. (Anything else would not be portable.) Therefore at every "unsafe" point, i.e. every call to such a subroutine, all the C variables of type object MUST BE ASSUMED TO BECOME GARBAGE. (Except for objects that are known to be unmovable, e.g. immediate data or Subrs.) Pointers inside CLISP data (e.g. to the characters of a `STRING` or to the elements of a `SIMPLE-VECTOR`) become INVALID as well.

The workaround is usually to allocate all the needed CLISP data first and do the rest of the computation with C variables, without calling unsafe routines, and without worrying about garbage-collect.

Run-time GC-safety checking is available when you build CLISP with a C++ compiler, e.g.:

    bash$ CC=g++ ./configure --with-debug build-g-gxx

When built like this, CLISP will abort when you reference GC-unsafe data after an allocation (which could have triggered a garbage-collection), and gdb will pinpoint the trouble spot.

## 31.5. Foreign Pointers

Pointers to C functions and to `malloc`ed data can be hidden in CLISP objects of type machine_type; garbage-collect will not modify its value. But one should not dare to assume that a C stack pointer or the address of a C function in a shared library satisfies the same requirements.

If another pointer is to be viewed as a CLISP object, it is best to box it, e.g. in a `SIMPLE-BIT-VECTOR` or in an Fpointer (using `allocate_fpointer()`.)

## Chapter 32. Extending CLISP.

Common Lisp is a programmable programming language.

--John Foderaro

CLISP can be easily extended the same way any other Common Lisp implementation can: create a lisp file with your variables, functions, macros, etc.; `LOAD` it into a running CLISP, and save the memory image.

This method does not work when you need to use some functionality not available in CLISP, e.g., you want to call a C function. You are urged to use External Modules instead of adding built-in function. Note that CLISP comes with an “FFI” which allows you to access C libraries in an easy way (including creating `FFI:FOREIGN-FUNCTION`s dynamically).

## 32.1. Adding a built-in function.

In the rare cases when you really need to modify CLISP internals and add a truly built-in function, you should read the CLISP sources for inspiration and enlightenment, choose a file where your brand-new built-in function should go to, and then ...

- add the `LISPFUN` form and the implementation there;
- add the `LISPFUN` header to file `#P"subr.d"`;
- declare the function name in file `#P"constsym.d"` in the appropriate package (probably “EXT”, if there is no specific package);
- if your function accepts keyword arguments, then an appropriate pair of forms must be added to `#P"subrkw.d"` and you must make sure that the keyword symbols are declared in `#P"constsym.d"`;
- export your function name from the appropriate package in file `#P"init.lisp"`;
- when you are done, you should run make check-sources in your build directory: this will check that the definitions (source files) and the declarations (`#P"subr.d"`, `#P"subrkw.d"` and `#P"fsubr.d"`) are in sync.

### Warning

Be very careful with the GC-unsafe functions! Always remember about GC-safety!

These instructions are intentionally terse - you are encouraged to use modules and/or “FFI” instead of adding built-ins directly.

## 32.2. Adding a built-in variable.

If you must be able to access the variable in the C code, follow these steps:

- declare the variable name in `#P"constsym.d"` in the appropriate package (probably “CUSTOM”, if there is no specific package);
- add a `define_variable()` call in function `init_symbol_values()` in file `#P"spvw.d"`;
- export your variable name from the appropriate package in file `#P"init.lisp"`;

## 32.3. Recompilation.

Any change that forces make to remake `#P"lisp.run"`, will force recompilation of all `#P".lisp"` files and re-dumping of `#P"lispinit.mem"`, which may be time-consuming. This is not always necessary, depending on what kind of change you introduced.

On the other hand, if you change any of the following files:

`#P"constobj.d"`
`#P"constsym.d"`
`#P"fsubr.d"`
`#P"subr.d"`
`#P"subrkw.d"`

your `#P"lispinit.mem"` will have to be re-dumped.

### Warning

If you change the signature of any system function mentioned in the `FUNTAB` arrays in file `#P"eval.d"`, all the `#P".fas"` files will become obsolete and will need to be recompiled. You will need to add a note to that effect to the `#P"NEWS"` file and augment the object `version` in file `#P"constsym.d"`. Please try to avoid this as much as possible.

## Chapter 33. The CLISP bytecode specification

### Last modified: 19 September 1998.

## 33.1. Introduction

The CLISP compiler compiles Common Lisp programs into instruction codes for a virtual processor. This bytecode is optimized for saving space in the most common cases of Common Lisp programs. The main advantages/drawbacks of this approach, compared to native code compilation, are:

- Bytecode compiled programs are a lot smaller than when compiled to native code. This results in better use of CPU caches, and in less virtual memory paging. Users perceive this as good responsiveness.
- Maximum execution speed (throughput in tight loops) is limited.
- Since no bytecode instructions are provided for "unsafe" operations (like unchecked array accesses, or "fast" `CAR`/`CDR`), programs run with all safety checks enabled even when compiled.
- Execution speed of a program can easily be understood by looking at the output of the `DISASSEMBLE` function. A rule of thumb is that every elementary instruction costs 1 time unit, whereas a function call costs 3 to 4 time units.
- Needing to do no type inference, the compiler is pretty straightforward and fast. As a consequence, the definition of CLOS generic functions, which needs to compile small pieces of generated code, is not perceived to be slow.
- The compiler is independent from the hardware CPU. Different back-ends, one for each hardware CPU, are not needed. As a consequence, the compiler is fairly small (and would have been easily maintainable if it were written in a less kludgey way...), and it is impossible for the compiler writer to introduce CPU dependent bugs.

## 33.2. The virtual machine

The bytecode can be thought of as being interpreted by a virtual processor. The engine which actually interprets the bytecode (the "implementation of the virtual machine") is actually a C function, but it could as well be a just-in-time compiler which translates a function's bytecode into hardware CPU instructions the first time said function is called.

The virtual machine is a stack machine with two stacks:

`STACK`
  a stack for CLISP objects and frames (“Lisp stack”).
`SP`
  a stack for other data and pointers (“Program stack”).

This two-stack architecture permits to save an unlimited number of CLISP objects on the `STACK` (needed for handling of Common Lisp multiple values), without consing. Also, in a world with a compacting no-ambiguous-roots garbage collector, `STACK` must only hold CLISP objects, and `SP` can hold all the other data belonging to a frame, which would not fit into `STACK` without tagging/untagging overhead.

The scope of `STACK` and `SP` is only valid for a given function invocation. Whereas the amount of `STACK` space needed for executing a function (excluding other function calls) is unlimited, the amount of `SP` space needed is known a priori, at compile time. When a function is called, no relation is specified between the caller's `STACK` and the callee's `STACK`, and between the caller's `SP` and the callee's `SP`. The bytecode is designed so that outgoing arguments on the caller's `STACK` can be shared by the caller's incoming arguments area (on the callee's `STACK`), but a virtual machine implementation may also copy outgoing arguments to incoming arguments instead of sharing them.

The virtual machine has a special data structure, `values`, containing the "top of stack", specially adapted to Common Lisp multiple values:

`mv_count`
  an unsigned integer.
`value1`
  the first value, a CLISP object. If ``mv_count`` = 0, this is `NIL`.
`mv_space`
  all values except the first one, an array of CLISP objects.

The contents of `values` is short-lived. It does not survive a function call, not even a garbage collection.

The interpretation of some bytecode instructions depends on a constant, `jmpbufsize`. This is a CPU-dependent number, the value of `SYSTEM::*JMPBUF-SIZE*`. In C, it is defined as `ceiling(sizeof(jmp_buf),sizeof(void*))`.

## 33.3. The structure of compiled functions

A compiled function consists of two objects: The function itself, containing the references to all CLISP objects needed for the bytecode, and a byte vector containing only immediate data, including the bytecode proper.

Typically, the byte vector is about twice as large as the function vector. The separation thus helps the garbage collector (since the byte vector does not need to be scanned for pointers).

A function looks like this (cf. the C type `Cclosure`):

name
  This is the name of the function, normally a symbol or a list of the form `(`SETF` `symbol`)`. It is used for printing the function and for error messages. This field is immutable.
`codevec`
  This is the byte-code vector, a `(`SIMPLE-ARRAY` (`UNSIGNED-BYTE` 8) (*))`. This field is immutable.
`consts`[]
  The remaining fields in the function object are references to other CLISP objects. These references are immutable, which is why they are called "constants". (The referenced CLISP objects can be mutable objects, such as `CONS`es or `VECTOR`s, however.)

### The Exception to the Immutability Rule

When a generic function's dispatch code is installed, the `codevec` and `consts` fields are destructively modified.

Some of the `consts` can play special roles. A function looks like this, in more detail:

name
  see above.
`codevec`
  see above.
`venv-const`*
  At most one object, representing the closed-up variables, representing the variables of the lexical environment in which this function was defined. It is a `SIMPLE-VECTOR`, which looks like this: `#(`next` `value1` ... `valuen`)` where `value1`, ..., `valuen` are the values of the closed-up variables, and `next` is either `NIL` or a `SIMPLE-VECTOR` having the same structure.
`block-const`*
  Objects representing closed-up `BLOCK` tags, representing the `BLOCK` tags of the lexical environment in which this function was defined. Each is a `CONS` containing in the `CDR` part: either a frame pointer to the block frame, or `#<DISABLED>`. The `CAR` is the block's name, only for error message purposes.
`tagbody-const`*
  Objects representing closed-up `TAGBODY` tags, representing the `TAGBODY` tags of the lexical environment in which this function was defined. Each is a `CONS` containing in the `CDR` part: either a frame pointer to the `TAGBODY` frame, or `#<DISABLED>` if the `TAGBODY` has already been left. The `CAR` is a `SIMPLE-VECTOR` containing the names of the `TAGBODY` tags, only for the error message purposes.
`keyword-const`*
  If the function was defined with a lambda list containing `&KEY`, here come the symbols ("keywords"), in their correct order. They are used by the interpreter during function call.
`other-const`*
  Other objects needed by the function's bytecode.

If `venv-const`, `block-const`, `tagbody-const` are all absent, the function is called autonomous. This is the case if the function does not refer to lexical variables, blocks or tags defined in compile code outside of the function. In particular, it is the case if the function is defined in a null lexical environment.

If some `venv-const`, `block-const`, or `tagbody-const` are present, the function (a "closure") is created at runtime. The compiler only generates a prototype, containing `NIL` values instead of each `venv-const`, `block-const`, `tagbody-const`. At runtime, a function is created by copying this prototype and replacing the `NIL` values by the definitive ones.

The list `(`keyword-const`* `other-const`*)` normally does not contain duplicates, because the compiler removes duplicates when possible. (Duplicates can occur nevertheless, through the use of `LOAD-TIME-VALUE`.)

The `codevec` looks like this (cf. the C type `Codevec`):

`spdepth_1` (2 bytes)
  The 1st part of the maximal `SP` depth.
`spdepth_jmpbufsize` (2 bytes)
  The `jmpbufsize` part of the maximal `SP` depth. The maximal `SP` depth (precomputed by the compiler) is given by `spdepth_1 + spdepth_jmpbufsize * `jmpbufsize``.
`numreq` (2 bytes)
  Number of required parameters.
`numopt` (2 bytes)
  Number of optional parameters.
`flags` (1 byte)
  bit 0
    set if the function has an `&REST` parameter
  bit 7
    set if the function has `&KEY` parameters
  bit 6
    set if the function has `&ALLOW-OTHER-KEYS`
  bit 4
    set if the function is a generic function
  bit 3
    set if the function is a generic function and its effective method shall be returned (instead of being executed)
`signature` (1 byte)
  An abbreviation code depending on `numreq`, `numopt`, `flags`. It is used for speeding up the function call.
`numkey` (2 bytes, only if the function has `&KEY`)
  The number of `&KEY` parameters.
`keyconsts` (2 bytes, only if the function has `&KEY`)
  The offset of the `keyword-const` in the function.
`byte`* (any number of bytes)
  The bytecode instructions.

## 33.4. The general structure of the instructions

All instructions consist of one byte, denoting the opcode, and some number of operands.

The conversion from a byte (in the range 0..255) to the opcode is performed by lookup in the table contained in the file `#P"bytecode.d"`.

There are the following types of operands, denoted by different letters:

`k`, `n`, `m`, `l`
  A (nonnegative) numeric operand. The next byte is read. If its bit 7 is zero, then the bits 6..0 give the value (7 bits). If its bit 7 is one, then the bits 6..0 and the subsequent byte together form the value (15 bits).
`b`
  A (nonnegative) 1-byte operand. The next byte is read and is the value.
`label`
  A label operand. A signed numeric operand is read: The next byte is read. If its bit 7 is zero, then the bits 6..0 give the value (7 bits, sign-extended). If its bit 7 is one, then the bits 6..0 and the subsequent byte together form the value (15 bits, sign-extended). If the latter 15-bit result is zero, then four more bytes are read and put together (32 bits, sign-extended). Finally, the bytecode pointer for the target is computed as the current bytecode pointer (pointing after the operand just read), plus the signed numeric operand.

## 33.5. The instruction set

### 33.5.1. Instructions for constants

mnemonic | description | semantics
--- | --- | ---
`(`NIL`)` | Load `NIL` into values. | `value1` := `NIL`, `mv_count` := 1
`(PUSH-NIL `n`)` | Push `n` `NIL`s into the `STACK`. | `n` times do: *--`STACK` := `NIL`, values undefined
`(`T`)` | Load `T` into values. | `value1` := `T`, `mv_count` := 1
`(CONST `n`)` | Load the function's `n`th constant into values. | `value1` := `consts`[`n`], `mv_count` := 1

### 33.5.2. Instructions for lexical variables

mnemonic | description | semantics
--- | --- | ---
`(LOAD `n`)` | Load a directly accessible local variable into values. | `value1` := *(`STACK`+`n`), `mv_count` := 1
`(LOADI `k1` `k2` `n`)` | Load an indirectly accessible local variable into values. | `k` := `k1` + `jmpbufsize` * `k2`, `value1` := *(*(`SP`+`k`)+ `n`), `mv_count` := 1
`(LOADC `n` `m`)` | Load a closed-up variable, defined in the same function and directly accessible, into values. | `value1` := `SVREF`(*(`STACK`+`n`),1+`m`), `mv_count` := 1
`(LOADV `k` `m`)` | Load a closed-up variable, defined in an outer function, into values. | `v` := `venv-const`, `m` times do: `v` := `SVREF`(`v`,0), `value1` := `SVREF`(`v`,`m`), `mv_count` := 1
`(LOADIC `k1` `k2` `n` `m`)` | Load a closed-up variable, defined in the same function and indirectly accessible, into values. | `k` := `k1` + `jmpbufsize` * `k2`, `value1` := `SVREF`(*(*(`SP`+`k`)+`n`),1+`m`), `mv_count` := 1
`(STORE `n`)` | Store values into a directly accessible local variable. | *(`STACK`+`n`) := `value1`, `mv_count` := 1
`(STOREI `k1` `k2` `n`)` | Store values into an indirectly accessible local variable. | `k` := `k1` + `jmpbufsize` * `k2`, *(*(`SP`+`k`)+ `n`) := `value1`, `mv_count` := 1
`(STOREC `n` `m`)` | Store values into a closed-up variable, defined in the same function and directly accessible. | `SVREF`(*(`STACK`+`n`),1+m) := `value1`, `mv_count` := 1
`(STOREV `k` `m`)` | Store values into a closed-up variable, defined in an outer function. | `v` := `venv-const`, `m` times do: `v` := `SVREF`(`v`,0), `SVREF`(`v`,`m`) := `value1`, `mv_count` := 1
`(STOREIC `k1` `k2` `n` `m`)` | Store values into a closed-up variable, defined in the same function and indirectly accessible. | `k` := `k1` + `jmpbufsize` * `k2`, `SVREF`(*(*(`SP`+`k`)+`n`),1+`m`) := `value1`, `mv_count` := 1

### 33.5.3. Instructions for dynamic variables

mnemonic | description | semantics
--- | --- | ---
`(GETVALUE `n`)` | Load a symbol's value into values. | `value1` := symbol-value(`consts`[`n`]), `mv_count` := 1
`(SETVALUE `n`)` | Store values into a symbol's value. | symbol-value(`consts`[`n`]) := `value1`, `mv_count` := 1
`(BIND `n`)` | Bind a symbol dynamically. | Bind the value of the symbol `consts`[`n`] to `value1`, implicitly `STACK` -= 3, values undefined
`(UNBIND1)` | Dissolve one binding frame. | Unbind the binding frame `STACK` is pointing to, implicitly `STACK` += 3
`(UNBIND `n`)` | Dissolve `n` binding frames. | `n` times do: Unbind the binding frame `STACK` is pointing to, thereby incrementing `STACK` Thus, `STACK` += 1+2*`n`
`(PROGV)` | Bind a set of symbols dynamically to a set of values. | `symbols` := *`STACK`++, *--`SP` := `STACK`, build a single binding frame binding the symbols in `symbols` to the values in `value1`, values undefined

### 33.5.4. Instructions for stack operations

mnemonic | description | semantics
--- | --- | ---
`(PUSH)` | Push one object onto the `STACK`. | *--`STACK` := `value1`, values undefined
`(POP)` | Pop one object from the `STACK`, into values. | `value1` := *`STACK`++, `mv_count` := 1
`(SKIP `n`)` | Restore a previous `STACK` pointer. Remove `n` objects from the `STACK`. | `STACK` := `STACK` + `n`
`(SKIPI `k1` `k2` `n`)` | Restore a previous `STACK` pointer. Remove an unknown number of objects from the `STACK`. | `k` := `k1` + `jmpbufsize` * `k2`, `STACK` := *(`SP`+`k`), `SP` := `SP`+`k`+1, `STACK` := `STACK` + `n`
`(SKIPSP `k1` `k2`)` | Restore a previous `SP` pointer. | `k` := `k1` + `jmpbufsize` * `k2`, `SP` := `SP`+`k`

### 33.5.5. Instructions for control flow, jumps

mnemonic | description | semantics
--- | --- | ---
`(SKIP&RET `n`)` | Clean up the `STACK`, and return from the function. | `STACK` := `STACK`+`n`, return from the function, returning values.

`(SKIP&RETGF `n`)`

Clean up the `STACK`, and return from the generic function.

If bit 3 is set in the function's `flags`, then `STACK` := `STACK`+`n`, `mv_count` := 1, and return from the function. Otherwise: if the current function has no `&REST` argument, then `STACK` := `STACK`+`n`-`numreq`, apply `value1` to the `numreq` arguments still on the `STACK`, and return from the function. Else `STACK` := `STACK`+`n`-`numreq`-1, apply `value1` to the `numreq` arguments and the `&REST` argument, all still on the `STACK`, and return from the function.

`(JMP `label`)` | Jump to `label`. | PC := `label`.
`(JMPIF `label`)` | Jump to `label`, if `value1` is true. | If `value1` is not `NIL`, PC := `label`.
`(JMPIFNOT `label`)` | Jump to `label`, if `value1` is false. | If `value1` is `NIL`, PC := `label`.
`(JMPIF1 `label`)` | Jump to `label` and forget secondary values, if `value1` is true. | If `value1` is not `NIL`, `mv_count` := 1, PC := `label`.
`(JMPIFNOT1 `label`)` | Jump to `label` and forget secondary values, if `value1` is false. | If `value1` is `NIL`, `mv_count` := 1, PC := `label`.
`(JMPIFATOM `label`)` | Jump to `label`, if `value1` is not a cons. | If `value1` is not a cons, PC := `label`. values undefined
`(JMPIFCONSP `label`)` | Jump to `label`, if `value1` is a cons. | If `value1` is a cons, PC := `label`. values undefined
`(JMPIFEQ `label`)` | Jump to `label`, if `value1` is `EQ` to the top-of-stack. | If eq(`value1`,*`STACK`++), PC := `label`. values undefined
`(JMPIFNOTEQ `label`)` | Jump to `label`, if `value1` is not `EQ` to the top-of-stack. | If not eq(`value1`,*`STACK`++), PC := `label`. values undefined
`(JMPIFEQTO `n` `label`)` | Jump to `label`, if the top-of-stack is `EQ` to a constant. | If eq(*`STACK`++,`consts`[`n`]), PC := `label`. values undefined
`(JMPIFNOTEQTO `n` `label`)` | Jump to `label`, if the top-of-stack is not `EQ` to a constant. | If not eq(*`STACK`++,`consts`[`n`]), PC := `label`. values undefined
`(JMPHASH `n` `label`)` | Table-driven jump, depending on `value1`. | Lookup `value1` in the hash table `consts`[`n`]. (The hash table's test is either `EQ` or `EQL`.) If found, the hash table value is a signed `FIXNUM`, jump to it: PC := PC + value. Else jump to `label`. values undefined
`(JMPHASHV `n` `label`)` | Table-driven jump, depending on `value1`, inside a generic function. | Lookup `value1` in the hash table `SVREF`(`consts`[0],`n`). (The hash table's test is either `EQ` or `EQL`.) If found, the hash table value is a signed `FIXNUM`, jump to it: PC := PC + value. Else jump to `label`. values undefined
`(JSR `label`)` | Subroutine call. | *--`STACK` := function. Then start interpreting the bytecode at `label`, with values undefined. When a `(RET)` is encountered, program execution is resumed at the instruction after `(JSR `label`)`.
`(JMPTAIL `m` `n` `label`)` | Tail subroutine call. | `n``>=``m`. The `STACK` frame of size `n` is reduced to size `m`: {*(`STACK`+`n`-`m`), ..., *(`STACK`+`n`-1)} := {*`STACK`, ..., *(`STACK`+`m`-1)}. `STACK` += n-m. *--`STACK` := function. Then jump to `label`, with values undefined.

### 33.5.6. Instructions for lexical environment, creation of closures

mnemonic | description | semantics
--- | --- | ---
`(VENV)` | Load the `venv-const` into values. | `value1` := `consts`[0], `mv_count` := 1.
`(MAKE-VECTOR1&PUSH `n`)` | Create a `SIMPLE-VECTOR` used for closed-up variables. | `v` := new `SIMPLE-VECTOR` of size `n`+1. `SVREF`(`v`,0) := `value1`. *--`STACK` := `v`. values undefined
`(COPY-CLOSURE `m` `n`)` | Create a closure by copying the prototype and filling in the lexical environment. | `f` := copy-function(`consts`[`m`]). For `i`=0,..,`n`-1: `f`_`consts`[i] := *(`STACK`+`n`-1-`i`). `STACK` += `n`. `value1` := `f`, `mv_count` := 1

### 33.5.7. Instructions for function calls

mnemonic | description | semantics
--- | --- | ---
`(CALL `k` `n`)` | Calls a constant function with `k` arguments. | The function `consts`[`n`] is called with the arguments *(`STACK`+`k`-1), ..., *(`STACK`+0). `STACK` += `k`. The returned values go into values.
`(CALL0 `n`)` | Calls a constant function with 0 arguments. | The function `consts`[`n`] is called with 0 arguments. The returned values go into values.
`(CALL1 `n`)` | Calls a constant function with 1 argument. | The function `consts`[`n`] is called with one argument *`STACK`. `STACK` += 1. The returned values go into values.
`(CALL2 `n`)` | Calls a constant function with 2 arguments. | The function `consts`[`n`] is called with two arguments *(`STACK`+1) and *(`STACK`+0). `STACK` += 2. The returned values go into values.
`(CALLS1 `b`)` | Calls a system function with no `&REST`. | Calls the system function FUNTAB[`b`]. The right number of arguments is already on the `STACK` (including `#<UNBOUND>`s in place of absent `&OPTIONAL` or `&KEY` parameters). The arguments are removed from the `STACK`. The returned values go into values.
`(CALLS2 `b`)` | Calls a system function with no `&REST`. | Calls the system function FUNTAB[256+`b`]. The right number of arguments is already on the `STACK` (including `#<UNBOUND>`s in place of absent `&OPTIONAL` or `&KEY` parameters). The arguments are removed from the `STACK`. The returned values go into values.
`(CALLSR `m` `b`)` | Calls a system function with `&REST`. | Calls the system function FUNTABR[`b`]. The minimum number of arguments is already on the `STACK`, and `m` additional arguments as well. The arguments are removed from the `STACK`. The returned values go into values.
`(CALLC)` | Calls a computed compiled function with no `&KEY`. | Calls the compiled function `value1`. The right number of arguments is already on the `STACK` (including `#<UNBOUND>`s in place of absent `&OPTIONAL` parameters). The arguments are removed from the `STACK`. The returned values go into values.
`(CALLCKEY)` | Calls a computed compiled function with `&KEY`. | Calls the compiled function `value1`. The right number of arguments is already on the `STACK` (including `#<UNBOUND>`s in place of absent `&OPTIONAL` or `&KEY` parameters). The arguments are removed from the `STACK`. The returned values go into values.
`(FUNCALL `n`)` | Calls a computed function. | Calls the function *(`STACK`+`n`) with the arguments *(`STACK`+`n`-1), ..., *(`STACK`+0). `STACK` += `n`+1. The returned values go into values.
`(APPLY `n`)` | Calls a computed function with an unknown number of arguments. | Calls the function *(`STACK`+`n`) with the arguments *(`STACK`+`n`-1), ..., *(`STACK`+0) and a list of additional arguments `value1`. `STACK` += `n`+1. The returned values go into values.

### 33.5.8. Instructions for optional and keyword parameters

mnemonic | description | semantics
--- | --- | ---
`(PUSH-UNBOUND `n`)` | Push `n``#<UNBOUND>`s into the `STACK`. | `n` times do: *--`STACK` := `#<UNBOUND>`. values undefined
`(UNLIST `n` `m`)` | Destructure a proper `LIST`. | 0 ≤ `m` ≤ `n`. `n` times do: *--`STACK` := `CAR`(`value1`), `value1` := `CDR`(`value1`). During the last `m` iterations, the list `value1` may already have reached its end; in this case, *--`STACK` := `#<UNBOUND>`. At the end, `value1` must be `NIL`. values undefined
`(UNLIST* `n` `m`)` | Destructure a proper or dotted `LIST`. | 0 ≤ `m` ≤ `n`, `n` > 0. `n` times do: *--`STACK` := `CAR`(`value1`), `value1` := `CDR`(`value1`). During the last `m` iterations, the list `value1` may already have reached its end; in this case, *--`STACK` := `#<UNBOUND>`. At the end, after `n` `CDR`s, *--`STACK` := `value1`. values undefined
`(JMPIFBOUNDP `n` `label`)` | Jump to `label`, if a local variable is not unbound. | If *(`STACK`+`n`) is not `#<UNBOUND>`, `value1` := *(`STACK`+`n`), `mv_count` := 1, PC := `label`. Else: values undefined.
`(BOUNDP `n`)` | Load `T` or `NIL` into values, depending on whether a local variable is bound. | If *(`STACK`+`n`) is not `#<UNBOUND>`, `value1` := `T`, `mv_count` := 1. Else: `value1` := `NIL`, `mv_count` := 1.
`(UNBOUND->NIL `n`)` | If a local variable is unbound, assign a default value `NIL` to it. | If *(`STACK`+`n`) is `#<UNBOUND>`, *(`STACK`+`n`) := `NIL`.

### 33.5.9. Instructions for multiple values

mnemonic | description | semantics
--- | --- | ---
`(VALUES0)` | Load no values into values. | `value1` := `NIL`, `mv_count` := 0
`(VALUES1)` | Forget secondary values. | `mv_count` := 1
`(`STACK`-TO-MV `n`)` | Pop the first `n` objects from `STACK` into values. | Load values(*(`STACK`+`n`-1),...,*(`STACK`+0)) into values. `STACK` += `n`.
`(MV-TO-`STACK`)` | Save values on `STACK`. | Push the `mv_count` values onto the `STACK` (in order: `value1` comes first). `STACK` -= `mv_count`. values undefined
`(NV-TO-`STACK` `n`)` | Save `n` values on `STACK`. | Push the first `n` values onto the `STACK` (in order: `value1` comes first). `STACK` -= `n`. values undefined
`(MV-TO-LIST)` | Convert multiple values into a list. | `value1` := list of values, `mv_count` := 1
`(LIST-TO-MV)` | Convert a `LIST` into multiple values. | Call the function `VALUES-LIST` with `value1` as argument. The returned values go into values.
`(MVCALLP)` | Start a `MULTIPLE-VALUE-CALL` invocation. | *--`SP` := `STACK`. *--`STACK` := `value1`.
`(MVCALL)` | Finish a `MULTIPLE-VALUE-CALL` invocation. | newSTACK := *`SP`++. Call the function *(newSTACK-1), passing it *(newSTACK-2), ..., *(`STACK`+0) as arguments. `STACK` := newSTACK. The returned values go into values.

### 33.5.10. Instructions for `BLOCK` and `RETURN-FROM`

mnemonic | description | semantics
--- | --- | ---
`(BLOCK-OPEN `n` `label`)` | Create a `BLOCK` frame. | Create a `BLOCK` frame, `STACK` -= 3, `SP` -= 2+`jmpbufsize`. The topmost (third) object in the block frame is `CONS`(`consts`[`n`],frame-pointer) (its `block-cons`). Upon a `RETURN-FROM` to this frame, execution will continue at `label`. values undefined.
`(BLOCK-CLOSE)` | Dissolve a `BLOCK` frame. | Dissolve the `BLOCK` frame at `STACK`, `STACK` += 3, `SP` += 2+`jmpbufsize`. Mark the `block-cons` as invalid.
`(RETURN-FROM `n`)` | Leave a `BLOCK` whose `block-cons` is given. | `block-cons` := `consts`[`n`]. If `CDR`(`block-cons`) = `#<DISABLED>`, `SIGNAL` an `ERROR`. Else `CDR`(`block-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it values.
`(RETURN-FROM-I `k1` `k2` `n`)` | Leave a `BLOCK` whose `block-cons` is indirectly accessible. | `k` := `k1` + `jmpbufsize` * `k2`, `block-cons` := *(*(`SP`+`k`)+`n`). If `CDR`(`block-cons`) = `#<DISABLED>`, `SIGNAL` an `ERROR`. Else `CDR`(`block-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it values.

### 33.5.11. Instructions for `TAGBODY` and `GO`

mnemonic | description | semantics
--- | --- | ---

`(TAGBODY-OPEN `m` `label1` ... `labeln`)`

Create a `TAGBODY` frame.

Fetch `consts`[`m`], this is a `SIMPLE-VECTOR` with `n` elements, then decode `n` label operands. Create a `TAGBODY` frame, `STACK` -= 3+`n`, `SP` -= 1+`jmpbufsize`. The third object in the `TAGBODY` frame is `CONS`(`consts`[`m`],frame-pointer) (the `tagbody-cons`) Upon a `GO` to tag `label` of this frame, execution will continue at `labell`. values undefined

`(TAGBODY-CLOSE-NIL)` | Dissolve a `TAGBODY` frame, and load `NIL` into values. | Dissolve the `TAGBODY` frame at `STACK`, `STACK` += 3+`m`, `SP` += 1+`jmpbufsize`. Mark the `tagbody-cons` as invalid. `value1` := `NIL`, `mv_count` := 1.
`(TAGBODY-CLOSE)` | Dissolve a `TAGBODY` frame. | Dissolve the `TAGBODY` frame at `STACK`, `STACK` += 3+`m`, `SP` += 1+`jmpbufsize`. Mark the `tagbody-cons` as invalid.
`(GO `n` `label`)` | Jump into a `TAGBODY` whose `tagbody-cons` is given. | `tagbody-cons` := `consts`[`n`]. If `CDR`(`tagbody-cons`) = `#<DISABLED>`, `SIGNAL` an `ERROR`. Else `CDR`(`tagbody-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it the number `label`.
`(GO-I `k1` `k2` `n` `label`)` | Jump into a `TAGBODY` whose `tagbody-cons` is indirectly accessible. | `k` := `k1` + `jmpbufsize` * `k2`, `tagbody-cons` := *(*(`SP`+`k`)+`n`). If `CDR`(`tagbody-cons`) = `#<DISABLED>`, `SIGNAL` an `ERROR`. Else `CDR`(`tagbody-cons`) is a frame-pointer. Unwind the stack up to this frame, pass it the number `label`.

### 33.5.12. Instructions for `CATCH` and `THROW`

mnemonic | description | semantics
--- | --- | ---
`(CATCH-OPEN `label`)` | Create a `CATCH` frame. | Create a `CATCH` frame, with `value1` as tag. `STACK` -= 3, `SP` -= 2+`jmpbufsize`. Upon a `THROW` to this tag execution continues at `label`.
`(CATCH-CLOSE)` | Dissolve a `CATCH` frame. | Dissolve the `CATCH` frame at `STACK`. `STACK` += 3, `SP` += 2+`jmpbufsize`.
`(THROW)` | Non-local exit to a `CATCH` frame. | `tag` := *`STACK`++. Search the innermost `CATCH` frame with tag `tag` on the `STACK`, unwind the stack up to it, pass it values.

### 33.5.13. Instructions for `UNWIND-PROTECT`

mnemonic | description | semantics
--- | --- | ---
`(UNWIND-PROTECT-OPEN `label`)` | Create an `UNWIND-PROTECT` frame. | Create an `UNWIND-PROTECT` frame. `STACK` -= 2, `SP` -= 2+`jmpbufsize`. When the stack will be unwound by a non-local exit, values will be saved on `STACK`, and execution will be transferred to `label`.
`(UNWIND-PROTECT-NORMAL-EXIT)` | Dissolve an `UNWIND-PROTECT` frame, and start the cleanup code. | Dissolve the `UNWIND-PROTECT` frame at `STACK`. `STACK` += 2, `SP` += 2+`jmpbufsize`. *--`SP` := 0, *--`SP` := 0, *--`SP` := `STACK`. Save the values on the `STACK`, `STACK` -= `mv_count`.
`(UNWIND-PROTECT-CLOSE)` | Terminate the cleanup code. | newSTACK := *`SP`++. Load values(*(newSTACK-1), ..., *(`STACK`+0)) into values. `STACK` := newSTACK. SPword1 := *`SP`++, SPword2 := *`SP`++. Continue depending on SPword1 and SPword2. If both are 0, simply continue execution. If SPword2 is 0 but SPword1 is nonzero, interpret it as a label and jump to it.
`(UNWIND-PROTECT-CLEANUP)` | Dissolve an `UNWIND-PROTECT` frame, and execute the cleanup code like a subroutine call. | Dissolve the `UNWIND-PROTECT` frame at `STACK`, get `label` out of the frame. `STACK` += 2, `SP` += 2+`jmpbufsize`. *--`SP` := 0, *--`SP` := PC, *--`SP` := `STACK`. Save the values on the `STACK`, `STACK` -= `mv_count`. PC := `label`.

### 33.5.14. Instructions for `HANDLER-BIND`

mnemonic | description | semantics
--- | --- | ---
`(HANDLER-OPEN `n`)` | Create a handler frame. | Create a handler frame, using `consts`[`n`] which contains the `CONDITION` types, the corresponding labels and the current `SP` depth (= function entry `SP` - current `SP`).
`(HANDLER-BEGIN&PUSH)` | Start a handler. | Restore the same `SP` state as after the HANDLER-OPEN. `value1` := the `CONDITION` that was passed to the handler, `mv_count` := 1. *--`STACK` := `value1`.

### 33.5.15. Instructions for some inlined functions

mnemonic | description | semantics
--- | --- | ---
`(NOT)` | Inlined call to `NOT`. | `value1` := not(`value1`), `mv_count` := 1.
`(EQ)` | Inlined call to `EQ`. | `value1` := eq(*`STACK`++,`value1`), `mv_count` := 1.
`(CAR)` | Inlined call to `CAR`. | `value1` := `CAR`(`value1`), `mv_count` := 1.
`(CDR)` | Inlined call to `CDR`. | `value1` := `CDR`(`value1`), `mv_count` := 1.
`(CONS)` | Inlined call to `CONS`. | `value1` := cons(*`STACK`++,`value1`), `mv_count` := 1.
`(SYMBOL-FUNCTION)` | Inlined call to `SYMBOL-FUNCTION`. | `value1` := `SYMBOL-FUNCTION`(`value1`), `mv_count` := 1.
`(SVREF)` | Inlined call to `SVREF`. | `value1` := `SVREF`(*`STACK`++,`value1`), `mv_count` := 1.
`(SVSET)` | Inlined call to `SYSTEM::SVSTORE`. | `arg1` := *(`STACK`+1), `arg2` := *(`STACK`+0), `STACK` += 2. `SVREF`(`arg2`,`value1`) := `arg1`. `value1` := `arg1`, `mv_count` := 1.
`(LIST `n`)` | Inlined call to `LIST`. | `value1` := `LIST`(*(`STACK`+`n`-1),...,*(`STACK`+0)), `mv_count` := 1, `STACK` += `n`.
`(LIST* `n`)` | Inlined call to `LIST*`. | `value1` := `LIST*`(*(`STACK`+`n`-1),..., *(`STACK`+0),`value1`), `mv_count` := 1, `STACK` += `n`.

### 33.5.16. Combined instructions

The most frequent short sequences of instructions have an equivalent combined instruction. They are only present for space and speed optimization. The only exception is `FUNCALL&SKIP&RETGF`, which is needed for generic functions.

mnemonic | equivalent
--- | ---
`(NIL&PUSH)` | `(NIL) (PUSH)`
`(T&PUSH)` | `(T) (PUSH)`
`(CONST&PUSH `n`)` | `(CONST `n`) (PUSH)`
`(LOAD&PUSH `n`)` | `(LOAD `n`) (PUSH)`
`(LOADI&PUSH `k1` `k2` `n`)` | `(LOADI `k1` `k2` `n`) (PUSH)`
`(LOADC&PUSH `n` `m`)` | `(LOADC `n` `m`) (PUSH)`
`(LOADV&PUSH `k` `m`)` | `(LOADV `k` `m`) (PUSH)`
`(POP&STORE `n`)` | `(POP) (STORE `n`)`
`(GETVALUE&PUSH `n`)` | `(GETVALUE `n`) (PUSH)`
`(JSR&PUSH `label`)` | `(JSR `label`) (PUSH)`
`(COPY-CLOSURE&PUSH `m` `n`)` | `(COPY-CLOSURE `m` `n`) (PUSH)`
`(CALL&PUSH `k` `n`)` | `(CALL `k` `n`) (PUSH)`
`(CALL1&PUSH `n`)` | `(CALL1 `n`) (PUSH)`
`(CALL2&PUSH `n`)` | `(CALL2 `n`) (PUSH)`
`(CALLS1&PUSH `b`)` | `(CALLS1 `b`) (PUSH)`
`(CALLS2&PUSH `b`)` | `(CALLS2 `b`) (PUSH)`
`(CALLSR&PUSH `m` `n`)` | `(CALLSR `m` `n`) (PUSH)`
`(CALLC&PUSH)` | `(CALLC) (PUSH)`
`(CALLCKEY&PUSH)` | `(CALLCKEY) (PUSH)`
`(FUNCALL&PUSH `n`)` | `(FUNCALL `n`) (PUSH)`
`(APPLY&PUSH `n`)` | `(APPLY `n`) (PUSH)`
`(CAR&PUSH)` | `(CAR) (PUSH)`
`(CDR&PUSH)` | `(CDR) (PUSH)`
`(CONS&PUSH)` | `(CONS) (PUSH)`
`(LIST&PUSH `n`)` | `(LIST `n`) (PUSH)`
`(LIST*&PUSH `n`)` | `(LIST* `n`) (PUSH)`
`(NIL&STORE `n`)` | `(NIL) (STORE `n`)`
`(T&STORE `n`)` | `(T) (STORE `n`)`
`(LOAD&STOREC `k` `n` `m`)` | `(LOAD `k`) (STOREC `n` `m`)`
`(CALLS1&STORE `b` `k`)` | `(CALLS1 `b`) (STORE `k`)`
`(CALLS2&STORE `b` `k`)` | `(CALLS2 `b`) (STORE `k`)`
`(CALLSR&STORE `m` `n` `k`)` | `(CALLSR `m` `n`) (STORE `k`)`
`(LOAD&CDR&STORE `n`)` | `(LOAD `n`) (CDR) (STORE `n`)`
`(LOAD&CONS&STORE `n`)` | `(LOAD `n`+1) (CONS) (STORE `n`)`
`(LOAD&INC&STORE `n`)` | `(LOAD `n`) (CALL1 #'1+) (STORE `n`)`
`(LOAD&DEC&STORE `n`)` | `(LOAD `n`) (CALL1 #'1-) (STORE `n`)`
`(LOAD&CAR&STORE `m` `n`)` | `(LOAD `m`) (CAR) (STORE `n`)`
`(CALL1&JMPIF `n` `label`)` | `(CALL1 `n`) (JMPIF `label`)`
`(CALL1&JMPIFNOT `n` `label`)` | `(CALL1 `n`) (JMPIFNOT `label`)`
`(CALL2&JMPIF `n` `label`)` | `(CALL2 `n`) (JMPIF `label`)`
`(CALL2&JMPIFNOT `n` `label`)` | `(CALL2 `n`) (JMPIFNOT `label`)`
`(CALLS1&JMPIF `b` `label`)` | `(CALLS1 `b`) (JMPIF `label`)`
`(CALLS1&JMPIFNOT `b` `label`)` | `(CALLS1 `b`) (JMPIFNOT `label`)`
`(CALLS2&JMPIF `b` `label`)` | `(CALLS2 `b`) (JMPIF `label`)`
`(CALLS2&JMPIFNOT `b` `label`)` | `(CALLS2 `b`) (JMPIFNOT `label`)`
`(CALLSR&JMPIF `m` `n` `label`)` | `(CALLSR `m` `n`) (JMPIF `label`)`
`(CALLSR&JMPIFNOT `m` `n` `label`)` | `(CALLSR `m` `n`) (JMPIFNOT `label`)`
`(LOAD&JMPIF `n` `label`)` | `(LOAD `n`) (JMPIF `label`)`
`(LOAD&JMPIFNOT `n` `label`)` | `(LOAD `n`) (JMPIFNOT `label`)`
`(LOAD&CAR&PUSH `n`)` | `(LOAD `n`) (CAR) (PUSH)`
`(LOAD&CDR&PUSH `n`)` | `(LOAD `n`) (CDR) (PUSH)`
`(LOAD&INC&PUSH `n`)` | `(LOAD `n`) (CALL1 #'1+) (PUSH)`
`(LOAD&DEC&PUSH `n`)` | `(LOAD `n`) (CALL1 #'1-) (PUSH)`
`(CONST&SYMBOL-FUNCTION `n`)` | `(CONST `n`) (SYMBOL-FUNCTION)`
`(CONST&SYMBOL-FUNCTION&PUSH `n`)` | `(CONST `n`) (SYMBOL-FUNCTION) (PUSH)`
`(CONST&SYMBOL-FUNCTION&STORE `n` `k`)` | `(CONST `n`) (SYMBOL-FUNCTION) (STORE `k`)`
`(APPLY&SKIP&RET `n` `k`)` | `(APPLY `n`) (SKIP&RET `k`)`
`(FUNCALL&SKIP&RETGF `n` `k`)` | `(FUNCALL `n`) (SKIP&RETGF `k`)`

### 33.5.17. Shortcut instructions

There are special one-byte instructions (without explicit operands) for the following frequent instructions:

mnemonic | operand range
--- | ---
`(LOAD `n`)` | 0 ≤ `n` < 15
`(LOAD&PUSH `n`)` | 0 ≤ `n` < 25
`(CONST `n`)` | 0 ≤ `n` < 21
`(CONST&PUSH `n`)` | 0 ≤ `n` < 30
`(STORE `n`)` | 0 ≤ `n` < 8

## Appendix A. GNU Free Documentation License

### Version 1.2, November 2002

> Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

## A.1. PREAMBLE

The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

## A.2. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.

The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

## A.3. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

## A.4. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

## A.5. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
4. Preserve all the copyright notices of the Document.
5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
8. Include an unaltered copy of this License.
9. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
11. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
13. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
14. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
15. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

## A.6. COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements".

## A.7. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

## A.8. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

## A.9. TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warrany Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

## A.10. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

## A.11. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

## A.12. ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

> Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this:

> with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

## Index

### Symbols

*CURRENT-LANGUAGE* , The Language
*WINDOW* , Extensions-2.1. Random Screen Access

### C

CLASS-FINALIZED-P , Defining Classes [CLHS-4.3.2]

### D

DEFINTERNATIONAL , The Language
DEFLANGUAGE , The Language
DEFLOCALIZED , The Language

### F

FINALIZE-INHERITANCE , Defining Classes [CLHS-4.3.2]
FORMAT
  ~!, Function FORMAT

### G

GC , Function ROOM
GENERIC-FLET , Deviations from ANSI CL standard
GENERIC-LABELS , Deviations from ANSI CL standard

### L

linking set, Overview
LOCALIZED , The Language

### M

MAKE-XTERM-IO-STREAM , Extensions-2.10. Other
METHOD-CALL-ERROR , Standard Method Combination [CLHS-7.6.6.2]
METHOD-CALL-TYPE-ERROR , Standard Method Combination [CLHS-7.6.6.2]
module, Overview
module set, Overview

### N

NO-PRIMARY-METHOD , Standard Method Combination [CLHS-7.6.6.2]

### P

PACKAGE-LOCK , Constraints on the “COMMON-LISP” Package for Conforming Programs - package locking [CLHS-11.1.2.1.2]

### S

SYMBOL-MACRO-EXPAND , Macro DEFINE-SYMBOL-MACRO

### W

WITH-OUTPUT-TO-PRINTER , Printing
WITHOUT-PACKAGE-LOCK , Constraints on the “COMMON-LISP” Package for Conforming Programs - package locking [CLHS-11.1.2.1.2]
WRITE-FLOAT-DECIMAL , Miscellaneous Issues

## References

### Books

[CLtL1] Guy L. Steele, Jr.. Common Lisp: the Language (1st Edition). 1984. 465. 0-201-10088-6. Digital Press.

[CLtL2] Guy L. Steele, Jr.. Common Lisp: the Language (2nd Edition). 1990. 1032. 0-201-10088-6. Digital Press.

[Metaobject Protocol] AMOPGregor Kiczales, Jim des Rivieres, and Daniel G. Bobrow. The Art of the Metaobject Protocol. 1991. 335. 0-262-61074-4. MIT Press.

### ANSI standard documents

[ANSI CL standard] ANSI CL1994. ANSI Common Lisp standard X3.226-1994 - Information Technology - Programming Language - Common Lisp.

[Common Lisp HyperSpec] CLHSCommon Lisp HyperSpec.