# Introduction [CLHS-1]

## Special Symbols [CLHS-1.4.1.3]

The final delimiter of an interactive stream: On &unix;, the user has to type &ctrl;D at the beginning of a line. On &dos; or &win32;, the user has to type &ctrl;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 &eos; 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.

## Error Terminology [CLHS-1.4.2]

Safety settings are ignored; therefore where the standard uses the phrase should signal an error, an &error-t; is &signal;ed.

## 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-t; contain the class &structure-object-t; instead of the class &standard-object-t;.

## Symbols in the Package &cl-pac; [CLHS-1.9]

The 6 symbols missing from the &cl-pac; package (out of 978 specified by the &ansi-cl;):

- &call-method;
- &define-method-combination;
- &invalid-method-error;
- &make-method;
- &method-combination-error;
- &method-combination-t;

# Syntax [CLHS-2]

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

## 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-t;, is interpreted as &symbol-t; when being read.

When creating a symbol from a token, no character attributes are removed.

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

## Double-Quote [CLHS-2.4.5]

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

## Backquote [CLHS-2.4.6]

The backquote read macro also works when nested. Example:

       (&eval; ``(,#'(&lambda-m; () ',a) ,#'(&lambda-m; () ',b)))
     = (&eval; `(list #'(&lambda-m; () ',a) #'(&lambda-m; () ',b)))
     = (&eval; (list 'list (list 'function (list 'lambda nil (list 'quote a)))
                         (list 'function (list 'lambda nil (list 'quote b)))))

## Sharpsign [CLHS-2.4.8]

Reader macros are also defined for the following:

### Additional reader macros

Macro | Meaning
--- | ---
#, | load-time evaluation
#Y | function objects and file &encoding;s
#"" | pathname

# 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-lang;, compiled functions (both of type &compiled-function-t;) and interpreted functions (of type &function-t;).

## Evaluation [CLHS-3.1]

### Introduction to Environments [CLHS-3.1.1]

#### Macro &the-env;

As in Scheme, the macro `(&the-env;)` returns the current lexical environment. This works only in interpreted code and is not compilable!

#### Function `(EXT:EVAL-ENV &form-r; &optional-amp; &env-r;)`

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.

## Compilation [CLHS-3.2]

### Compiler Terminology [CLHS-3.2.1]

&clisp; compiles to platform-independent byte-code.

### Compiler Macros [CLHS-3.2.2.1]

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

### Definition of Similarity [CLHS-3.2.4.2.2]

Hash tables are externalizable objects.

## Declarations [CLHS-3.3]

The declarations `(&type-dec; &type-r; &var-r; ...)`, `(&ftype-dec; &type-r; &func-r; ...)`, `(&optimize-dec; (quality &value-r;) ...)` are ignored by the interpreter and the compiler.

The &ansi-cl; declaration `(&optimize-dec; (debug ...))` is legal.

The &ansi-cl; declaration `(&ignorable-dec; &var-r; ...)` affects the variable binding for the variable &var-r;. The compiler will not warn about the variable, regardless whether it is used or not.

### Additional declarations

The declaration `(COMPILE)` has the effect that the current form is compiled prior to execution. Examples:

     (&locally; (&declare; (compile)) &form-r;)

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-r;, the second is interpreted (slower) and decrements the same &x-r;.

The type assertion `(&the; &val-type-r; &form-r;)` enforces a type check in interpreted code. No type check is done in compiled code. See also the &ethe; macro.

## Lambda Lists [CLHS-3.4]

### Boa Lambda Lists [CLHS-3.4.6]

The initial value of an &aux-amp; variable in a boa &lalist; is the value of the corresponding slot's initial form.

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

### Declaration &special-dec;

`(&proclaim; '(&special-dec; &var-r;))` 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;s may not be bound dynamically or lexically.

#### Function &spe-var-p;

You can use the function `(&spe-var-p; &symbol-r; &optional-amp; &env-r;)` to check whether the symbol is a special variable. &env-r; 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 &the-env; (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-r;, it will be called at run time and check for globally special variables, but when &env-r; is &t;, it will be called at compile time and the value will be used as a constant in the code.

### Function &constantp;.

Function &constantp; fully complies with &ansi-cl;. Additionally, some non-trivial forms are identified as constants, e.g., `(&constantp; '(&plus; 1 2 3))` returns &t;.

### Macro &eval-when;

&eval-when; also accepts the situations `(NOT EVAL)` and `(NOT COMPILE)`.

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

# Types and Classes [CLHS-4]

## Types [CLHS-4.2]

### Type Specifiers [CLHS-4.2.3]

The general form of the &complex-t; type specifier is `(&complex-t; type-of-real-part type-of-imaginary-part)`. The type specifier `(&complex-t; &type-r;)` is equivalent to `(&complex-t; &type-r; &type-r;)`.

The &ansi-cl; type specifier `(&real-t; low high)` denotes the real numbers between low and high.

&deftype; &lalist;s are subject to destructuring (nested &lalist;s are allowed, as in &defmacro;) and may contain a &whole-amp; marker, but not an &environment-amp; marker.

#### Function `(`EXT:TYPE-EXPAND` typespec &optional-amp; 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-t;

- &symbol-t;, &null-t;, &boolean-t;

- &fixnum-t;, &bignum-t;, &rational-t;, &short-float-t;, &single-float-t;, &double-float-t;, &long-float-t;, &complex-t;

- &character-t;, &base-char-t;

- `(&array-t; &eltype-r; &dimensions-r;)`, `(&simple-array-t; &eltype-r; &dimensions-r;)`

- `(&vector-t; &t; &size-r;)`, `(&simple-vector-t; &size-r;)`

- `(&string-t; &size-r;)`, `(&simple-string-t; &size-r;)`

- `(&base-string-t; &size-r;)`, `(&simple-base-string-t; &size-r;)`

- `(&bit-vector-t; &size-r;)`, `(&simple-bit-vector-t; &size-r;)`

- &function-t;, &compiled-function-t;

- &stream-t;, &file-stream-t;, &synonym-stream-t;, &broadcast-stream-t;, &concatenated-stream-t;, &two-way-stream-t;, &echo-stream-t;, &string-stream-t;

- &package-t;, &hash-table-t;, &readtable-t;, &pathname-t;, &logical-pathname-t;, &random-state-t;, &byte-t;

- `SPECIAL-OPERATOR`, `LOAD-TIME-EVAL`, &symbol-macro;, &encoding;, &foreign-pointer-t;, &foreign-address-t;, &foreign-variable;;, &foreign-function;

- &weak-pointer;, `READ-LABEL`, `FRAME-POINTER`, `SYSTEM-INTERNAL`

- `ADDRESS` (should not occur)

- any other &symbol-t; (structure types or &clos; classes)

- a class object (&clos; classes without a proper name)

## Classes [CLHS-4.3]

The &clos; symbols are &export;ed from the package &clos-pac;. &cl-pac; uses (as in &use-package;) &clos-pac; and &re-export;s the &ansi-cl; standard exported symbols (the &clisp; extensions, e.g., &class-proto;, are &not-e; &re-export;ed). Since the default &use-k; argument to &make-package; is &cl-pac;, 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-r; &cl-pac;)
      (&shadow; &symbol-r; "CL-NO-CLOS"))
    (&do-symbols; (&symbol-r; "CL-NO-CLOS")
      (&export; &symbol-r; "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

.

## Deviations from &ansi-cl;

&defclass; supports the option &metaclass-k; &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.

There is a generic function &no-prim;
(similar to &no-applicable-method;) which is called when a generic function of the class &standard-generic-function-t; is invoked and no primary method on that generic function is applicable.

&gen-flet;
and &gen-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 &clu-pac; and &cl-pac; because of the &ansi-cl; issue GENERIC-FLET-POORLY-DESIGNED:DELETE.

&add-method; can put methods into other generic functions than the one the method came from.

&print-object; is only called on objects of type &standard-object-t; and &structure-object-t;. It is not called on other objects, like &cons-t;es and &number-t;s, due to the performance concerns.

## 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-t;

- &character-t;

- &number-t;, &complex-t;, &real-t;, &float-t;, &rational-t;, &ratio-t;, &integer-t;

- &sequence-t;

- &array-t;, &vector-t;, &bit-vector-t; &string-t;

- &list-t;, &cons-t;

- &symbol-t;, &null-t;

- &function-t;, &generic-function-t;, &standard-generic-function-t;

- &hash-table-t;

- &package-t;

- &pathname-t;, &logical-pathname-t;

- &random-state-t;

- &readtable-t;

- &stream-t;, &broadcast-stream-t;, &concatenated-stream-t;, &echo-stream-t;, &string-stream-t;, &file-stream-t;, &synonym-stream-t;, &two-way-stream-t;

## Defining Classes [CLHS-4.3.2]

&defclass; supports the &metaclass-k; option. Possible values are &standard-class; (the default) and &structure-class; (which creates structure classes, like &defstruct; does).

It is &not-e; required that the superclasses of a class are defined before the &defclass; form for the class is evaluated. Use &amop; generic functions &class-fin-p;
to check whether the class has been finalized and thus its instances can be created, and &fin-inher;
to force class finalization.

## 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-e; 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.

## Integrating Types and Classes [CLHS-4.3.7]

The class &method-combination-t; is not implemented.

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

### Function &coerce;

&fixnum-t; is not a character designator in &ansi-cl;, although &code-char; provides an obvious venue to &coerce; a &fixnum-t; to a &character-t;. When &fixnum-char-ansi; is &nil;, &clisp; &coerce;s &fixnum-t;s to &character-t;s via &code-char;. When &fixnum-char-ansi; is non-&nil;, &fixnum-t;s cannot be &coerce;d to &character-t;s.

# Data and Control Flow [CLHS-5]

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

### Function &function-lambda-expression;

The &name-r; of a &foreign-function; is a string (the name of the underlying &c-lang; function), not a lisp function name.

### Macro &destructuring-bind;

This macro does not perform full error checking.

### Macros &prog1;, &prog2;, &and-m;, &or-m;, &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-e; evaluated at compile time, just like with &defvar; and &defparameter;. Use &eval-when; if you need the value at compile time.

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

### 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;.

### Function &eq;

&eq; compares &character-t;s and &fixnum-t;s as &eql; does. No unnecessary copies are made of &character-t;s and &number-t;s. Nevertheless, one should use &eql; as it is more portable across &cl; implementations.

`(let ((x y)) (eq x x))` always returns &t;, regardless of &y-r;.

Note that `(eq x x)` might not be &t; for a &foreign-variable; &x-r;.

### Function &symbol-function;

`(&setf; (&symbol-function; &symbol-r;) &object-r;)` requires &object-r; to be either a function, a &symbol-function; return value or a &lambda-expr;. The &lambda-expr; is thereby immediately converted to a &function-t;.

### Macro &setf;

Additional &place;s:

&funcall;

  `(&setf; (&funcall; #'&symbol-r; ...) &object-r;)` and `(&setf; (&funcall; '&symbol-r; ...) &object-r;)` are equivalent to `(&setf; (&symbol-r; ...) &object-r;)`.

&progn;

  `(&setf; (&progn; &form-r; ... &place-r;) &object-r;)`

&locally;

  `(&setf; (&locally; &declaration-r; ... &form-r; ... &place-r;) &object-r;)`

&if;

  `(&setf; (&if; condition place&sub-1; place&sub-2;) &object-r;)`

&get-dispatch-macro-character;

  `(&setf; (&get-dispatch-macro-character; ...) ...)` calls &set-dispatch-macro-character;.

&lfd;:

  `(&setf; (&lfd;) &digits-r;)` sets the default mantissa length of long floats to &digits-r; bits.

&values-list;

  `(&setf; (&values-list; list) &form-r;)` is equivalent to `(&values-list; (&setf; list (&multiple-value-list; &form-r;)))`

&key-amp; markers in &defsetf; &lalist;s are supported, but the corresponding keywords must appear literally in the program text.

`(&get-setf-expansion; &form-r; &optional-amp; &env-r;)`, `(EXT:GET-SETF-METHOD &form-r; &optional-amp; &env-r;)`, and `(EXT:GET-SETF-METHOD-MULTIPLE-VALUE &form-r; &optional-amp; &env-r;)` receive as optional argument &env-r; the environment necessary for macro expansions. In &define-setf-expander; and `EXT:DEFINE-SETF-METHOD` &lalist;s, one can specify &environment-amp; 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-t;. 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 &letf; and &letf-star; macros.

### Special Operator &function;

`(&function; &symbol-r;)` returns the local function definition established by &flet; or &labels;, if it exists, otherwise the global function definition.

`(&special-operator-p; &symbol-r;)` returns &nil; or &t;. If it returns &t;, then `(&symbol-function; &symbol-r;)` returns the (useless) special operator handler.

### 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-r; expansion)`.

The function &symbol-mex;
tests for a &symbol-macro;: If &symbol-r; is defined as a &symbol-macro;, `(&symbol-mex; &symbol-r;)` 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.

### Macro &lambda-m;

#### Constant &lambda-list-keywords;

`(&optional-amp; &rest-amp; &key-amp; &allow-other-keys-amp; &aux-amp; &body-amp; &whole-amp; &environment-amp;)`

#### Function call limits

&call-arguments-limit; | 212=4096
&multiple-values-limit; | 27=128
&lambda-parameters-limit; | 212=4096

### 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 &suppress-check-redef;

When &suppress-check-redef; is &nil;, &clisp; issues a &warning-t; when a function (macro, variable, class, etc) is redefined in a different file than its original definition. It is &not-e; a good idea to set this variable to &t;.

# Iteration [CLHS-6]

No notes.

# Objects [CLHS-7]

Only the &standard; method combination is implemented.

## Declarative Method Combination [CLHS-7.6.6.3]

User-defined method combination is not supported. The macros &define-method-combination;, &call-method; and the functions &invalid-method-error;, &method-combination-error; are not implemented.

## The Objects Dictionary [CLHS-7.7]

### Generic function &class-proto;.

The &amop; generic function &class-proto; 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 (&class-proto; '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

# Structures [CLHS-8]

The &print-function-k; option should contain a &lambda-expr; `(&lambda-m; (object stream depth) (declare (ignore depth)) ...)` This &lambda-expr; names a &function-t; whose task is to output the external representation of the &structure-object-t; &object-r; onto the &stream-t; &stream-r;. 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-var; must be respected.

- The treatment of &print-pretty-var; is up to you.

- The value of &print-circle-var; 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-var; is respected by &write;, &prin1;, &princ;, &print;, &pprint;, &format; instructions &format-a;, &format-s;, &format-w;, and &format; instructions &format-r;, &format-d;, &format-b;, &format-o;, &format-x;, &format-f;, &format-e;, &format-g;, &format-dollar; 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-var; must be respected, especially if you are outputting an arbitrary number of components.

- The value of &print-readably-var; must be respected. Remember that the values of &print-escape-var;, &print-level-var;, &print-length-var; are ignored if &print-readably-var; is true. The value of &print-readably-var; is respected by &print-unreadable-object;, &write;, &prin1;, &princ;, &print;, &pprint;, &format; instructions &format-a;, &format-s;, &format-w;, and &format; instructions &format-r;, &format-d;, &format-b;, &format-o;, &format-x;, &format-f;, &format-e;, &format-g;, &format-dollar; with not-numerical arguments. Therefore &print-readably-var; will be respected automatically if only these functions are used for printing objects.

- You need not worry about the values of &print-base-var;, &print-radix-var;, &print-case-var;, &print-gensym-var;, &print-array-var;, &pr-closure;, &pr-rpars;, &pr-indent;.

The &inherit-k; option is exactly like &include-k; except that it does not create new accessors for the inherited slots (this is a &clisp; extension).

# 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 &muffle-cerrors;

The macro `(&muffle-cerrors; {&form-r;}*)` executes the &form-r;s. When a continuable error occurs, no message is printed, instead, the &continue; &restart-t; is invoked.

## Macro &appease-cerrors;

The macro `(&appease-cerrors; {&form-r;}*)` executes the &form-r;s. Continuable errors are reported as warnings and the &continue; &restart-t; is invoked.

## Macro &exit-on-error;

The macro `(&exit-on-error; {&form-r;}*)` executes the &form-r;s. When a non-continuable error or a &ctrl;C interrupt occurs, the error message is printed and &clisp; terminates with an error status.

## Macro &with-restarts;

The macro &with-restarts; is like &restart-case;, except that the forms are specified after the restart clauses instead of before them, and the restarts created are not implicitly associated with any &condition-t;. `(&with-restarts; ({`restart-clause`}*) {&form-r;}*)` is therefore equivalent to `(&restart-case; (&progn; {&form-r;}*) {`restart-clause`}*)`.

## 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-t; reports containing an object which requires newlines when pretty printing is enabled, is undefined.

## The Conditions Dictionary [CLHS-9.2]

### Macro &restart-case;

In &restart-case; clauses the argument list can also be specified after the keyword/value pairs instead of before them. The syntax therefore is

### Macro `(&restart-case; &form-r; {`restart-clause`}*)`

`restart-clause` ::==

         (restart-name arglist
          {keyword-value}* {&form-r;}*) |
         (restart-name {keyword-value}*
          arglist {&form-r;}*)

### Function &compute-restarts;

&compute-restarts; and &find-restart; behave as specified in &ansi-cl;: 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.

# Symbols [CLHS-10]

No notes.

# Packages [CLHS-11]

## The &ansi-cl; packages present in &clisp;

&cl-pac;

  with the nicknames CL and LISP

&clu-pac;

  with the nicknames CL-USER and USER

&kwd-pac;

  with the nickname

The package &cl-pac; &export;s only those symbols from the &ansi-cl; that are actually implemented.

## Constraints on the &cl-pac; Package for Conforming Programs - package locking [CLHS-11.1.2.1.2]

### Function &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-t; (continuing overrides locking for this operation). When &suppress-check-redef; is &t; (&not-e; a good idea!), the &error-t; is not &signal;ed for redefine operations. Function `(&package-lock; &pack-r;)` returns the generalized boolean indicating whether the &pack-r; is locked. A package (or a list thereof) can be locked using `(&setf; (&package-lock; package-or-list) &t;)`. &clisp; locks its system packages (specified in the variable &sys-pack-list;).

### Macro &without-package-lock;

If you want to evaluate some forms with certain packages unlocked, you can use &without-package-lock;
:

    (&without-package-lock; ("LISP" "EXT" "CLOS")
      (defun restart () ...))

or

    (&without-package-lock; ("LISP") (trace read-line))

`(&without-package-lock; () ...)` temporarily unlocks all packages in &sys-pack-list;.

### Discussion - see also the USENET posting by Steven M. Haflich haflich@pacbell.net

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-var;, but only in the interpreted code and during compilation. There is no check for package locks in compiled code because of the performance considerations.

## The COMMON-LISP-USER Package [CLHS-11.1.2.2]

The &clu-pac; package uses the &cl-pac; and &ext-pac; packages.

## Implementation-Defined Packages [CLHS-11.1.2.4]

The following additional packages exist:

### Implementation-Defined Packages

&clos-pac;

  &export;s all &clos;-specific symbols, including some additional symbols.

&sys-pac;

  has the nicknames SYS and COMPILER, and has no &export;ed symbols. It defines many system internals.

&ext-pac;

  is the umbrella package for all extensions: it imports and &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 &cl-pac;): &ldap-pac;, &posix-pac;, &socket-pac;, &gstream-pac;, &gray-pac;, &i18n-pac;, &custom-pac;.

&charset-pac;

  defines and &export;s some character sets, for use with &make-encoding; and as &extfmt; argument.

&ffi-pac;

  implements the foreign function interface. Some platforms only.

&screen-pac;

  defines an API for random screen access. Some platforms only.

All pre-existing packages except &clu-pac; belong to the implementation, in the sense that the programs that do not follow Section 11.1.2.1.2 ("Constraints on the &cl-pac; Package for Conforming Programs") cause undefined behavior.

## The Packages Dictionary [CLHS-11.2]

### Function &make-package;

For &make-package;, the default value of the &use-k; argument is `(&cl-pac;)`.

&make-package; accepts a keyword argument &case-sensitive-k;. Similarly, &defpackage; accepts an option &case-sensitive-k;. 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-var;)`, though.

### Function &re-export;

The function `(&re-export; FROM-PACK TO-PACK)` re-&export;s all external &symbol-t;s from FROM-PACK also from TO-PACK, provided it already uses FROM-PACK; and &signal;s an &error-t; otherwise.

# Numbers [CLHS-12]

## Numeric Types

The type &number-t; is the disjoint union of the types &real-t; and &complex-t; (exhaustive partition)

The type &real-t; is the disjoint union of the types &rational-t; and &float-t;.

The type &rational-t; is the disjoint union of the types &integer-t; and &ratio-t;.

The type &integer-t; is the disjoint union of the types &fixnum-t; and &bignum-t;.

The type &float-t; is the disjoint union of the types &short-float-t;, &single-float-t;, &double-float-t; and &long-float-t;.

## Number Concepts [CLHS-12.1]

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

Byte specifiers are objects of built-in type &byte-t;, not &integer-t;s.

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

When a mathematical function may return an exact (rational) or inexact (floating-point) result, it always returns the exact result.

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

There are four floating point types: &short-float-t;, &single-float-t;, &double-float-t; and &long-float-t;:

type | sign | mantissa | exponent | comment
--- | --- | --- | --- | ---
&short-float-t; | 1 bit | 16+1 bits | 8 bits | immediate
&single-float-t; | 1 bit | 23+1 bits | 8 bits | &ieee-bfp;
&double-float-t; | 1 bit | 52+1 bits | 11 bits | &ieee-bfp;
&long-float-t; | 1 bit | >=64 bits | 32 bits | variable length

The single and double float formats are those of the &ieee-bfp; Standard for Binary Floating-Point Arithmetic, except that &clisp; does not support features like `±0`, `±inf`, `NaN`, gradual underflow, etc. (&cl; does not make use of these features.) This is why &features-var; 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; &lfd-l;. It can be set by `(&setf; (&lfd;) &n-r;)`, where &n-r; is a positive integer. E.g., `(&setf; (&lfd;) 3322)` sets the default precision of long floats to about 1000 decimal digits.

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

The floating point contagion is controlled by the variable &flocont;. When it is non-&nil;, contagion is done as per the &ansi-cl;: &short-float-t; → &single-float-t; → &double-float-t; → &long-float-t;.

Rationale:

  See it pragmatically: save what you can and let others worry about the rest.

Brief:

  &cl; 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; 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 &cl; has no way of knowing the actual accuracy, &ansi-cl; (and all the other standard engineering programming languages, like &c-lang;, 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 &warn-fpc; is for), but one should not be penalized for this too harshly.

When &flocont; 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-t; → &long-float-t; → &double-float-t; → &single-float-t; → &short-float-t; (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-v;) &pi-v;)` 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-t;s, a &long-float-t; (like &pi-v;) 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-t;; furthermore much computation time would be lost by calculating with &long-float-t;s when only &short-float-t;s would be needed.

##### Variable &warn-fpc;

If the variable &warn-fpc; 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 &warn-fpc; 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-v;, to your preferred type). Set it to &error; to have &clisp; &signal; an &error-t; on float precision contagion.

### 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 &zero;, not only `0.0` (which would mean "approximately 0").

The type specifier for this is `(&complex-t; &integer-t; &single-float-t;)`, and `(&complex-t; `type-of-real-part` `type-of-imaginary-part`)` in general.

The type specifier `(&complex-t; &type-r;)` is equivalent to `(&complex-t; &type-r; &type-r;)`.

### 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 &zero;, 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-r; = `#C(0.0 3.0)` - evaluates to `#C(-9.0 0)` = `-9.0`, with &x-r; = `#C(0 3.0)`.

## The Numbers Dictionary [CLHS-12.2]

### Function &upgraded-complex-part-type;

When the argument is not a &recog-subt; or &real-t;, &upgraded-complex-part-type; &signal;s an &error-t;, otherwise it returns &real-t;, since a &complex-t; number in &clisp; can always have &realpart; and &imagpart; of any type.

### Variable &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 &default-float-format;.

### Macro &no-underflow;

The macro `(&no-underflow; {&form-r;}*)` executes the &form-r;s, with errors of type &floating-point-underflow-t; inhibited. Floating point operations will silently return zero instead of &signal;ling an &error-t; of type &floating-point-underflow-t;.

### Additional Integer Functions

#### Function `EXT:!`

`(`EXT:!` &n-r;)` returns the factorial of &n-r;, &n-r; being a nonnegative &integer-t;.

#### Function `EXT:EXQUO`

`(`EXT:EXQUO` &x-r; &y-r;)` returns the integer quotient `x/y` of two integers &x-r;,&y-r;, and &signal;s an &error-t; when the quotient is not integer. (This is more efficient than &slash;.)

#### Function `EXT:XGCD`

`(`EXT:XGCD` &x1-r; ... &xn-r;)` returns the values &l-r;, &k1-r;, ..., &kn-r;, where &l-r; is the greatest common divisor of the integers &x1-r;, ..., &xn-r;, and &k1-r;, ..., &kn-r; are the integer coefficients such that

     &l-r; = (&gcd; &x1-r; ... &xn-r;)
       = (+ (* &k1-r; &x1-r;) ... (* &kn-r; &xn-r;))

### Floating Point

#### Function &expt;

`(&expt; &base-r; exponent)` is not very precise if exponent has a large absolute value.

#### Function &log;

`(&log; &number-r; &base-r;)` &signal;s an &error-t; if `&base-r; = 1`.

#### Constant &pi-v;

The value of &pi-v; is a &long-float-t; with the precision given by &lfd-l;. When this precision is changed, the value of &pi-v; is automatically recomputed. Therefore &pi-v; is &not-e; a &constant;.

### Float Decoding [CLHS]

&float-radix; always returns `2`.

`(&float-digits; &number-r; &digits-r;)` coerces &number-r; (a &real-t; number) to a floating point number with at least &digits-r; mantissa digits. The following always evaluates to &t;:

       (&geq; (&float-digits; (&float-digits; &number-r; &digits-r;)) &digits-r;)

### Boolean Operations [CLHS]

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

### Fixnum Limits [CLHS]

#### Fixnum limits

&cpu-type-header;
&most-positive-fixnum; | 224-1 = 16777215 | 232-1 = 4294967295
&most-negative-fixnum; | -224 = -16777216 | -232 = -4294967296

### Float Limits [CLHS]

Together with &pi-v;, 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 &lfd-l; is &setf;ed. They are &not-e; &constant;s.

### Condition &floating-point-invalid-operation-t;

This &condition-t; is never &signal;ed by &clisp;.

### Condition &floating-point-inexact-t;

This &condition-t; is never &signal;ed by &clisp;.

# Characters [CLHS-13]

The characters are ordered according to a superset of the &charset-ascii;.

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: &dos;, &os2; platforms only, and only in &clisp; built &without; compile-time flag &unicode;.

  More precisely, &clisp; uses the IBM PC character set (code page 437):

  &char-table-header;
  &cc;
  &cc;&cc;&cc;&cc;&cc;&cc;&cc;
  #x00 |  |  |  |  |  |  | ¶ | §
  &cc;&cc;
  #x10 |  |  |  |  |  |  |  |  |  |  |  |  |  |
  &ascii-printable;
  #x80 | Ç | ü | é | â | ä | à | å | ç | ê | ë | è | ï | î | ì | Ä | Å
  #x90 | É | æ | Æ | ô | ö | ò | û | ù | ÿ | Ö | Ü | ¢ | £ | ¥ | ₧ | ƒ
  #xA0 | á | í | ó | ú | ñ | Ñ | ª | º | ¿ | ⌐ | ¬ | ½ | ¼ | ¡ | « | »
  #xB0 | ░ | ▒ | ▓ | │ | ┤ | ╡ | ╢ | ╖ | ╕ | ╣ | ║ | ╗ | ╝ | ╜ | ╛ | ┐
  #xC0 | └ | ┴ | ┬ | ├ | ─ | ┼ | ╞ | ╟ | ╚ | ╔ | ╩ | ╦ | ╠ | ═ | ╬ | ╧
  #xD0 | ╨ | ╤ | ╥ | ╙ | ╘ | ╒ | ╓ | ╛ | ╚ | ┘ | ┌ | █ | ▄ | ▌ | ▐ | ▀
  #xE0 | α | ß | Γ | π | Σ | σ | µ | τ | Φ | Θ | Ω | δ | ∞ | &phgr; | &epsi; | ∩
  #xF0 | ≡ | ± | ≥ | ≤ | ⌠ | ⌡ | ÷ | ≈ | ° | ∙ | · | √ | ⁿ | ² | ■ |

  &char-table-legend;

Platform dependent: &unix; (except &nextstep;), &win32;, &amiga;, &acorn; 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:

  &char-table-header;
  &cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc; &cc;&cc;&cc;&cc;&cc;
  #x00
  &cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc; &cc;&cc;&cc;&cc;&cc;
  #x10
  &ascii-printable;
  #x80 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  #x90 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  #xA0 |  | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ |  | ® | ¯
  #xB0 | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿
  #xC0 | À | Á | Â | Ã | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï
  #xD0 | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß
  #xE0 | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï
  #xF0 | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ

  &char-table-legend;

Platform dependent: &nextstep; platforms only, and only in &clisp; built &without; compile-time flag &unicode;.

  More precisely, &clisp; uses the &nextstep; character set:

  &char-table-header;
  &cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc; &cc;&cc;&cc;&cc;&cc;
  #x00
  &cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc; &cc;&cc;&cc;&cc;&cc;
  #x10
  &ascii-printable;
  #x80 |  | À | Á | Â | Ã | Ä | Å | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï
  #x90 | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | Ù | Ú | Û | Ü | Ý | Þ | µ | × | ÷
  #xA0 | © | ¡ | ¢ | £ | ⁄ | ¥ | ƒ | § | ¤ | ’ | “ | « | ‹ | › | ﬁ | ﬂ
  #xB0 | ® | – | † | ‡ | · | ¦ | ¶ | • | ‚ | „ | ” | » | … | ‰ | ¬ | ¿
  #xC0 | ¹ | ˋ | ´ | ˆ | ˜ | ¯ | ˘ | ˙ | ¨ | ² | ˚ | ¸ | ³ | ˝ | ˛ | ˇ
  #xD0 | — | ± | ¼ | ½ | ¾ | à | á | â | ã | ä | å | ç | è | é | ê | ë
  #xE0 | ì | Æ | í | ª | î | ï | ð | ñ | Ł | Ø | Œ | º | ò | ó | ô | õ
  #xF0 | ö | æ | ù | ú | û | ı | ü | ý | ł | ø | œ | ß | þ | ÿ |  |

  &char-table-legend;

## Standard characters

&char-code-header;
#\Space | #x20
&nl-c; | #x0A

## Semi-standard characters

&char-code-header;
#\Backspace | #x08
#\Tab | #x09
#\Linefeed | #x0A
#\Page | #x0C
&ret-c; | #x0D

&nl-c; is the &line-term;.

## Additional Named Characters

&char-code-header;
#\Null | #x00
#\Bell | #x07
#\Escape | #x1B

## Additional syntax for characters with code from #x00 to #x1F:

&char-code-header;
#\^@ | #x00
#\^A … #\^Z | #x01 … #x1A
#\^[ | #x1B
#\^\ | #x1C
#\^] | #x1D
#\^^ | #x1E
#\^_ | #x1F

See also the section Character I/O.

## Attributes

Characters do not have the &cltl1; font and bits attributes. For backward compatibility, there is a class &input-char; representing either a character with font and bits, or a keystroke. The following functions work with objects of types &character-t; and &input-char;. Note that &eql; or &equal; cannot be used to compare objects of type &input-char;.

`ext:char-font-limit` = 16

  The system uses only font 0.

`ext:char-bits-limit` = 16

  Character bits:

  &key-value-header;
  &control-k; | &ch-ctrl;
  &meta-k; | &ch-meta;
  &super-k; | &ch-super;
  &hyper-k; | &ch-hyper;

`(`ext:char-font` &object-r;)`

  returns the font of a &character-t; or &input-char;.

`(`ext:char-bits` &object-r;)`

  returns the bits of a &character-t; or &input-char;.

`(`ext:make-char` &ch-r; [bits [font]])`

  returns a new &input-char;, or &nil; if such a character cannot be created.

`(`ext:char-bit` &object-r; &name-r;)`

  returns &t; if the named bit is set in &object-r;, else &nil;.

`(`ext:set-char-bit` &object-r; &name-r; newvalue)`

  returns a new &input-char; with the named bit set or unset, depending on the boolean newvalue.

Platform dependent: &unix;, &dos;, &os2;, &win32;, &acorn; platforms only.

  The system itself uses this &input-char; type only to mention special keys and &ctrl;/&alt;/&shift; key status on return from `(&read-char; &kbd-in;)`.

## Character Scripts [CLHS-13.1.2.1]

The only defined character script is the type &character-t; itself.

## Character Attributes [CLHS-13.1.3]

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

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

## Alphabetic Characters [CLHS-13.1.4.2]

The alphabetic characters are those &unicode; characters which are defined as letters by the &unicode; standard.

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

The characters with case are those &unicode; characters &c-r;, for which the upper case mapping &uc-r; and the lower case mapping &lc-r; have the following properties:

- &uc-r; and &lc-r; are different

- &c-r; is one of &uc-r; and &lc-r;

- the upper case mapping of &uc-r; and of &lc-r; is &uc-r;

- the lower case mapping of &uc-r; and of &lc-r; is &lc-r;

The titlecase property of &unicode; characters has no equivalent in &cl;.

## Numeric Characters [CLHS-13.1.4.4]

The numeric characters are those &unicode; characters which are defined as digits by the &unicode; standard.

## Ordering of Characters [CLHS-13.1.6]

The characters are ordered according to their &unicode; code.

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

Newlines are written according to the stream's &encoding;, see the function &stream-external-format; and the description of &encoding;s, in particular, &line-term;s. The default behavior is as follows:

Platform dependent: &dos;, &os2;, &win32; platforms only.

  When writing to a file, &nl-c; is converted to &cr-c;/&lf-c;. (This is the usual convention on &dos;.) For example, &ret-c;+&nl-c; is written as &cr-c;/&cr-c;/&lf-c;.

When reading from a file, &cr-c;/&lf-c; is converted to &nl-c; (the usual convention on &dos;), and &cr-c; not followed by &lf-c; is converted to &nl-c; as well (the usual conversion on MacOS, also used by some programs on &win32;).

## Character Encodings [CLHS-13.1.9]

The integer returned by &char-int; is the same as the character's code.

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

See the description of &encoding;s.

## The Characters Dictionary [CLHS-13.2]

&char-code; takes values from &zero; (inclusive) to &char-code-limit; (exclusive), i.e., the implementation supports exactly &char-code-limit; characters.

### 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-t; are equivalent to &character-t;.

The graphic characters have been described above.

The standard characters are &nl-c; 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.

## Functions on characters

### Function `(&char-width; &ch-r;)`

returns the number of screen columns occupied by &ch-r;. 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 &string-width;.

## Platform-Dependent Characters

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

### Platform dependent characters: &amiga; platforms.

&code-char-header;
`(&code-char; #x00)` | #\Null
`(&code-char; #x01)` | #\Code1
`(&code-char; #x02)` | #\Code2
`(&code-char; #x03)` | #\Code3
`(&code-char; #x04)` | #\Code4
`(&code-char; #x05)` | #\Code5
`(&code-char; #x06)` | #\Code6
`(&code-char; #x07)` | #\Bell | #\Bel
`(&code-char; #x08)` | #\Backspace | #\Bs
`(&code-char; #x09)` | #\Tab | #\Ht
`(&code-char; #x0A)` | &nl-c; | #\Linefeed | #\Lf
`(&code-char; #x0B)` | #\Vt
`(&code-char; #x0C)` | #\Page | #\Ff
`(&code-char; #x0D)` | &ret-c; | #\Cr
`(&code-char; #x0E)` | #\So
`(&code-char; #x0F)` | #\Si
`(&code-char; #x10)` | #\Code16
`(&code-char; #x11)` | #\Code17
`(&code-char; #x12)` | #\Code18
`(&code-char; #x13)` | #\Code19
`(&code-char; #x14)` | #\Code20
`(&code-char; #x15)` | #\Code21
`(&code-char; #x16)` | #\Code22
`(&code-char; #x17)` | #\Code23
`(&code-char; #x18)` | #\Code24
`(&code-char; #x19)` | #\Code25
`(&code-char; #x1A)` | #\Code26
`(&code-char; #x1B)` | #\Escape | #\Esc
`(&code-char; #x1C)` | #\Code28
`(&code-char; #x1D)` | #\Code29
`(&code-char; #x1E)` | #\Code30
`(&code-char; #x1F)` | #\Code31
`(&code-char; #x20)` | #\Space
`(&code-char; #x7F)` | #\Rubout
`(&code-char; #x9B)` | #\Csi

### Platform dependent characters: &dos;, &os2;, &win32; platforms.

&code-char-header;
`(&code-char; #x00)` | #\Null
`(&code-char; #x07)` | #\Bell
`(&code-char; #x08)` | #\Backspace | #\Rubout
`(&code-char; #x09)` | #\Tab
`(&code-char; #x0A)` | &nl-c; | #\Linefeed
`(&code-char; #x0B)` | #\Code11
`(&code-char; #x0C)` | #\Page
`(&code-char; #x0D)` | &ret-c;
`(&code-char; #x1A)` | #\Code26
`(&code-char; #x1B)` | #\Escape
`(&code-char; #x20)` | #\Space

### Platform dependent characters: &unix;, &acorn; platforms.

&code-char-header;
`(&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)` | &nl-c; | #\Nl | #\Linefeed
`(&code-char; #x0B)` | #\Vt
`(&code-char; #x0C)` | #\Page | #\Np
`(&code-char; #x0D)` | &ret-c; | #\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

## Obsolete Constants

### Character bit constants (obsolete)

constant | value
--- | ---
&ch-ctrl; | 1
&ch-meta; | 2
&ch-super; | 4
&ch-hyper; | 8

# Conses [CLHS-14]

## The Conses Dictionary [CLHS-14.2]

### Functions &mapcar;, &mapcan;, &maplist;, &mapcon;, ...

#### Function &mapcap;

The function &mapcap; is like &mapcan;, except that it concatenates the resulting lists with &append; instead of &nconc;:

`(&mapcap; &func-r; &x1-r; ... &xn-r;)` == `(&apply; #'&append; (&mapcar; &func-r; &x1-r; ... &xn-r;))`

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

#### Function &maplap;

The function &maplap; is like &mapcon;, except that it concatenates the resulting lists with &append; instead of &nconc;:

`(&maplap; &func-r; &x1-r; ... &xn-r;)` == `(&apply; #'&append; (&maplist; &func-r; &x1-r; ... &xn-r;))`

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

# Arrays [CLHS-15]

## Function &make-array;

&make-array; can return specialized arrays for the &array-element-type;s `(&unsigned-byte-t; 2)`, `(&unsigned-byte-t; 4)`, &unsigned-byte-8;, &unsigned-byte-16;, &unsigned-byte-32;, and, of course, the required specializations &nil-t;, &bit-t; and &character-t;.

## Array Elements [CLHS-15.1.1]

### Array limits

&cpu-type-header;
&array-rank-limit; | 212 = 4096
&array-dimension-limit; | 224 = 16777216 | 232 = 4294967296
&array-total-size-limit; | 224 = 16777216 | 232 = 4294967296

Note that &array-dimension-limit; and &array-total-size-limit; are not fixnums (they are equal to `(&pl1; &most-positive-fixnum;)`), contrary to the &ansi-cl; Issue ARRAY-DIMENSION-LIMIT-IMPLICATIONS:ALL-FIXNUM.

## 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!

# Strings [CLHS-16]

String comparison is based on the function &char-leq;. Therefore diphthongs do not obey the usual national rules. Example: `o` < `oe` < `z` < `ö`.

## The Strings Dictionary [CLHS-16.2]

### Functions on strings

#### Function &string-width;

`(&string-width; &string-r; &key-amp; &start-r; &end-r;)` returns the number of screen columns occupied by &string-r;. This is computed as the sum of all &char-width;s of all of the &string-r;'s characters.

# Sequences [CLHS-17]

## The Sequences Dictionary [CLHS-17.3]

### Additional Macros

#### Macro &doseq;

For iteration through a sequence, a macro &doseq;, similar to &dolist;, may be used instead of &map-f;:

    (&doseq; (&var-r; seqform [resultform])
      {&declaration-r;}*
      {&tag-r;|&form-r;}*)

&doseq; forms are &iter-form;s.

### Functions &nreverse; & &nreconc;

#### Function &nreverse;

The result of &nreverse; is always &eq; to the argument. &nreverse; on a &vector-t; swaps pairs of elements. &nreverse; on a &list-t; 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.

### 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-t;, the &cdr; parts are modified. If the argument is a &vector-t; with fill pointer, the fill pointer is lowered and the remaining elements are compacted below the new fill pointer.

#### Variable &count-ansi;

Contrary to the &ansi-cl; issue 283 RANGE-OF-COUNT-KEYWORD:NIL-OR-INTEGER, negative &count-k; keyword arguments are not allowed unless you set &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; issue.

### Functions &sort; & &stable-sort;

&sort; and &stable-sort; have two additional keywords &start-k; and &end-k;:

    (&sort; &sequence-r; &pred-r; &key-amp; &key-k; &start-k; &end-k;)
    (&stable-sort; &sequence-r; &pred-r; &key-amp; &key-k; &start-k; &end-k;)

&sort; and &stable-sort; are identical. They implement the mergesort algorithm. Worst case complexity: `O(n*log(n))` comparisons, where &n-r; is the &length; of the subsequence bounded by the &start-k; and &end-k; arguments.

# Hash Tables [CLHS-18]

## The Hash Tables Dictionary [CLHS-18.2]

### Function &make-hash-table;

&make-hash-table; supports additional keywords `:INITIAL-CONTENTS` and `:WEAK`:

    (&make-hash-table; &key-amp; :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-k;
- `:VALUE`
- `:EITHER`
- `:BOTH`

and specifies whether the &hash-table-t; is weak: if the key, value, either or both are not accessible for the &gc;ion purposes, i.e., if they are only accessible via weak &hash-table-t;s and &weak-pointer;s, it is &gc;ed and removed from the weak &hash-table-t;.

The &setf;able predicate `EXT:HASH-TABLE-WEAK-P` checks whether the &hash-table-t; is weak.

Just like &weak-pointer;s, weak &hash-table-t;s cannot be printed readably.

### Macro &defhash;

You can define a new hash table test using the macro &defhash;: `(&defhash; test-name &test-f; &hash-f;)`, after which test-name can be passed as the `:TEST` argument to &make-hash-table;. E.g.:

     (&defhash; string &string-eq; &sxhash;)
     (&make-hash-table; :test 'string)

(which is not too useful because it is equivalent to an &equal; &hash-table-t; but less efficient).

The fundamental requirement is that the &test-f; and &hash-f; are consistent:

      (&funcall; &test-f; &x-r; &y-r;) ==>
      (&areq; (&funcall; &hash-f; &x-r;) (&funcall; &hash-f; &y-r;))

This means that the following definition:

      (&defhash; number &areq; &sxhash;) ; BAD!

is &not-e; correct because `(&areq; 1 1d0)` is &t; but `(&areq; (&sxhash; 1) (&sxhash; 1d0))` is &nil;. The correct way is, e.g.:

      (&defhash; number &areq; (&lambda-m; (x) (&sxhash; (&coerce; x '&short-float-t;))))

(note that `(&coerce; &x-r; &short-float-t;)` does &not-e; cons while `(&coerce; &x-r; &double-float-t;)` does).

### Function &hash-table-test;

Function &hash-table-test; returns either one of the four standard symbols &eq;, &eql;, &equal;, &equalp;, or, for &hash-table-t;s created with a user-defined &hash-table-test; (see macro &defhash;), a &cons-t; cell `(&test-f; . &hash-f;)`.

### Macro &dohash;

For iteration through a &hash-table-t;, a macro &dohash;, similar to &dolist;, can be used instead of &maphash;:

    (&dohash; (key-var value-var hash-table-form [resultform])
      {&declaration-r;}*
      {&tag-r;|&form-r;}*)

&dohash; forms are &iter-form;s.

# Filenames [CLHS-19]

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

Platform dependent: &unix;, &amiga; platforms only.

  For example, `#P"foo/bar"` denotes the file &bar-f; in the directory &foo-f;, while `#P"foo/bar/"` denotes the subdirectory &bar-f; of the directory &foo-f;.

Platform dependent: &dos;, &os2;, &win32; platforms only.

  For example, `#P"foo\\bar"` denotes the file &bar-f; in the directory &foo-f;, while `#P"foo\\bar\\"` denotes the subdirectory &bar-f; of the directory &foo-f;.

Platform dependent: &acorn; platforms only.

  For example, `#P"foo.bar"` denotes the file &foo-f; in the directory &bar-f;, while `#P"foo.bar."` denotes the subdirectory &bar-f; of the directory &foo-f;.

Platform dependent: &win32; and &cygwin; platforms only.

  User variable &dev-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 &config-file; to change it.

This is especially important for the directory-handling functions.

## 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 &parsedot;.

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.

## Pathname Components [CLHS-19.2.1]

When a pathname is to be fully specified (no wildcards), that means that no &wild-k;, &wild-inferiors-k; is allowed, no wildcard characters are allowed in the strings, and &name-r; &eq; &nil; may not be allowed either.

Platform dependent: &amiga; platforms only.
  &path-comps;
  &host-r;
  &always-nil;
  &device-r;
  &string-or-nil; &dir-term;

    &elt-val-meaning-header;
    &startp-rel-abs; &subdirs-def; &subdir-string-or-wild;
    &subdir-r; | &parent-k; | &file-slash; instead of `"subdir/"`

  &name-r;
  &wild-string-or-nil;
  &type-r;
  &wild-string-or-nil;
  &version-nil;

  Constraint: &startpoint-r; = &relative-k; only if &device-r; is &nil;. If the device is specified, the pathname must be absolute!

  An &amiga; &name-type-split;

  Case is ignored in the strings on comparison. No case conversions are performed.

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

  ### Formal specification of the external notation

  ch ::==

    any character except ':','/' and '*','?'

  name ::==

    {ch}+

  device ::==

    [ <empty> | ':' | name ':' ]

    empty | current device, relative to current directory
    ':' | current device, absolute (relative to root for disks)
    name ':' | specified device, absolute (relative to root for disks)

  subdir ::==

    [ <empty> | name ]

    empty | parent directory

  pathname ::==

    device { subdir '/' }* name

  Examples:

  String | Device | Directory | our pathname
  --- | --- | --- | ---
  `"c:foo"` | 'C' | `"device->foo"` | `"c"` (&absolute-k; &foo-f;)
  `"c:foo/"` | 'C' | `"device->foo"` | `"c"` (&absolute-k; &foo-f;)
  `"c:foo/bar"` | 'C' | `"device->foo->bar"` | `"c"` (&absolute-k; &foo-f; &bar-f;)
  `"c:/foo"` | 'C' | `"device->up->foo"` | `"c"` (&absolute-k; &parent-k; &foo-f;)
  `"c:"` | 'C' | `"device"` | `"c"` (&absolute-k;)
  `":foo"` | current | `"device->root->foo"` | &nil; (&absolute-k; &foo-f;)
  &foo-f; | current | `"device->foo"` | &nil; (&relative-k; &foo-f;)
  `"/foo"` | current | `"device->up->foo"` | &nil; (&relative-k; &parent-k; &foo-f;)
  `"//foo/bar"` | current | `"device->up->up->foo->bar"` | &nil; (&relative-k; &parent-k; &parent-k; &foo-f; &bar-f;)
  &file-bsla; | current | `"device"` | &nil; (&relative-k;)

  Appending a &file-slash; to a path string that is non-empty and does not end with &file-colon; or &file-slash; does not change its meaning. This &file-slash; must be appended before another non-empty component can be appended. But appending a &file-slash; to a path string that is empty or ends with &file-colon; or &file-slash; means going up to the parent directory!

  We interpret any path string that is empty or ends with &file-colon; or &file-slash; as pathname of a directory (with both &name-r; and &type-r; being &nil;).

Platform dependent: &unix; platforms only.
  &path-comps;
  &host-r;
  &always-nil;
  &device-r;
  &always-nil; &dir-term;

    &elt-val-meaning-header;
    &startp-rel-abs; &subdirs-def; &subdir-string-or-wild;

  &name-r;
  &wild-string-or-nil;
  &type-r;
  &wild-string-or-nil;
  &version-nil;

  A &unix; &name-type-split;

  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: &os2; platforms only.
  &path-comps;
  &host-r;
  &always-nil;
  &device-r;

    &nil; or &wild-k; or &file-letter-uc;

  &dir-term;

    &elt-val-meaning-header;
    &startp-rel-abs; &subdirs-def; &subdir-string-or-wild;

  &name-r;
  &wild-string-or-nil;
  &type-r;
  &wild-string-or-nil;
  &version-nil;

  An &os2; &name-type-split;

  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 &file-bsla; one may use &file-slash;, as usual for &dos; calls.

Platform dependent: &win32; platforms only.
  &path-comps;
  &host-r;

    &nil; or &simple-string-t;, wildcard characters may occur but do not act as wildcards

  &device-r;

    &nil; or &wild-k; or &file-letter-uc;

  &dir-term;

    &elt-val-meaning-header;
    &startp-rel-abs; &subdirs-def; &subdir-string-or-wild;

  &name-r;
  &wild-string-or-nil;
  &type-r;
  &wild-string-or-nil;
  &version-nil;

  If &host-r; is non-&nil;, &device-r; must be &nil;.

  A &win32; &name-type-split;

  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 &file-bsla; one may use &file-slash;, as usual for DOS calls.

  If &host-r; is non-&nil; and the &directory-r;'s &startpoint-r; is not &absolute-k;, `(&parse-namestring; (&namestring; &path-r;))` will not be the same as &path-r;.

Platform dependent: &unix;, &amiga;, &os2;, &win32; platforms only.

  The wildcard characters: &file-star; matches any sequence of characters, &file-ques; matches any one character.

### Name/type namestring split.

Platform dependent: &unix;, &amiga;, &os2;, &win32; platforms only.

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

  - if there is no &file-dot; in the filename, then the &name-r; is everything, &type-r; is &nil;;

  - if there is a &file-dot;, then &name-r; is the part before and &type-r; the part after the last dot.

  - if the only &file-dot; is the first character, then the behavior depends on the value of the user variable &parsedot; which can be either

    &type-k;

      &nil; &name-r;, everything after the &file-dot; is the &type-r;; or

    &name-k;

      &nil; &type-r;, everything is the &name-r;

  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-k; "foo.bar")`.

Platform dependent: &acorn; platforms only.

  RISC OS provides several file systems as standard (ADFS, IDEFS, NetFS, RamFS, NetPrint) and support for extra file systems (DOSFS, ResourceFS and DeviceFS).

  A module called FileSwitch is at the center of all file system operation in RISC OS. FileSwitch provides a common core of functions used by all file systems. It only provides the parts of these services that are device independent. The device dependent services that control the hardware are provided by separate modules, which are the actual file systems. FileSwitch keeps track of active file systems and switches between them as necessary.

  One of the file system modules that RISC OS provides is FileCore. It takes the normal calls that FileSwitch sends to a file system module, and converts them to a simpler set of calls to modules that control the hardware. Unlike FileSwitch it creates a fresh instantiation of itself for each module that it supports. Using FileCore to build file system modules imposes a more rigid structure on it, as more of the file system is predefined.

  As well as standard file systems, FileSwitch supports image file systems. These provide facilities for RISC OS to handle media in foreign formats, and to support `image files' (or partitions) in those formats. Rather than accessing the hardware directly they rely on standard RISC OS file systems to do so. DOSFS is an example of an image file system used to handle DOS format discs.

  Terminology

    A pathname may include a file system name, a special field, a media name (e.g., a disc name), directory name(s), and the name of the object itself; each of these parts of a pathname is known as an `element' of the pathname.

  Filenames

    Filename `elements' may be up to ten characters in length on FileCore-based file systems and on NetFS. These characters may be digits or letters. FileSwitch makes no distinction between upper and lower case, although file systems can do so. As a general rule, you should not use top-bit-set characters in filenames, although some file systems (such as FileCore-based ones) support them. Other characters may be used provided they do not have a special significance. Those that do are listed below:

    &file-dot;

      Separates directory specifications, e.g., `"$.fred"`

    &file-colon;

      Introduces a drive or disc specification, e.g., `":0"`, `":bigdisc"`. It also marks the end of a file system name, e.g., `"adfs:"`

    &file-star;

      Acts as a `wildcard' to match zero or more characters.

    &file-hash;

      Acts as a `wildcard' to match any single character.

    &file-doll;

      is the name of the root directory of the disc.

    `"&"`

      is the user root directory (URD)

    `"@"`

      is the currently selected directory (CSD)

    `"^"`

      is the `parent' directory

    `"%"`

      is the currently selected library (CSL)

    &file-bsla;

      is the previously selected directory (PSD)

  Directories

    The root directory, &file-doll;, forms the top of the directory hierarchy of the media which contains the CSD. &file-doll; does not have a parent directory, trying to access its parent will just access &file-doll;. Each directory name is separated by a &file-dot; character. For example:

    - `"$.Documents.Memos"`

    - `"%.cc"`

  File Systems

    Files may also be accessed on file systems other than the current one by prefixing the filename with a file system specification. A file system name may appear between &file-dash; characters, or suffixed by a &file-colon;, though the latter is advised since &file-dash; can also be used to introduce a parameter on a command line, or as part of a file name. For example:

    - `"-net-$.SystemMesg"`

    - `"adfs:%.aasm"`

  Special Fields

    Special fields are used to supply more information to the file system than you can using standard path names; for example NetFS and NetPrint use them to specify server addresses or names. They are introduced by a &file-hash; character; a variety of syntaxes are possible:

    - `"net#MJHardy::disc1.mike"`

    - `"#MJHardy::disc1.mike"`

    - `"-net#MJHardy-:disc1.mike"`

    - `"-#MJHardy-:disc1.mike"`

    The special fields here are all MJHardy, and give the name of the fileserver to use. Special fields may use any character except for control characters, double quote '"', solidus '|' and space. If a special field contains a hyphen you may only use the first two syntaxes given above.

  `"File$Path"` and `"Run$Path"`

    These two special variables control exactly where a file will be looked for, according to the operation being performed on it.

    name | purpose
    --- | ---
    File$Path | for read operations
    Run$Path | for execute operations

    The contents of each variable should expand to a list or prefixes, separated by commas. When a read operation is performed then the prefixes in `"File$Path"` are used in the order in which they are listed. The first object that matches is used, whether it be a file or directory. Similarly any execute operation uses the prefixes in Run$Path. These search paths are only used when the pathname does not contain an explicit file system reference, e.g., executing `"adfs:file"` will not use `"Run$Path"`.

  Other path variables

    You can set up other path variables and use them as pseudo file systems. For example if you typed:

        *Set Source$Path adfs:$.src.,adfs:$.public.src.

    , you could then refer to the pseudo file system as `"Source:"` or (less preferable) as `"-Source-"`. These path variables work in the same was as `"File$Path"` and `"Run$Path"`.

    NOTE: Path variables are not implemented in this version of &clisp;. A workaround for this is to use "<Foo$Path>" instead of "Foo:" until they are made available.

  from Lisp-string notation to internal representation

    No swapping. &foolisp-f; means file type &lisp-file; and file name &foo-f;. This is pseudo-BNF:

    legal character ::==

      any ISO latin-1 graphic character ≥ ' ' except '.' ':' '*' '#' '$' '&' '@' '^' '%' '\' '?'

    extended legal character ::==

      any ISO latin-1 graphic character ≥ ' ' except ':' '"' '|'

    legal-wild char ::==

      legal char | '*' | '#' | '?'

    host ::==

      '-' { extended legal char except '-' }+ '-' | { extended legal char except '-' } { extended legal char }* ':' | empty

    device ::==

      ':' { legal char }+ '.' | empty

    directory ::==

      { '$' | '&' | '@' | '%' | '\' } '.' { subdirectory }* | { subdirectory }+ | empty

      '$' -> | &absolute-k; &root-k;
      '&' -> | &absolute-k; &home-k;
      '@' -> | &absolute-k; &current-k;
      '%' -> | &absolute-k; &library-k;
      '\' -> | &absolute-k; &previous-k;
      else | &relative-k;

    subdirectory ::==

      { '^' | { legal-wild char }+ } '.'

      '^' -> | &parent-k;

    filename ::==

      { { legal-wild char }+ | empty }

    filetype ::==

      { '.' { legal-wild char }+ | empty }

    pathname ::==

      host device directory filename filetype

    Examples:

    String | Hostname | Device | Directory | Name | Type
    --- | --- | --- | --- | --- | ---
    `"-net-$.SystemMesg"` | `"net"` | &nil; | `(&absolute-k; &root-k;)` | `"SystemMesg"` | &nil;
    `"net#MJHardy::disc1.mike"` | `"net#MJHardy"` | `"disc1"` | `(&absolute-k; &root-k;)` | `"mike"` | &nil;
    `"#MJHardy::disc1.mike"` | `"#MJHardy"` | `"disc1"` | `(&absolute-k; &root-k;)` | `"mike"` | &nil;
    `"-net#MJHardy-:disc1.mike"` | `"net#MJHardy"` | `"disc1"` | `(&absolute-k; &root-k;)` | `"mike"` | &nil;
    `"-#MJHardy-:disc1.mike"` | `"#MJHardy"` | `"disc1"` | `(&absolute-k; &root-k;)` | `"mike"` | &nil;
    `"@.foo"` | &nil; | &nil; | `(&absolute-k; &current-k;)` | &foo-f; | &nil;
    &foo-f; | &nil; | &nil; | `(&relative-k;)` | &foo-f; | &nil;
    `"^."` | &nil; | &nil; | `(&relative-k; &parent-k;)` | &nil; | &nil;
    `"@.^."` | &nil; | &nil; | `(&absolute-k; &current-k; &parent-k;)` | &nil; | &nil;
    `"foo.bar"` | &nil; | &nil; | `(&relative-k;)` | &foo-f; | &bar-f;
    `"foo.bar.baz"` | &nil; | &nil; | `(&relative-k; &foo-f;)` | &bar-f; | `"baz"`
    `"foo.bar."` | &nil; | &nil; | `(&relative-k; &foo-f; &bar-f;)` | &nil; | &nil;
    `"foo.@."` | illegal |  |  |  |

  From internal representation to RISCOS string

    with swapping only of name/type components.

    Hostname | Device | Directory | Name | Type | RISCOS String
    --- | --- | --- | --- | --- | ---
    `"net"` | `"disc1"` | `(&absolute-k; &root-k;)` | &foo-f; | &nil; | `"net::disc1.$.foo"`
    `"net#MJ"` | `"disc1"` | `(&absolute-k; &root-k; &foo-f;)` | &bar-f; | `"baz"` | `"net#MJ::disc1.$.foo.baz.bar"`
    `"adfs"` | `"4"` | `(&absolute-k; &root-k; &foo-f; &bar-f;)` | &nil; | &nil; | `"adfs::4.$.foo.bar"`
    &nil; | `"disc1"` | `(&absolute-k; &root-k; &foo-f;)` | &bar-f; | &nil; | `":disc1.$.foo.bar"`
    &nil; | `"disc1"` | `(&absolute-k; &current-k;)` | &nil; | &nil; | illegal here
    &nil; | `"disc1"` | `(&relative-k;)` | &nil; | &nil; | `":disc1."`
    &nil; | `"disc1"` | &nil; | &nil; | &nil; | `":disc1."`
    &nil; | &nil; | `(&absolute-k; &root-k;)` | &foo-f; | &nil; | `"$.foo"`
    &nil; | &nil; | `(&absolute-k; &current-k;)` | &foo-f; | &nil; | `"@.foo"`
    &nil; | &nil; | `(&relative-k;)` | &foo-f; | &bar-f; | `"bar.foo"`
    &nil; | &nil; | `(&relative-k; &foo-f;)` | &bar-f; | `"baz"` | `"foo.baz.bar"`
    &nil; | &nil; | `(&absolute-k; &library-k;)` | &bar-f; | &nil; | `"%.bar"`
    &nil; | &nil; | `(&absolute-k; &library-k; &foo-f;)` | &bar-f; | &nil; | `"%.foo.bar"`
    &nil; | &nil; | `(&relative-k;)` | &foo-f; | &bar-f; | `"bar.foo"`
    &nil; | &nil; | `(&relative-k; &foo-f;)` | &bar-f; | &nil; | `"foo.bar"`
    &nil; | &nil; | `(&relative-k; &foo-f;)` | &nil; | &bar-f; | illegal here

    That is, the RISCOS string is the flattening-concatenation of

          (append
            (if (null hostname) "" (append hostname ":"))
            (if (null device) "" (append ":" device "."))
            (case (pop directory)
              (:absolute (case (pop directory)
                                 (:root "$.")
                                 (:home "&.")
                                 (:current "@.")
                                 (:library "%.")
                                 (:previous "\\.")))
              (:relative ""))
            (mapcar (lambda (subdir) (append subdir ".")) directory)
            (if (null name)
                (if (null type) "" (error "type with name illegal here"))
                (if (null type)
                    name
                    (append type "." name))))

  internal representation
    &path-comps;
    &host-r;
    &string-or-nil;
    &device-r;
    &string-or-nil; &dir-term;

      element | values
      --- | ---
      &startpoint-r; | &relative-k; | &absolute-k; anchor
      anchor | &root-k; | &home-k; | &current-k; | &library-k; | &previous-k;
      &subdirs-def;
      &subdir-r; | &parent-k;
      &subdir-r; | &simple-string-t;, may contain wildcard characters &file-ques;, &file-hash; and &file-star;

    &name-r;

      &simple-string-t; or &nil;, may contain wildcard characters &file-ques;,&file-hash; and &file-star; (may also be specified as &wild-k;)

    &type-r;

      &nil; or &simple-string-t;, may contain wildcard characters &file-ques;,&file-hash; and &file-star; (may also be specified as &wild-k;)

    &version-nil;

    Constraint: &startpoint-r; is not &absolute-k; &root-k; only if device is &nil;. If the device is specified, the pathname must be &absolute-k; &root-k;.

    The wildcard characters: &file-star; matches any sequence of characters, &file-hash; or &file-ques; matches any one character.

    Due to the name/type swapping rule, there are pathnames that cannot result from &parse-namestring;. To get a pathname whose type is &nil;, &make-pathname; must be used. Example: `(&make-pathname; :directory "!Clisp." &name-k; "README")`.

## :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;.

## External notation.

External notation of pathnames (cf. &parse-namestring; and &namestring;), of course without spaces, [,],{,}:

Platform dependent: &dos; platforms only.

  [ [drivespec] : ] | a letter &file-star;|&file-letter-lc;|&file-letter-uc;
  { name [. type] \ } | each one a subdirectory, &file-bsla; may be replaced by &file-slash;
  [ name [. type] ] | filename with type (extension)

  Name and type may be &string-t;s of any &length; (consisting of alphanumeric characters and &file-dash;, `"_"`). They are shortened to 8 (respectively 3) characters and converted to upper case. A single &file-star; is allowed for &wild-k;.

Platform dependent: &amiga; platforms only.

  see above.

Platform dependent: &unix; platforms only.

  [ &file-slash; ] | &file-slash; denotes absolute pathnames
  { &name-r; &file-slash; } | each one a subdirectory
  [ &name-r; [&file-dot; &type-r;] ] | filename with type (extension)

  Name and type may be &string-t;s of any &length; (consisting of printing &ascii; characters, except &file-slash;).

Platform dependent: &os2;, &win32; platforms only.

  [ [drivespec] : ] | a letter &file-star;|&file-letter-lc;|&file-letter-uc;
  { &name-r; [. &type-r;] \ } | each one a subdirectory, &file-bsla; may be replaced by &file-slash;
  [ &name-r; [. &type-r;] ] | filename with type (extension)

  Name and type may be &string-t;s of any &length; (consisting of printing &ascii; characters, except &file-slash;, &file-bsla;, &file-colon;).

Platform dependent: &acorn; platforms only.

  see above.

&namestring; has an optional flag argument: `(&namestring; &path-r; &t;)` returns an external notation suitable for passing to the operating system or other programs.

Platform dependent: &dos;, &os2;, &amiga; platforms only.

  The function &user-homedir-pathname; is not implemented.

Platform dependent: &dos;, &os2; platforms only.

  If you really need that function, you can define it like this:

      (defun user-homedir-pathname (&optional-amp; host)
        (declare (ignore host))
        (or (&getenv; "HOME") "\\"))

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

## The Filenames Dictionary [CLHS-19.4]

### Pathname Designators

When &parsename; is &nil;, &symbol-t; 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.

### Function &translate-pathname;

&translate-pathname; has two additional keywords: `(&translate-pathname; &source-r; from-wildname to-wildname &key-amp; &all-k; &merge-k;)`

If &all-k; is specified and non-&nil;, a list of all resulting pathnames, corresponding to all matches of `(&pathname-match-p; &source-r; from-wildname)`, is returned. If &merge-k; is specified and &nil;, unspecified pieces of to-pathname are not replaced by corresponding pieces of &source-r;.

### Function &parse-namestring;

`(&parse-namestring; &string-r; &optional-amp; &host-r; &defaults-r; &key-amp; &start-r; &end-r; junk-allowed)` returns a logical pathname only if &host-r; is a logical host or &host-r; is &nil; and &defaults-r; is a &logical-pathname-t;. To construct a logical pathname from a string, the function &logical-pathname; can be used.

The &ansi-cl; behavior of recognizing logical pathnames when the &string-r; 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; behavior, you should set &parsename; to non-&nil;.

### Function &merge-pathnames;

`(&merge-pathnames; &path-r; [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 &path-r; and default-pathname are relative pathnames, the behavior depends on &pathmerge;: 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-m; a b)`. Obviously, putting in the same default a second time should do the same as putting it in once: `(&or-m; a b b)` is the same as `(&or-m; 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 &cl; 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 &pathmerge; is &nil;), but not in implementations that strictly follow the &ansi-cl; spec. In fact, the above twice-default = once-default rule holds for all pathnames in &clisp;.

Reversely, when &pathmerge; is non-&nil;, the normal &ansi-cl; behavior is exhibited: `(&merge-pathnames; #P"x/" #P"y/")` evaluates to `#P"y/x/"`.

#### Rationale

merge is merge and not or.

### Function &load-logical-pathname-translations;

When the &host-r; argument to &load-logical-pathname-translations; is not a defined logical host yet, we proceed as follows:

1. If both &env-var;s `LOGICAL_HOST_&host-r;_FROM` and `LOGICAL_HOST_&host-r;_TO` exist, then their values define the map of the &host-r;.

2. If the &env-var; `LOGICAL_HOST_&host-r;` exists, its value is read from, and the result is passed to `(&setf; &logical-pathname-translations;)`.

3. Variable &load-lpt-db; is consulted. Its value should be a list of files and/or directories, which are searched for in the &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-r;` or `&host-r;.host`, in that directory, is &read; from once, CMUCL-style, the object read being the &logical-pathname-translations; of the &host-r;.

# Files [CLHS-20]

## 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 &probe-dir; 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 &cl; 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 &probe-dir;

`(&probe-dir; &path-r;)` tests whether &path-r; exists and is a directory. It will, unlike &probe-file; or &truename;, not &signal; an &error-t; if the parent directory of &path-r; does not exist.

### Function &delete-file;

`(&delete-file; &path-r;)` deletes the pathname &path-r;, not its &truename;, and returns the absolute pathname it actually removed or &nil; if &path-r; did not exist. When &path-r; points to a file which is currently open in &clisp;, an &error-t; is &signal;led.

### Function &directory;

`(&directory; &optional-amp; &path-r; &key-amp; :FULL :CIRCLE &if-does-not-exist;)` can run in two modes:

- If &path-r; 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-k;

  &signal; an &error-t; on bad directory entries (this corresponds to the default behavior of &directory; in &cmucl;)

`:KEEP`

  keep bad directory entries in the returned list (this roughly corresponds to the `(&directory; ... `:TRUNAMEP` &nil;)` call in &cmucl;)

`:IGNORE`

  Similar to `:DISCARD`, but also do not signal an error when a directory is unaccessible (contrary to the &ansi-cl; specification).

#### Function `EXT:DIR`

`(`EXT:DIR` &optional-amp; &path-r;)` is like &directory;, but displays the pathnames instead of returning them. `(EXT:DIR)` shows the contents of the current directory.

#### Function &cd;

`(&cd; &path-r;)` sets it, `(&cd;)` returns it.

Platform dependent: &unix;, &amiga; platforms only.

  `(&cd; [&path-r;])` manages the current directory.

Platform dependent: &acorn; platforms only.

  `(&cd; [&path-r;])` manages the current host, current device and the current directory.

Platform dependent: &dos;, &os2;, &win32; platforms only.

  `(&cd; [&path-r;])` manages the current device and the current directory.

#### Function `EXT:DEFAULT-DIRECTORY`

`(`EXT:DEFAULT-DIRECTORY`)` is equivalent to `(&cd;)`. `(&setf; (`EXT:DEFAULT-DIRECTORY`) &path-r;)` is equivalent to `(&cd; &path-r;)`, 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.

# Streams [CLHS-21]

## Interactive Streams [CLHS-21.1.1.1.3]

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

## Terminal interaction.

### &readline;

Platform dependent: &unix;, &dos;, &os2; platforms only, and only in &clisp; built &without; compile-time flag &noreadline; (and when &readline; is installed on your machine already).

  Input through &terminal-io-var; uses the &readline; library. Arrow keys can be used to move within the input history. The #\Tab key completes the &symbol-t; name or &pathname-t; that is being typed. See readline user manual for general details and CLISP manual for &clisp;-specific extensions. The &readline; library is not used if standard input and standard output do not both refer to the same terminal.

### Macro &with-kbd;

Platform dependent: &unix;, &amiga;, &acorn;, &dos;, &os2;, &win32; platforms only.

  &terminal-io-var; is not the only stream that communicates directly with the user: During execution of the body of a `(&with-kbd; . &body-r;)` form, &kbd-in; is the stream that reads the keystrokes from the keyboard. It returns every keystroke in detail, as &character-t; or &input-char; with the following bits:

  `:hyper`

    (Platform dependent: &dos;, &os2;, &win32;, &amiga; platforms only.) if a non-standard key. These keys are: [&dos;, &os2;, &win32;]: Function keys, cursor keypads, numeric keypad. [&amiga;]:Function keys, cursor keypad.

  slot key

    the key name, for non-standard keys:

    Platform dependent: &dos;, &os2; platforms only.

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

    Platform dependent: &unix;, &win32; platforms only.

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

    Platform dependent: &amiga; platforms only.

      &key-value-header;
      F1..F10 | `:F1`..`:F10`
      Help | `:Help`
      Arrow keys | `:Left``:Right` `:Up``:Down`

  slot &ch-r;

    the &ascii; code for standard keys

  `:super`

    (Platform dependent: &dos;, &os2;, &win32;, &amiga; 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 &ctrl; key.

  `:meta`

    (Platform dependent: &dos;, &os2;, &win32; platforms only.) if pressed together with the &alt; key.

  This keyboard input is not echoed on the screen. During execution of a `(&with-kbd; . &body-r;)` form, no input from &terminal-io-var; or any synonymous stream should be requested.

See also Random Screen Access.

## The Streams Dictionary [CLHS-21.2]

### Function &stream-element-type;

&stream-element-type; is &setf;able. The &stream-element-type; of &stream-t;s created by the functions &open;, &mk-pipe-in; &mk-pipe-out;, &mk-pipe-io;, &so-accept;, &so-connect; can be modified, if the old and the new &stream-element-type;s are either

- both equivalent to &character-t; or &unsigned-byte-8; or &signed-byte-8;; or

- both equivalent to &unsigned-byte-n; or &signed-byte-n;, with the same &n-r;.

Functions &stream-element-type; and `(&setf; &stream-element-type;)` are &generic-function-t;s, see section "Gray streams".

#### Binary input from &standard-input-var;

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-var;. Since &standard-input-var; normally is a &synonym-stream-t; pointing to &terminal-io-var;, 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-e; send you an &eos; on the end of the data, you will need to use `(&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-t; 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; (&getenv; "CONTENT_LENGTH"))
                           :element-type &unsigned-byte-8;)))
      (&with-open-stream; (in (&make-stream; &input-k; &eltype; &unsigned-byte-8;))
        (&read-sequence; buf in))
      buf)

### Function &make-stream;

Function &make-stream; creates a Lisp stream out of an OS file handle: `(&make-stream; &object-r; &direction-k; &eltype; &extfmt; &buffered;)`

&object-r; designates an OS handle (a &file-des;), and should be one of the following:

number

  denotes the &file-des; of this value

&input-k;

  denotes &clisp; process standard input

&output-k;

  denotes &clisp; process standard output

&error-k;

  denotes &clisp; process standard error

&stream-t;

  denotes the handle of this stream, which should be a &file-stream-t; or a &socket-stream;

The handle is duplicated (with &dup;), so it is safe to &close; a &stream-t; returned by &make-stream;.

### Binary input, &read-byte;, &rd-integer; & &rd-float;

The function `(&rd-integer; &stream-r; &eltype-r; &optional-amp; &endianness; &eof-ep; &eof-v;)` reads a multi-byte &integer-t; from &stream-r;. &stream-r; should be a stream with &stream-element-type; &unsigned-byte-8;. &eltype-r; should be &type-eq; to &unsigned-byte-n;, where &n-r; is a multiple of 8.

`(&rd-integer; &stream-r; &eltype-r;)` is like `(&read-byte; &stream-r;)` if &stream-r;'s &stream-element-type; were set to &eltype-r;, except that &stream-r;'s &file-position; will increase by &n-r;/8 instead of 1.

Together with `(&setf; &stream-element-type;)`, this function permits mixed character/binary input from a stream.

The function `(&rd-float; &stream-r; &eltype-r; &optional-amp; &endianness; &eof-ep; &eof-v;)` reads a floating-point number in &ieee-bfp; binary representation from &stream-r;. &stream-r; should be a &stream-t; with &stream-element-type; &unsigned-byte-8;. &eltype-r; should be &type-eq; to &single-float-t; or &double-float-t;.

#### Endianness

&endianness; can be `:LITTLE` or `:BIG`. The default is `:LITTLE`, which corresponds to the &read-byte; behavior in &clisp;.

### Binary output, &write-byte;, &wr-integer; & &wr-float;

The function `(&wr-integer; &int-r; &stream-r; &eltype-r; &optional-amp; &endianness;)` writes a multi-byte integer to &stream-r;. &stream-r; should be a &stream-t; with &stream-element-type; &unsigned-byte-8;. &eltype-r; should be &type-eq; to &unsigned-byte-n;, where &n-r; is a multiple of 8.

`(&wr-integer; &int-r; &stream-r; &eltype-r;)` is like `(&write-byte; &int-r; &stream-r;)` if &stream-r;'s &stream-element-type; were set to &eltype-r;, except that &stream-r;'s &file-position; will increase by &n-r;/8 instead of 1.

Together with `(&setf; &stream-element-type;)`, this function permits mixed character/binary output to a &stream-t;.

The function `(&wr-float; float &stream-r; &eltype-r; &optional-amp; &endianness;)` writes a floating-point number in &ieee-bfp; binary representation to &stream-r;. &stream-r; should be a &stream-t; with &stream-element-type; &unsigned-byte-8;. &eltype-r; should be &type-eq; to &single-float-t; or &double-float-t;.

### Bulk Input and Output

#### Function &read-sequence;

In addition to &read-sequence;, the following two functions are provided:

&rd-by-seq; performs multiple &read-byte; operations:

  `(&rd-by-seq; &sequence-r; &stream-r; &key-amp; &start-k; &end-k; :NO-HANG)` fills the subsequence of &sequence-r; specified by &start-k; and &end-k; with &integer-t;s consecutively read from &stream-r;. It returns the index of the first element of &sequence-r; that was not updated (= &end-r; or < &end-r; if the &stream-r; reached its end). When `:NO-HANG` is non-&nil;, does not block: treat input unavailability as &eos;.

  This function is especially efficient if &sequence-r; is a &unsigned-byte-vec; and &stream-r; is a &file-pipe-socket; &stream-t; with &stream-element-type; &unsigned-byte-8;.

&rd-ch-seq; performs multiple &read-char; operations:

  `(&rd-ch-seq; &sequence-r; &stream-r; &key-amp; &start-k; &end-k;)` fills the subsequence of &sequence-r; specified by &start-k; and &end-k; with characters consecutively read from &stream-r;. It returns the index of the first element of &sequence-r; that was not updated (= &end-r; or < &end-r; if the &stream-r; reached its end).

  This function is especially efficient if &sequence-r; is a &string-t; and &stream-k; is a &file-pipe-socket; stream with &stream-element-type; &character-t; or an input &string-stream-t;.

#### Function &write-sequence;

In addition to &write-sequence;, the following two functions are provided:

&wr-by-seq; performs multiple &write-byte; operations:

  `(&wr-by-seq; &sequence-r; &stream-r; &key-amp; &start-k; &end-k;)` outputs the &integer-t;s of the subsequence of &sequence-r; specified by &start-k; and &end-k; to &stream-k;. It returns &sequence-r;.

  This function is especially efficient if &sequence-r; is a &unsigned-byte-vec; and &stream-r; is a &file-pipe-socket; &stream-t; with &stream-element-type; &unsigned-byte-8;.

&wr-ch-seq; performs multiple &write-char; operations:

  `(&wr-ch-seq; &sequence-r; &stream-r; &key-amp; &start-k; &end-k;)` outputs the characters of the subsequence of &sequence-r; specified by &start-k; and &end-k; to &stream-k;. It returns &sequence-r;.

  This function is especially efficient if &sequence-r; is a &string-t; and &stream-k; is a &file-pipe-socket; &stream-t; with &stream-element-type; &character-t;.

#### Rationale

The rationale for &rd-ch-seq;, &rd-by-seq;, &wr-ch-seq; and &wr-by-seq; is that some &stream-t;s support both character and binary i/o, and when you read into a &sequence-t; that can hold both (e.g., &list-t; or &simple-vector-t;) you cannot determine which kind of input to use. In such situation &read-sequence; and &write-sequence; &signal; an &error-t;, while &rd-ch-seq;, &rd-by-seq;, &wr-ch-seq; and &wr-by-seq; work just fine.

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

`(&rcwhp; &stream-r;)`

  &rcwhp; 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-f; (&listen; &stream-r;))`: When the &eos; is reached, &listen; returns &nil;, whereas &rcwhp; returns &nil;.

  Note also that &rcwhp; is not a good way to test for &eos;: If &rcwhp; returns &t;, this does not mean that the &stream-r; will deliver more characters. It only means that it is not known at this moment whether the &stream-r; is already at &eos;, or will deliver more characters.

`(&rbla; &stream-r;)`

  To be called only if &stream-r;'s &stream-element-type; is &unsigned-byte-8; or &signed-byte-8;. Returns &t; if &read-byte; would return immediately with an &integer-t; result. Returns &eof-k; if the &eos; is already known to be reached. If &read-byte;'s value is not available immediately, returns &nil; instead of waiting.

`(&rbwhp; &stream-r;)`

  To be called only if &stream-r;'s &stream-element-type; is &unsigned-byte-8; or &signed-byte-8;. Returns &nil; if &read-byte; will return immediately. Otherwise it returns true.

`(&rbnh; &stream-r; &optional-amp; &eof-ep; &eof-v;)`

  To be called only if &stream-r;'s &stream-element-type; is &unsigned-byte-8; or &signed-byte-8;. Returns an &integer-t; or does &eos; handling, like &read-byte;, if that would return immediately. If &read-byte;'s value is not available immediately, returns &nil; instead of waiting.

### Function &file-position;

Platform dependent: &dos;, &os2;, &win32; platforms only.

  &file-position; works on any buffered file stream. When a &nl-c; is output to (respectively input from) a file stream, its file position is increased by 2 since &nl-c; is encoded as &cr-c;/&lf-c; in the file.

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

&eltype;

  types equivalent to &character-t; or &unsigned-byte-n;, &signed-byte-n;; if the stream is to be un&buffered;, &n-r; must be a multiple of 8.

  If &n-r; 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-r;-bit bytes) in the preamble.

  This is done to ensure the input/output consistency: suppose you open a file with &eltype; of `(&unsigned-byte-t; 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.

&extfmt;

  &encoding;s, (constant) &symbol-t;s in the &charset-pac; package, &string-t;s (denoting &iconv;-based encodings), the symbol &default-k;, and the &line-term; keywords &unix-k;, &mac-k;, &dos-k;. The default encoding is &def-file-enc;.

&buffered;

  &nil;, &t;, or &default-k;.

  - for functions that create &socket-stream;s and pipes, &default-k; is equivalent to &nil;;

  - for functions that open files, &default-k; 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!

### Function &close;

Function &close; is a &generic-function-t;, see section "Gray streams".

&close; ignores its &abort-k; argument.

&get-output-stream-string; returns the same value after &close; as it would before it.

&close; on an already closed &stream-t; does nothing and returns &t;.

If you do not &close; your &stream-t; explicitly, it will be closed at &gc;ion time automatically. This is not recommended though because &gc;ion is not deterministic. Please use &with-open-stream; etc.

### Function &open-stream-p;

Function &open-stream-p; is a &generic-function-t;, see section "Gray streams".

### Class &broadcast-stream-t;

&input-stream-p; and &interactive-stream-p; return false for &broadcast-stream-t;s.

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

`(EXT:MAKE-BUFFERED-OUTPUT-STREAM &func-r;)` returns a buffered &out-s;. &func-r; is a &function-t; expecting one argument, a &simple-string-t;. &write-char; collects the &character-t;s in a &string-t;, until a newline character is written or &force-output;/&finish-output; is called. Then &func-r; is called with a &simple-string-t; as argument, that contains the characters collected so far. &clear-output; dicards the characters collected so far.

`(EXT:MAKE-BUFFERED-INPUT-STREAM &func-r; mode)` returns a buffered &in-s;. &func-r; is a &function-t; of 0 arguments that returns either &nil; (stands for &eos;) or up to three values &string-r;, &start-r;, &end-r;. &read-char; returns the &character-t;s of the current &string-r; one after another, as delimited by &start-r; and &end-r;, which default to &zero; and &nil;, respectively. When the &string-r; is consumed, &func-r; is called again. The &string-r; returned by &func-r; should not be changed, otherwise &func-r; should copy the &string-r; with &copy-seq; or &subseq; beforehand. mode determines the behavior of &listen; when the current &string-r; buffer is empty:

&nil;

  the stream acts like a &file-stream-t;, i.e. &func-r; is called

&t;

  the stream acts like an interactive stream without &eos;, i.e. one can assume that further characters will always arrive, without calling &func-r;

&function-t;

  this &function-t; tells, upon call, if further non-empty &string-r;s are to be expected.

&clear-input; discards the rest of the current &string-r;, so &func-r; will be called upon the next &read-char; operation.

# Printer [CLHS-22]

## Multiple Possible Textual Representations [CLHS-22.1.1.1]

### Variable &pr-closure;

An additional variable &pr-closure; controls whether compiled and interpreted functions (closures) are output in detailed form. If &pr-closure; is non-&nil;, compiled closures are output in #Y syntax which the reader understands. &pr-closure; is initially set to &nil;.

### Variable &pr-rpars;

An additional variable &pr-rpars; controls the output of the right (closing) parentheses. If &pr-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. &pr-rpars; is initially set to &nil;.

### Variable &pr-indent;

An additional variable &pr-indent; 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. &pr-indent; is initially set to `1`.

### Variable &ppr-first-newline;

An additional variable &ppr-first-newline; controls pretty-printing of multi-line objects. When &ppr-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 &nl-c;, then a &nl-c; is printed before the object. &ppr-first-newline; has no effect if &print-pretty-var; is &nil;. &ppr-first-newline; is initially set to &t;.

## Printing Other Vectors [CLHS-22.1.3.7]

When &print-readably-var; is true, other vectors are written as follows: if the &array-element-type; is &t-t;, the syntax `#(x0 ... xn-1)` is used. Otherwise, the syntax `#A(&eltype-r; &dimensions-r; &cont-r;)` is used.

## Printing Other Arrays [CLHS-22.1.3.8]

When &print-readably-var; is true, other arrays are written as follows: if the &array-element-type; is &t-t;, the syntax `#rankA &cont-r;` is used. Otherwise, the syntax `#A(&eltype-r; &dimensions-r; &cont-r;)` is used.

## The Lisp Pretty Printer [CLHS-22.2]

The Lisp Pretty Printer implementation is &not-e; perfect yet. &pprint-logical-block; does not respect &print-lines-var;.

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

A pprint dispatch table is a &cons; of a symbol &print-pprint-dispatch-var; an &alist; which maps types into priorities and print functions. Their use is strongly discouraged because of the performance issues: when &print-pprint-dispatch-var; is non-trivial and &print-pretty-var; 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).

## 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 &pr-closure;.

### Function &format;

The additional &format; instruction ~!
is similar to &format-slash;, but avoids putting a function name into a string, thus, even if the function is not interned in the &clu-pac; package, you might not need to specify the package explicitly. `(&format; &stream-r; "~args!" &func-r; &object-r;)` is equivalent to `(&funcall; &func-r; &stream-r; &object-r; colon-modifier-p atsign-modifier-p args)`.

&format; &format-r; and &format; &format-rs; 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; &format-c; does not output the character itself, only the instruction how to type the character.

For &format; &format-e; and &format; &format-g;, the value of &read-default-float-format-var; does not matter if &print-readably-var; is true.

&format; &format-t; can determine the current column of any built-in stream.

### pathnames

Pathnames are printed as follows: If &print-escape-var; is &nil;, only the namestring is printed; otherwise it is printed with `#P""` syntax, as per &ansi-cl; Issue PRINT-READABLY-BEHAVIOR:CLARIFY. But, if &print-readably-var; is true, we are in trouble as `#P""` is ambiguous (which is verboten when &print-readably-var; is true), while being mandated by the &ansi-cl;. Therefore, in this case, &clisp;'s behavior is determined by the value of &pathprint;: when it is &nil;, we print pathnames like this: `#-CLISP #P"" #+CLISP #S(PATHNAME ...)`. Otherwise, when the variable &pathprint; is non-&nil;, the `#P""` notation is used as per 1.5.1.4.1 Resolution of Apparent Conflicts in Exceptional Situations.

### Miscellaneous Issues

&print-case-var; 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 &mem-image; (which you should never do anyway!)

If &print-readably-var; is true, &read-default-float-format-var; has no influence on the way floating point numbers are printed.

Platform dependent: &unix;, &dos;, &os2;, &win32;, &acorn; platforms only.

  &print-pretty-var; is initially &nil; but set to &t; in &config-file;. This makes screen output prettier.

Platform dependent: &amiga; platforms only.

  &print-pretty-var; is initially &nil; but set to &t; in &config-file;. This makes unbuffered screen output both much faster and prettier.

&print-array-var; is initially set to &t;.

# Reader [CLHS-23]

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

## Unreadable objects

format | meaning
--- | ---
`#<&type-r; ...>` | all &structure-object-t;s lacking a keyword constructor
`#<ARRAY &type-r; &dimensions-r;>` | all &array-t;s except &string-t;s, if &print-array-var; is &nil;
`#<SYSTEM-FUNCTION &name-r;>` | built-in function written in &c-lang;
`#<ADD-ON-SYSTEM-FUNCTION &name-r;>` | other function written in &c-lang;
`#<SPECIAL-OPERATOR &name-r;>` | special operator handler
`#<COMPILED-CLOSURE &name-r;>` | compiled function, if &pr-closure; is &nil;
`#<CLOSURE &name-r; ...>` | 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-t;
`#<PACKAGE &name-r;>` | &package-t;
`#<HASH-TABLE #x...>` | &hash-table-t;, if &print-array-var; is &nil;
`#<READTABLE #x...>` | &readtable-t;
`#<SYMBOL-MACRO &form-r;>` | &symbol-macro; handler
`#<MACRO &func-r;>` | macro expander (defined by &defmacro; and friends)
`#<&foreign-pointer-t; #x...>` | foreign pointer (Platform dependent: &unix;, &win32;, &amiga; platforms only.)
`#<&foreign-address-t; #x...>` | foreign address (Platform dependent: &unix;, &win32;, &amiga; platforms only.)
`#<&foreign-variable; &name-r; #x...>` | foreign variable (Platform dependent: &unix;, &win32;, &amiga; platforms only.)
`#<&foreign-function; &name-r; #x...>` | foreign function (Platform dependent: &unix;, &win32;, &amiga; 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-dec;
`#<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

## characters

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

## Additional read dispatch macros

- #Y is used to read compiled functions and to set the current &in-s;'s &encoding;.

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

  Platform dependent: &dos;, &os2;, &win32; platforms only.

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

  Platform dependent: &acorn; platforms only.

    As in all strings, backslashes must be written twice here: `#"\\.test.lisp"`

## 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-k; option of &make-package; and &defpackage;.

# System Construction [CLHS-24]

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

### Function &compile-file;

`(&compile-file; input-file &key-amp; &outfile-k; :LISTING &warnings-k; &verbose-k; &print-k; &extfmt;)` compiles a file to platform-independent bytecode.

input-file

  should be a &path-des;.

&outfile-k;

  should be &nil; or &t; or a &path-des; or an &out-s;. The default is &t;.

`:LISTING`

  should be &nil; or &t; or a &path-des; or an &out-s;. The default is &nil;.

&warnings-k;

  specifies whether warnings should also appear on the screen.

&verbose-k;

  specifies whether error messages should also appear on the screen.

&print-k;

  specifies whether an indication which forms are being compiled should appear on the screen.

The variables &compile-warn;, &compile-verbose-var;, &compile-print-var; provide defaults for the &warnings-k;, &verbose-k;, &print-k; 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: &lisp-file;) the following files are generated:

File | When | Default file type | Contents
--- | --- | --- | ---
output file | only if &outfile-k; is not &nil; | &fasl-file; | can be loaded using the &load; function
auxiliary output file | only if &outfile-k; is not &nil; | &lib-file; | 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-lang; output file | only if &outfile-k; is not &nil; | `#P".c"` | foreign function interface; this file is deleted if it is empty

If you have two files in the same directory - &foolisp-f; and `#P"foo.c"`, and you compile the first file with &clisp;, the second file will be clobbered if you have any &ffi-pac; forms in the first one!

### Function &compile-file-pathname;

The default for the &outfile-k; argument is &t;, which means &fasl-file;.

### Function &require;

The function &require; receives as the optional argument either a &pathname-t; or a &list-t; of &pathname-t;s: files to be &load;ed if the required module is not already present.

At compile time, `(&require; &foo-f;)` forms are treated specially: &load-paths; is searched for &foolisp-f; and `#P"foo.lib"`. If the latest such file is a &lisp-file;, it is compiled; otherwise the &lib-file; is loaded.

The &lib-file; 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-e; necessary to either enclose &require; forms in &eval-when; or to load the required files in the makefiles: if you have two files, &foolisp-f; and `#P"bar.lisp"`, and the latter requires the former, you can write in your &make-file;:

    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 &lib-file;s are usually smaller and load faster that &fasl-file;s):

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

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

### Function &load;

&load; has four additional keywords &echo-k;, &compiling-k;, &extra-file-types-k;, and &obsolete-action-k;.

`(&load; &filename-r; &key-amp; &verbose-k; &print-k; &echo-k; &if-does-not-exist; &compiling-k; &extra-file-types-k; &obsolete-action-k;)`

&verbose-k; &t;

  causes &load; to emit a short message that a file is being loaded. The default is &load-verbose-var;, which is initially &t;.

&print-k; &t;

  causes &load; to print the value of each form. The default is &load-print-var;, which is initially &nil;.

&echo-k; &t;

  causes the input from the file to be echoed to &standard-output-var; (normally to the screen). Should there be an error in the file, you can see at one glance where it is. The default is &load-echo;, which is initially &nil;.

&compiling-k; &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 &load-comp;, which is initially &nil;.

&extra-file-types-k; &list-t;

  Specifies the additional file types considered for loading, in addition to &source-types; (which is initially `("lisp" "lsp" "cl")`) and &compiled-types; (which is initially `("fas")`).

  When &filename-r; does not spefify a unique file (e.g., &filename-r; is &foo-f; and both &foolisp-f; and `#P"foo.fas"` are found in the &load-paths;), then the newest file is loaded.

&obsolete-action-k; &nil;

  Specifies the action to take when loading a &fasl-file; with a different bytecode version from the one supported by this &clisp; version. The possible actions are `:DELETE` to delete the &fasl-file; and &error-k; to &signal; an &error-t;. 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-t; is &signal;ed. The default is &load-obs;, which is initially &nil;.

The variables &load-verbose-var;, &load-print-var;, &load-obs;, &load-comp;, and &load-echo; are bound by &load; when it receives a corresponding keyword argument (&verbose-k;, &print-k;, &obsolete-action-k;, &compiling-k;, and &echo-k;), i.e., these arguments are recursive, just like the arguments &warnings-k;, &verbose-k;, and &print-k; for &compile-file;.

#### Variable &load-paths;

The variable &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;.

### Variable &features-var;

The variable &features-var; initially contains the symbols

#### &features-var; content

keyword | meaning
--- | ---
`:CLISP` | the name of this implementation
`:ANSI-CL` |
`:COMMON-LISP` |
`:INTERPRETER` |
`:COMPILER` |
`:SOCKETS` | see &socket-stream;s
`:GENERIC-STREAMS` | see Defining new kinds of Streams
`:SYSCALLS` | see System Calls
`:DIR-KEY` | see Directory Access
`:LOGICAL-PATHNAMES` |
`:FFI` | if a foreign function interface (see &ffi-pac;) is supported (Platform dependent: many &unix;, &win32; platforms only)
`:GETTEXT` | if internationalization (see &i18n-pac;) using the &ggettext; package is supported (Platform dependent: most &unix; platforms only)
`:UNICODE` | if &unicode; (ISO 10646) characters are supported (see &charset-pac;)
`:LOOP` |
`:CLOS` |
`:AMIGA` | if &hw; = Amiga and &os; = Exec/AmigaDOS
`:DOS` | if &hw; = PC (clone) and &os; = DOS
`:OS/2` | if &hw; = PC (clone) and &os; = OS/2
`:WIN32` | if &hw; = PC (clone) and &os; = Win32 (Windows 95/98/NT/Me/2000/XP)
`:PC386` | if &hw; = PC (clone) with a 386/486/586/686 CPU
&unix-k; | if &os; = Unix (in this case the &hw; is irrelevant!)
`:CYGWIN` | if &clisp; is using the &cygwin; &unix; compatibility layer on top of &win32; (in that case &unix-k; is also present)

# Environment [CLHS-25]

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

### Commands common to the main loop, the debugger and the stepper

&cmd-abbrev-oper-header;
`Help` | `:h` | prints a list of available commands

### Commands common to the debugger and the stepper

&cmd-abbrev-oper-header;
`Abort` | `:a` | abort to the next most recent &repl;
`Unwind` | `:uw` | abort to the next most recent &repl;
`Quit` | `:q` | quit to the top &repl;

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-star;, &unwind-protect; and &catch; produce special kinds of stack frames.

In a break loop there is a current stack frame, which is initially the most recent stack frame but can be moved using the debugger commands `Up` and `Down`.

Evaluation of forms in a break loop occurs in the lexical environment of the current stack frame but in the dynamic environment of the debugger's caller. This means that to inspect or modify a lexical variable all you have to do is to move to the current stack frame just below the frame that corresponds to the form or the function call that binds that variable.

There is a current "stack mode" which defines in how much detail the stack is shown by the stack related debugger commands.

### Commands common to the debugger and the stepper

&cmd-abbrev-oper-header;
`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:

### Commands specific to &eval;/&apply;

&cmd-abbrev-oper-header;
`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 &trace-val; 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.

### Commands specific to the debugger

&cmd-abbrev-oper-header;
`Continue` | `:c` | continues evaluation of the program.

### Commands specific to the stepper

&cmd-abbrev-oper-header;
`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-r;)` 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.

## The Environment Dictionary [CLHS-25.2]

### 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 &foreign-function;, a special operator indicator, a symbol denoting one of these, a number, or a string.

### Function &uncompile;

The function &uncompile; does the converse of &compile;: `(&uncompile; &func-r;)` reverts a compiled &func-r; (name), that has been entered or loaded in the same session and then compiled, back to its interpreted form.

### Function &documentation;

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

#### Function `EXT:CLHS`

&hyperspec; access is provided via `(`EXT:CLHS` &symbol-r; &key-amp; &browser-k;)` function, which uses your web browser. browser (defaults to &browser;) should be a valid keyword in the &browsers; &alist;.

### Macro &trace;

`(&trace; &func-r; ...)` makes the functions &func-r;, ... traced. &func-r; should be either a symbol or a list `(&symbol-r; &key-amp; `:suppress-if` `:step-if` `:pre` `:post` `:pre-break-if` `:post-break-if` `:pre-print` `:post-print` &print-k;)`, where

`:suppress-if` &form-r;

  no trace output as long as &form-r; is true

`:step-if` &form-r;

  invokes the stepper as soon as &form-r; is true

`:pre` &form-r;

  evaluates &form-r; before calling the function

`:post` &form-r;

  evaluates &form-r; after return from the function

`:pre-break-if` &form-r;

  goes into the break loop before calling the function if &form-r; is true

`:post-break-if` &form-r;

  goes into the break loop after return from the function if &form-r; is true

`:pre-print` &form-r;

  prints the values of &form-r; before calling the function

`:post-print` &form-r;

  prints the values of &form-r; after return from the function

&print-k; &form-r;

  prints the values of &form-r; 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

&trace-val;

  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-r;)` and to macros, but not to locally defined functions and macros.

#### Variable &trace-indent;

If you want the &trace; level to be indicated by the indentation in addition to the printed numbers, set &trace-indent; to non-&nil;. Initially it is &nil; since many nested traced calls will easily exhaust the available line length.

### 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-var; 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-k; keyword argument) is opened and it is controlled by &clisp; via a &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.

### 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 &gc;ion occurs.

The function `EXT:GC`
starts a global &gc;ion and its return value has the same meaning as the second value of &room;.

### 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 &gc;ions performed, if any.

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

### Function &ed;

The function &ed; calls the external editor specified by the value of `(&getenv; "EDITOR")` or, failing that, the value of the variable &editor; (see &config-file;). 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.

### Clock Time

Platform dependent: &amiga;, &acorn;, &dos;, &os2; platforms only.

  The variable &default-tz; 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-t;, but (as &float-t; or &rational-t; number) it should be a multiple of `1/3600`.

#### Time granularity

platform | &acorn;, &dos;, &os2; | &amiga; | &unix; | &win32;
--- | --- | --- | --- | ---
&internal-time-units-per-second; | 100 | 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.

### Machine

Platform dependent: &unix; platform only.

  The functions &short-site-name;, &long-site-name; should be defined in a site-specific &config-file; file. The default implementations try to read the value of the &env-var; `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 &config-file; file. The default implementations try to read the registry.

Platform dependent: &amiga;, &acorn;, &dos;, &os2; 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 &config-file; file.

### Functions &apropos; & &apropos-list;

The search performed by &apropos; and &apropos-list; is case-insensitive.

### 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-e; &recog-subt;) of &two-way-stream-t;, named &ds-t;. If you have a &source-r; &bidi-s; &x-r; and you want all transactions (input and output) on &x-r; to be copied to the &target-r; &out-s; &y-r;, you can do

      (&defvar; *loggable* &x-r;)
      (&setq; &x-r; (&make-synonym-stream; '*loggable*))
      (&defun; toggle-logging (&optional-amp; s)
        (&multiple-value-bind; (so ta) (dribble-toggle *loggable* s)
          (&when; (&streamp; so) (&setq; *loggable* so))
          ta))
      (toggle-logging &y-r;)     ; start logging
      ...
      (toggle-logging)       ; finish logging
      ...
      (toggle-logging &y-r;)     ; restart logging
      ...
      (toggle-logging)       ; finish logging
      (&close; &y-r;)

`(`EXT:DRIBBLE-STREAM` &stream-r;)`

  When &stream-r; is a &ds-t;, returns two values: the &source-r; and the &target-r; streams. Otherwise returns &nil;.

`(`EXT:DRIBBLE-STREAM-P` &stream-r;)`

  When &stream-r; is a &ds-t;, returns &t;, otherwise returns &nil;.

`(`EXT:DRIBBLE-STREAM-SOURCE` &stream-r;)`

  When &stream-r; is a &ds-t;, returns its &source-r; stream, otherwise signals a &type-error-t;.

`(`EXT:DRIBBLE-STREAM-TARGET` &stream-r;)`

  When &stream-r; is a &ds-t;, returns its &target-r; stream, otherwise signals a &type-error-t;.

`(`EXT:MAKE-DRIBBLE-STREAM` &source-r; &target-r;)`

  Create a new &ds-t;.

`(`EXT:DRIBBLE-TOGGLE` &stream-r; &optional-amp; &path-r;)`

  When &stream-r; is a &ds-t; and &path-r; is &nil;, writes a dribble termination note to the &stream-r;'s &target-r; &stream-t; and returns &stream-r;'s &source-r; and &target-r; &stream-t;s; when &stream-r; is not a &ds-t; and &path-r; is non-&nil;, creates a new &ds-t;, dribbling from &stream-r; to &path-r;, writes a dribble initialization note to &path-r;, and return the &ds-t; (the second value is the &target-r; &stream-t;); otherwise &warn; that no appropriate action may be taken. &path-r; may be an open &out-s; or a &path-des;. See above for the sample usage. See also `#P"src/dribble.lisp"` in the &clisp; source tree.

### 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 &mem-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.

# Glossary [CLHS-26]

No notes.

# Appendix [CLHS-a]

No notes.