# Introduction

## Special Symbols

The final delimiter of an interactive stream:

&unix;

  type &ctrl;D at the beginning of a line

&win32;

  type &ctrl;Z, followed by &enter;

final delimiter
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 &eos;.

A newline character can be entered by the user by pressing the &enter; key.

See also .

## Error Terminology

Safety settings are ignored by the interpreted code; therefore where the standard uses the phrase should signal an error, an &err-sig;. See for the safety of compiled code.

## Symbols in the Package &cl-pac;

All 978 symbols in the &cl-pac; package specified by the &ansi-cl; are implemented.

# Syntax

## Standard Characters

The standard characters are &nl-s; and the graphic characters with a &code-char; between 32 and 126 (inclusive).

## Reader Algorithm

The requirement of step 4 that a reader macro function may return zero values or one value &is-e; enforced. You can use the function &values; to control the number of values returned.

## Symbols as Tokens

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.

token reserved

## Valid Patterns for Tokens

When a token with package markers is read, then no checking is done whether the &symbol-package; part and the &symbol-name; part do not have number syntax. (What would the purpose of this check be?) So we consider tokens like USER:: or :1 or LISP::4711 or 21:3 as symbols.

## Backquote

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

Reader macros are also defined for the following:

Additional reader macros

`#,`

  load-time evaluation, kept despite the &ansi-cl; issue &iss315;.

`#Y`

  compiled &function-t; objects and &in-s;'s &encoding;s

`#""`

  &pathname-t;: `#"test.lisp"` is the value of `(&pathname; "test.lisp")`

### Sharpsign Backslash

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

### Sharpsign Less-Than-Sign

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

Unreadable objects

`&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;`

  &module; function written in &c-lang;

`SPECIAL-OPERATOR &name-r;`

  special operator handler

`COMPILED-FUNCTION &name-r;`

  compiled function, if &pr-closure; is &nil;

`FUNCTION &name-r; ...`

  interpreted function, , if &pr-closure; is &nil;

`FRAME-POINTER #x...`

  pointer to a stack frame

`DISABLED POINTER`

  frame pointer which has become invalid on exit from the corresponding █ 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 (&unix-w32-only;)

`&foreign-address-t; #x...`

  foreign address (&unix-w32-only;)

`&foreign-variable-t; &name-r; #x...`

  foreign variable (&unix-w32-only;)

`&foreign-function-t; &name-r; #x...`

  foreign function (&unix-w32-only;)

`UNBOUND`

  value of an unbound symbol, 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 &eos; is reached

`READ-LABEL ...`

  intermediate &read; result for &sharp-sharp;

`ADDRESS #x...`

  machine address, should not occur

`SYSTEM-POINTER #x...`

  should not occur

# Evaluation and Compilation

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

Function call limits

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

## Evaluation

### Introduction to Environments

Macro &the-env;

As in Scheme, the macro `(&the-env;)` returns the current &lex-env;. 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 &lex-env;, just as if the form had been a part of the program that the &env-r; came from.

### Symbols as Forms

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

The function &symbol-mex; tests for a &symbol-macro;: If &symbol-r; is defined as a &symbol-macro; in the &glo-env;, `(&symbol-mex; &symbol-r;)` returns two values, &t; and the expansion; otherwise it returns &nil;.

SYMBOL-MACRO-EXPAND

&symbol-mex; is a special case of ¯oexpand-1;. ¯oexpand-1; can also test whether a symbol is defined as a &symbol-macro; in &lex-env;s other than the &glo-env;.

#### Dynamic Variables

Undefined variables, i.e. &variable;s which are referenced outside any lexical binding for a variable of the same name and which are not declared &special-dec;, are treated like &dyn-var;s in the &glo-env;. The compiler &signal;s a &warning-t; when it encounters an undefined variable.

### Conses as Forms

Lists of the form `((&setf; &symbol-r;) ...)` are also treated as function forms. This makes the syntax `(&funcname-r; &args-r; ...)` consistent with the syntax `(&funcall; #'&funcname-r; &args-r; ...)`. It implements the item 7 of the &ansi-cl; issue &iss174; and the definition of function forms, and is consistent with the use of &funname;s elsewhere in &cl;.

### Special Forms

#### Special operator &eval-when;

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

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

#### Special operator &the;

The special form `(&the; &val-type-r; &form-r;)` is similar to &check-type; but does a type check only in interpreted code (no type check is done in compiled code - but see the ðe; macro) and does not allow interactive error correction by the user.

### Function Forms

Constant &lambda-list-keywords;

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

#### Function &symbol-function;

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

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

See also .

Function &arglist;

Function `(&arglist; &name-r;)` returns the &lalist; of the function or macro that &name-r; names and &sig-err; if &name-r; is not &fboundp;. It also &sig-err; when the macro &lalist; is not available due to the compiler optimization settings (see ).

Variable &suppress-check-redef;

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

Variable &defun-accept-spelalist;

When &defun-accept-spelalist; is non-&nil;, &defun; accepts &spelalist;s, converting type-parameter associations to type declarations:

    (defun f ((x list) (y integer)) ...)

is equivalent to

    (defun f (x y) (declare (type list x) (type integer y)) ...)

This extension is disabled by &opt-ansi; and by setting &ansi; to &t;, but can be re-enabled by setting &defun-accept-spelalist; explicitly.

## Compilation

### Compiler Terminology

&clisp; compiles to platform-independent &bytecode;.

#### Just-In-Time Native Compilation

Only in &clisp; built &with; &lightning;

The code compiled to &bytecode;s with optimization levels

    (&or-m; (≥ 0 &space-dec;) (≤ 1 &speed-dec;))

(by &compile;, &compile-file-my;, or &compile-decl;) will be just-in-time (i.e., on the first execution) compiled to native code using &lightning;.

### Compilation Semantics

#### Compiler Macros

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

#### Minimal Compilation

When a &defun; form is &eval;uated, the macros used there are expanded, so they must be already defined, and their (re)definition does ¬-e; affect functions which are already defined.

This means that even the interpreted code is minimally compiled in &clisp;.

#### Semantic Constraints

Non-conforming code that does not follow the rule

> Special proclamations for dynamic variables must be made in the compilation environment.

can produce quite unexpected results, e.g., observable differences between compiled and interpreted programs:

    (defun adder-c (value) (declare &compile-decl;) (lambda (x) (+ x value)))
    ADDER-Ccompiled function; &value-r; is lexical
    (defun adder-i (value) (lambda (x) (+ x value)))
    ADDER-Iinterpreted function; &value-r; is lexical
    (defparameter add-c-10 (adder-c 10))
    ADD-C-10compiled function
    (defparameter add-i-10 (adder-i 10))
    ADD-I-10interpreted function
    (funcall add-c-10 32)
    42as expected
    (funcall add-i-10 32)
    42as expected
    (defvar value 12)
    VALUEaffects ADDER-I and ADD-I-10 but ¬-e; ADDER-C and ADD-C-10
    (funcall add-c-10 32)
    42as before
    (funcall add-i-10 32)
    44&value-r; is now dynamic!

Non-conformance

The code shown above has a &special-dec; proclamation (by &defvar;) for the variable &value-r; in the execution environment (before the last two &funcall;s) but not in the compilation environment: at the moment the `ADDER-I` function is defined, &value-r; is not known to be a &special-dec; variable. Therefore the code is not conforming.

##### Rationale

The function `ADD-C-10` was compiled &before-e; &value-r; was declared &special-dec;, so the symbol &value-r; was eliminated from its code and the &special-dec; declaration did not affect the return value (i.e., `(funcall add-c-10 32)` always returned 42).

On the opposite, function `ADDER-I` was ¬-e; compiled, so `ADD-I-10` was interpreted. Whenever `ADD-I-10` is executed, its definition is interpreted all over again. Before &defvar;, &value-r; is evaluated as a lexical (because it is ¬-e; declared &special-dec; yet), but after &defvar;, we see a globally &special-dec; symbol &value-r; which can have only a global &symbol-value; (not a local binding), and thus we are compelled to evaluate it to 12.

This behavior was implemented intentionally to ease interactive development, because usually the `ADDER-I` above would be followed by a (forgotten) &defvar;.

When a user compiles a program, the compiler is allowed to remember the information whether a variable was &special-dec; or not, because that allows the compiler to generate more efficient code, but in interpreted code, when the user changes the state of a variable, he does ¬-e; want to re-evaluate all &defun;s that use the variable.

&ansi-cl; gives the implementation freedom regarding interpreted evaluation, how much it wants to remember / cache, and how much it wants to re-evaluate according the current &environment;, if it has changed. &clisp; implements ad-hoc look-up for variables (but ¬-e; for macros, see ).

### Definition of Similarity

Hash tables are &ext-obj;s.

### Exceptional Situations in the Compiler

Both &compile; and &eval; may &signal; the &source-program-error; &condition-t; which derives from &program-error-t; and which contains additional slots with accessors

&source-program-error-form;

  Returns the whole form in which the &error-t; was &signal;ed

&source-program-error-detail;

  Returns the specific (usually small) part of the above which triggered the &error-t;

Mixing &optional-amp; and &key-amp;

It is a bad design to have both &optional-amp; and &key-amp; in the same &lalist;, especially if the number of optional arguments is even: the users will often forget to supply optional arguments when supplying keys, e.g., `(&read-from-string; &string-r; &start-k; 5)` instead of `(&read-from-string; &string-r; t nil &start-k; 5)`. This is why the &clisp; compiler issues a &style-warning-t; in such cases:

    (&defun; foo (&optional-amp; a &key-amp; b) (cons a b))
    (&compile; 'foo)
    WARNING: in FOO : Mixing &optional-amp; and &key-amp; in lambda list (&optional-amp; A &key-amp; B) is bad design
    FOO ;
    1 ;
    NIL

## Declarations

### Minimal Declaration Processing Requirements

The declaration `(&dynamic-extent-dec; &var-r; ...)` is ignored.

The type declarations `(&type-dec; &type-r; &var-r; ...)` and `(&ftype-dec; &type-r; &func-r; ...)` are ignored by both the interpreter and the compiler. Use &check-type; to force type checks.

Rationale

When these declarations lie and a compiler respects them, the generated code often results in a hard crash (segmentation fault).

### Declaration &special-dec;

Declaration ¬spec;

Declarations `(&proclaim; '(&special-dec; &var-r;))` and &defconstant; are undone by the `(&proclaim; '(¬spec; &var-r;))` declaration. This declaration can be used only in global &proclaim; and &declaim; forms, ¬-e; in local &declare; forms.

You cannot expect miracles: functions compiled &before-e; the ¬spec; proclamation was issued will still be treating &var-r; as special even after the ¬spec; proclamation. See also .

Function &spe-var-p;

You can use the function `(&spe-var-p; &symbol-r; &optional-amp; &env-r;)` to check whether the &symbol-r; is a &dyn-var;. &env-r; of &nil; or omitted means use the &glo-env;. You can also obtain the current &lex-env; using the macro &the-env; (interpreted code only). This function will always return &t; for global special variables and &constant;s.

### Declaration &constnotin;

Constants defined by &defconstant; but proclaimed &constnotin; will not be inlined by the compiler. This is useful for variables which remain constant within an a single Lisp process but may vary between processes and machines (such as endianness or word size) thus they should be written to &fasl-file;s as symbols, not values.

### Function &constantp;

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

Since &defconstant; initial value forms are not evaluated at compile time, &constantp; will not report &t; of their name within the same &comp-unit; for the null &lex-env;. This is consistent and matches questionable code using the pattern `(&if; (&constantp; &form-r;) (&eval; &form-r;))`. Use &eval-when; if you need recognition and the value during compile-time. See also .

### Declaration &safety-dec;

Declaration `(&optimize-dec; (&safety-dec; 3))` results in safe compiled code: function calls are never eliminated. This guarantees the semantics described in .

### Declaration &compile-decl;

The declaration &compile-decl; has the effect that the current form is compiled prior to execution. Examples:

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

executes the compiled version of &form-r;.

    (&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;.

This declaration can also be used to name the resulting compiled closure:

    (&lambda-m; (x) (&declare; (compile ident)) x)
    &sharp-lt;&compiled-function-t; IDENT>
    (&function-lambda-expression; &star-var;)
    &nil;source is not preserved
    &t;
    IDENT
    (&fboundp; 'ident)
    &nil;sic!

The declaration &compile-decl; is ignored by the following special operators:

- &labels;
- &flet;
- ¯olet;

### Declaration &space-dec;

The declaration determines what metadata is recorded in the function object:

&space-dec; ≥ 2

  documentation string is discarded

&space-dec; ≥ 3

  the original &lalist; is also discarded (most information is still available, see &describe-my;, but the names of the positional arguments are not).

## Lambda Lists

### Boa Lambda Lists

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

# Types and Classes

## Types

### Type Specifiers

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

&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` &type-r; &optional-amp; once-p)`

If &type-r; is a user-defined &typespec-glo; this will expand it recursively until it is no longer a user-defined type (unless once-p is supplied and non-&nil;). Two values are returned - the expansion and an indicator (&t; or &nil;) of whether the original &type-r; was a user-defined &typespec-glo;.

The possible results of &type-of;

- &cons-t;

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

- &bit-t;, `(&integer-t; 0 &sharp-dot;&most-positive-fixnum;)`, `(&integer-t; &sharp-dot;&most-negative-fixnum; (0))`, `(&integer-t; (&sharp-dot;&most-positive-fixnum;))`, `(&integer-t; * (&sharp-dot;&most-negative-fixnum;))`

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

- &character-t;, &base-char-t;, &standard-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;, &standard-generic-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;, GLOBAL-SYMBOL-MACRO, &encoding;, &foreign-pointer-t;, &foreign-address-t;, &foreign-variable-t;, &foreign-function-t;

- &weak-pointer;, &weak-list;, &weak-and-relation;, &weak-or-relation;, &weak-mapping;, &weak-and-mapping;, &weak-or-mapping;, &weak-alist;, 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-glo;)

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.

## Classes

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., those described in , are ¬-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-my; "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.

&gen-flet; and &gen-labels; are implemented as macros, not as special operators (as permitted by ). They are not imported into the packages &clu-pac; and &cl-pac; because of the &ansi-cl; issue &iss181;.

GENERIC-FLET
GENERIC-LABELS

&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

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;

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

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

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

See also .

## Redefining Classes

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-k;, &documentation-k;, and changes to class options `:DEFAULT-INITARGS`, &documentation-k;.

The instances are updated when they are first accessed, ¬-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.

# Data and Control Flow

## Generalized Reference

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

An attempt to modify read-only data &sig-err;. 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 .

## Setf Expansions

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

## Kinds of Places

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; &cond-r; 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-float-t;s to &digits-r; bits.

&values-list;

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

  Note that this &place; is restricted: it can only be used in &setf;, &letf;, &letf-star;, not in other positions.

## Miscellaneous

### Function &function-lambda-expression;

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

### 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 ) and, as such, are rather efficient.

## Macro &defconstant;

The initial value is ¬-e; evaluated at compile time, just like with &defvar; and &defparameter;. Use &eval-when; if you need the value at compile time.

&constant;s may not be bound dynamically or lexically.

See also .

If you need to undo the effects of a &defconstant; form, &proclaim; the symbol &special-dec; (to turn the &constant; into a &dyn-var;), and then &proclaim; it ¬spec; (to turn the &dyn-var; into a &lex-var;).

If you follow the usual variable naming convention (`*FOO*` for &defvar; and &defparameter;, `+BAR+` for &defconstant;, `ZOT` for &let;/&let-star;), you will save yourself a lot of trouble. See also .

### Variable &suppress-similar-const-redef;

If the variable being defined by &defconstant; is already bound to a value which is not &eql; to the new value, a &warning-t; is issued. If, however, the new value is visually similar (prints to the same string, as is commonly the case when re-loading files) to the old one, the warning can be suppressed by setting &suppress-similar-const-redef; to a non-&nil; value.

visually similar

The initial value of &suppress-similar-const-redef; is &nil;.

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

If you use a built-in &hash-table-t; test (see ) as the test (e.g., &equal; instead of &string-eq; above, but not a test defined using &defhash;), the compiler will be able to optimize the &fcase; form better than the corresponding &cond; form.

## 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 &mul-val;, 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-r; &y-r;)) (&eq; &x-r; &x-r;))` always returns &t; for any Lisp object &y-r;. See also .

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

# Iteration

## The LOOP Facility

### Mixing Termination Test Clauses

Mixing termination test clauses with different default return values is not allowed because it is not specifed whether

    (loop repeat 1 thereis nil never nil)

should return &t; (the default return value from `NEVER`) of &nil; (the default return value from `THEREIS`).

### Iteration variables in the loop epilogue

The standard is unambiguous in that the iteration variables do still exist in the `FINALLY` clause, but ¬-e; as to what values these variables might have. Therefore the code which relies on the values of such variables, e.g.,

    (loop for x on y finally (return x))

is inherently non-portable across &cl; implementations, and should be avoided.

### Backward Compatibility

There have been some tightening in the &loop; syntax between &cltl2; and &ansi-cl;, e.g., the following form is legal in the former but not the latter:

    (loop initially for i from 1 to 5 do (print i) finally return i)

When &loop-ansi; is &nil;, such forms are still accepted in &clisp; but elicit a warning at macro-expansion time. When &loop-ansi; is non-&nil;, an &err-sig;.

## Miscellaneous

The macros &dolist; and &dotimes; establish a single binding for the iteration variable and assign it on each iteration.

# Objects

## Standard Method Combination

Generic function &no-prim; (similar to &no-applicable-method;) is called when there is an applicable method but no applicable primary method.

NO-PRIMARY-METHOD

The default methods for &no-prim;, &no-applicable-method; and &no-next-method; &signal; an &error-t; of type &meth-call-err; . You can find out more information about the error using functions `CLOS:METHOD-CALL-ERROR-GENERIC-FUNCTION`, `CLOS:METHOD-CALL-ERROR-ARGUMENT-LIST`, and (only for &no-next-method;) `CLOS:METHOD-CALL-ERROR-METHOD`. Moreover, when the generic function has only one dispatching argument, (i.e., such an argument that not all the corresponding parameter specializers are &t-t;), an &error-t; of type &meth-call-type-err; is &signal;ed, additionally making &type-error-datum; and &type-error-expected-type; available.

METHOD-CALL-ERROR
METHOD-CALL-TYPE-ERROR

# Structures

## The options for &defstruct;

### The &print-function-k; option

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

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

## The structure &mop;

The following functions accept a structure &name-r; as the only argument. If &defstruct; was given the &type-k; option (i.e., &defstruct; did ¬-e; define a new type), then `(&find-class; &name-r;)` fails (and the regular &clos; &mop; is not applicable), but these functions still work.

`EXT:STRUCTURE-SLOTS`

  Return the &list-t; of &esdmo;s.

`EXT:STRUCTURE-DIRECT-SLOTS`

  Return the &list-t; of &dsdmo;s.

`EXT:STRUCTURE-KEYWORD-CONSTRUCTOR`

  Return the name (a &symbol-t;) of the keyword constructor function for the structure, or &nil; if the structure has no keyword constructor.

`EXT:STRUCTURE-BOA-CONSTRUCTORS`

  Return the &list-t; of names (&symbol-t;s) of BOA constructors for the structure.

`EXT:STRUCTURE-COPIER`

  Return the name (a &symbol-t;) of the copier for the structure.

`EXT:STRUCTURE-PREDICATE`

  Return the name (a &symbol-t;) of the predicate for the structure.

# Conditions

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 &debugger; commands.

## Embedded Newlines in Condition Reports

The error message prefix for the first line is *** - . All subsequent lines are indented by 6 characters. Long lines are broken on &whitespace; (see ).

## Mentioning Containing Function in Condition Reports

Contrary to the recommendation of the standard, &clisp; usually does print the name of the containing function to simplify debugging in batch mode, see &exit-on-error;.

## Interfaces to Restarts

Macro &restart-case;

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

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-r;}*) {&form-r;}*)` is therefore equivalent to `(&restart-case; (&progn; {&form-r;}*) {&restart-clause-r;}*)`.

Function &compute-restarts;

&compute-restarts; and &find-restart; behave as specified in &ansi-cl;: If the optional &cond-r; argument is non-&nil;, only &restart-t;s associated with that &condition-t; and &restart-t;s associated with no &condition-t; at all are considered. Therefore the effect of associating a restart to a condition is not to activate it, but to hide it from other conditions. This makes the syntax-dependent implicit association performed by &restart-case; nearly obsolete.

Macro &muffle-cerrors;

The macro `(&muffle-cerrors; {&form-r;}*)` executes the &form-r;s; when a &cont-err; occurs whose &continue; &restart-t; can be invoked non-interactively (this includes all &cont-err;s signaled by the function &cerror;), 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; when a &cont-err; occurs whose &continue; &restart-t; can be invoked non-interactively (this includes all &cont-err;s &signal;ed by the function &cerror;), it is reported as a &warning-t;, and the &continue; &restart-t; is invoked.

Macro &abort-on-error;

The macro `(&abort-on-error; {&form-r;}*)` executes the &form-r;s; when an &error-t; occurs, or when a &ctrl-c; interrupt occurs, the error message is printed and the &abort-s; &restart-t; is invoked.

Macro &exit-on-error;

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

Variable &err-pr-bt;

When this variable is non-&nil; the error message printed by &abort-on-error; and &exit-on-error; includes the &backtrace; (stack).

Function &set-global-handler;

The function `(&set-global-handler; &cond-r; handler)` establishes a global handler for the &cond-r;. The handler should be &funcall;able (a &symbol-t; or a &function-t;). If it returns, the next applicable handler is invoked, so if you do ¬-e; want to land in the &debugger;, it should ¬-e; return. E.g., the option &opt-on-error; `abort` and the macro &abort-on-error; are implemented by installing the following handler:

    (defun sys::abortonerror (condition)
      (sys::report-error condition)
      (&invoke-restart; (&find-restart; '&abort; condition)))

When handler is &nil;, the handler for &cond-r; is removed and returned. When &cond-r; is also &nil;, all global handlers are removed and returned as a &list-t;, which can then be passed to &set-global-handler; as the first argument and the handlers re-established.

Macro &without-global-handlers;

The macro `(&without-global-handlers; &body-amp; &body-r;)` removes all global handlers by `(&set-global-handler; &nil; &nil;)`, executes &body-r; (where unhandled conditions now invoke the &debugger;), and then restores the handlers.

## Assertions

The prompt for replacement values (&restart-t;s &store-value-s;, &use-value-s; et al) is terminated with &prompt-finish; to indicate that the value entered is treated as usual for the Lisp &repl;, i.e., it is &eval;uated.

# Symbols

No notes.

# Packages

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 no nicknames

## Introduction to Packages

### Function &make-package;

The default value of the &use-k; argument is `(&cl-pac;)`.

&make-package; accepts additional keyword arguments &case-sensitive-k; and &case-inverted-k; (but ¬-e; &modern-k;!)

### Macro &defpackage;

&defpackage; accepts additional options &case-sensitive-k;, &case-inverted-k;, and &modern-k;.

When the package being defined already exists, it is modified as follows (and in this order):

&case-sensitive-k;

  adjusted with `(&setf; &pack-sensitive;)` (with a warning)

&case-inverted-k;

  adjusted with `(&setf; &pack-inverted;)` (with a warning)

&modern-k;

  if &cl-pac; is being used, it is un-used and &cs-cl; is used instead; also, &cs-cl; is used instead of &cl-pac; throughout the &defpackage; form, e.g.,

      (&defpackage; "FOO"
        (&modern-k; &t;)
        (&use-k; "COMMON-LISP" "EXT"))

  is equivalent to

      (&defpackage; "FOO"
        (&case-sensitive-k; &t;)
        (&case-inverted-k; &t;)
        (&use-k; "CS-COMMON-LISP" "EXT"))

  `(&modern-k; &nil;)` reverts the effects of `(&modern-k; &t;)`.

`:NICKNAMES`

  adjusted with &rename-package;

&documentation-k;

  reset to the new value with `(&setf; &documentation;)`

`:SHADOW`

  adjusted with &shadow;

`:SHADOWING-IMPORT-FROM`

  adjusted with &shadowing-import;

&use-k;

  adjusted with &use-package; and &unuse-package;

`:IMPORT-FROM`

  adjusted with &import;

`:INTERN`

  adjusted with &intern; (but ¬-e; &unintern;)

`:EXPORT`

  adjusted with &intern; and &export; (but ¬-e; &unexport;)

`:SIZE`

  ignored

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

### Function &pack-inverted;

Returns &t; if the argument is a case-inverted package. This function is &setf;able, although it is probably not a good idea to change the case-inverted status of an existing package.

### Function &pack-sensitive;

Returns &t; if the argument is a &case-sensitive-k; &package-t;. This function is &setf;able, although it is probably not a good idea to change the case-sensitive status of an existing package.

## Constraints on the &cl-pac; Package for Conforming Programs - package locking

Locking discussed in this section has nothing to do with &mutex-lock;.

Function &package-lock;

PACKAGE-LOCK

Packages can be locked. When a package is locked, attempts to change its symbol table or redefine its symbols (as &defun;, &defmacro;, &defgeneric;, &defvar;, &defparameter;, &defconstant;, &deftype;, &declaration-dec;) result in a &cont-err; (continuing overrides locking for this operation). When &suppress-check-redef; is &t; (¬-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; (&cl-pac; &ext-pac; &clos-pac;)
      (defun restart () ...))

WITHOUT-PACKAGE-LOCK
or

    (&without-package-lock; (&cl-pac;) (trace read-line))

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

Variable &sys-pack-list;

This variable specifies the default packages to be locked by &savemem; and unlocked by &without-package-lock; as a list of package names. You may add names to this list, e.g., a module will add its package, but you should ¬-e; remove &clisp; internal packages from this 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 &cont-err; 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

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

## Implementation-Defined Packages

The following additional packages exist:

Implementation-Defined Packages

&clos-pac;

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

&sys-pac;

  has the nickname SYS, 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;): &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.

&cs-cl;
&cs-clu;

  &case-sensitive-k; versions of &cl-pac; and &clu-pac;. See .

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

## Package Case-Sensitivity

&clisp; supports programs written with case sensitive symbols. For example, with case sensitive symbols, the symbols `cdr` (the function equivalent to &rest;) and the symbol `CDR` (a user-defined type denoting a Call Data Record) are different and unrelated.

There are some incompatibilities between programs assuming case sensitive symbols and programs assuming the &ansi-cl; case insensitive symbols. For example, `(eq 'KB 'Kb)` evaluates to false in a case sensitive world and to true in a case insensitive world. However, unlike some commercial &cl; implementations, &clisp; allows both kinds of programs to coexist in the same process and interoperate with each other. Example:

`OLD.lisp`

      (&in-package; "OLD")
      (&defun; FOO () ...)

`modern.lisp`

      (in-package "NEW")
      (defun bar () (old:foo))
      (symbol-name 'bar) ; "bar"

This is achieved through specification of the symbol case policy at the package level. A modern package is one that is declared to be both case-sensitive and case-inverted and which use the symbols from the &cs-cl; package.

&package-t; modern

A case-sensitive package is one whose &defpackage; declaration (or &make-package; creation form) has the option `(&case-sensitive-k; &t;)`. In a case-sensitive package, the reader does ¬-e; uppercase the symbol name before calling &intern;. Similarly, the printer, when printing the &symbol-name; part of a &symbol-t; (i.e. the part after the package markers), behaves as if the readtable's case were set to `:PRESERVE`. See also .

&package-t; case-sensitive

A case-inverted package is one whose &defpackage; declaration (or &make-package; creation form) has the option `(&case-inverted-k; &t;)`. In the context of a case-inverted package, symbol names are case-inverted: upper case characters are mapped to lower case, lower case characters are mapped to upper case, and other characters are left untouched. Every symbol thus conceptually has two symbol names: an old-world symbol name and a modern-world symbol name, which is the case-inverted old-world name. The first symbol name is returned by the function &symbol-name;, the modern one by the function `cs-cl:symbol-name`. The internal functions for creating or looking up symbols in a package, which traditionally took a string argument, now conceptually take two string arguments: old-style-string and inverted-string. Actually, a function like &intern; takes the old-style-string as argument and computes the inverted-string from it; whereas the function `cs-cl:intern` takes the inverted-string as argument and computes the old-style-string from it. See also .

&package-t; case-inverted

For a few built-in functions, a variant for the case-inverted world is defined in the &cs-cl; package, which has the nickname CS-CL:

`cs-cl:symbol-name`

  returns the case-inverted symbol name.

`cs-cl:intern`
`cs-cl:find-symbol`

  work consistently with `cs-cl:symbol-name`.

`cs-cl:shadow`
`cs-cl:find-all-symbols`
`cs-cl:string=`
`cs-cl:string/=`
`cs-cl:string<`
`cs-cl:string>`
`cs-cl:string<=`
`cs-cl:string>=`
`cs-cl:string-trim`
`cs-cl:string-left-trim`
`cs-cl:string-right-trim`

  convert a &symbol-t; to a &string-t; and therefore exist in a variant that uses `cs-cl:symbol-name` instead of &symbol-name;.

`cs-cl:make-package`

  creates a case-inverted &package-t;.

### User Package for the Case-sensitive World

A package &cs-clu; is provided for the user to modify and work in. It plays the same role as &clu-pac;, but for the case-sensitive world.

### Package Names

The handling of package names is unchanged. Package names are still usually uppercase. The package names are also subject to `(&readtable-case; &readtable-var;)`.

### Gensyms and Keywords

Note that gensyms and keywords are still treated traditionally: even in a case-sensitive package,

    (&string-eq; '#:FooBar '#:foobar)
    &t;
    (&eq; ':KeyWord ':keyword)
    &t;

We believe this has a limited negative impact for the moment, but can be changed some time in the future.

### Migration Tips

The following practices will pose no problems when migrating to a modern case-sensitive world:

- Using &ansi-cl; symbols in lowercase.

- Macros that create symbols by suffixing or prefixing given symbols.

- Comparing symbol names as in `(&string-eq; (&symbol-name; &x-r;) (&symbol-name; &y-r;))`.

The following practices will not work in a case-sensitive world or can give problems:

- Accessing the same symbol in both upper- and lowercase from the same source file.

- Macros that create symbols in other packages than the original symbols.

- Comparing &symbol-name; return values with &eq;.

- Comparing `(&symbol-name; x)` with `(cs-cl:symbol-name y)`.

### Using case-sensitive packages by default

&clisp; supports a command-line option &opt-modern; that sets the &package-var; initially to the &cs-clu; package, and &print-case-var; to `:DOWNCASE`.

For packages to be located in the modern (case-sensitive) world, you need to augment their &defpackage; declaration by adding the option `(&modern-k; &t;)`, see .

# Numbers

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

### Numeric Operations

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

Function &mod-expt;

`(&mod-expt; &k-r; &l-r; &m-r;)` is equivalent to `(&mod; (&expt; &k-r; &l-r;) &m-r;)` except it is more efficient for very large arguments.

#### Function &decode-float;

&float-radix; always returns 2.

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

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

#### Boolean Operations

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

#### Byte Operations on Integers

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

#### Floating Point Arithmetics

Function &expt;

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

Function &log;

`(&log; &number-r; &base-r;)` &sig-err; 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 ¬-e; a &constant;.

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 its argument (even though a &complex-t; number in &clisp; can always have ℜ and ℑ of any type) because it allows the most precise type inference.

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;. See also &read-default-float-format-var;.

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;ing an &error-t; of type &floating-point-underflow-t;.

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

### Implementation-Dependent Numeric Constants

#### Fixnum Limits

Fixnum limits

&cpu-type-header;
&most-positive-fixnum; | 224-1 = 16777215 | 248-1 = 281474976710655
&most-negative-fixnum; | -224 = -16777216 | -248 = -281474976710656

#### Bignum Limits

&bignum-t;s are limited in size. Their maximum size is `32*(216-2)=2097088` bits. The largest representable &bignum-t; is therefore `22097088-1`.

#### Float Limits

Together with &pi-v;, the other &long-float-t; 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 ¬-e; &constant;s.

Since the exponent of a &long-float-t; is a signed 32-bits integer, &most-positive-long-float; is about `2231`, which is much larger that the largest representable &bignum-t;, which is less than `2221`. This, obviously, means that &round;, &truncate;, &floor; and &ceiling; &sig-err; on large &long-float-t;s. Less obviously, this means that `(&format; &nil; "&format-e;" &most-positive-long-float;)` also fails.

### Rule of Float Substitutability

When a mathematical function may return an exact (&rational-t;) or inexact (&float-t;) result, it always returns the exact result.

### Floating-point Computations

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, so, to reduce portability problems, &clisp; by design returns the same floating point results on all platforms (&clisp; has a floating-point emulation built in for platforms that do not support &ieee-bfp;). Note that

- When you got a `NaN` in your program, your program is broken, so you will spend time determining where the `NaN` came from. It is better to &signal; an &error-t; in this case.

- When you got unnormalized floats in your program, your results will have a greatly reduced accuracy anyway. Since &clisp; has the means to cope with this - &long-float-t;s of variable precision - it does not need unnormalized floats.

This is why &features-my; does not contain the `:IEEE-FLOATING-POINT` keyword.

Arbitrary Precision Floats

&long-float-t;s 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-float-t;s 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-t;. E.g., `(&setf; (&lfd;) 3322)` sets the default precision of &long-float-t;s to about 1000 decimal digits.

#### Rule of Float Precision Contagion

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-e; `3.25` and nothing else, while the standard way could be lying about the deviation (accuracy): if the implied accuracy of `1.5` (i.e., 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) decided 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 !)

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 high accuracy of a result by giving it a precision that is greater than its accuracy.

Example:

  `(&subt; (+ 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-t; is emitted for every coercion involving different floating-point types. As explained above, float precision contagion is not a good idea. You can avoid the contagion by doing all your computations with the same floating-point type (and using &float; to convert all constants, e.g., &pi-v;, to your preferred type).

This variable helps you eliminate all occurrences of float precision contagion: set it to &t; to have &clisp; &signal; a &warning-t; on float precision contagion; set it to &error; to have &clisp; &signal; an &error-t; on float precision contagion, so that you can look at the stack &backtrace;.

#### Rule of Float and Rational Contagion

The contagion between floating point and rational numbers is controlled by the variable &floratcont;. When it is non-&nil;, contagion is done as per the &ansi-cl;: &rational-t; → &float-t;.

When &floratcont; is &nil;, the traditional &clisp; method is used, namely if the result is mathematically an exact rational number, this rational number is returned (in contrast to !)

&floratcont; has an effect only in those few cases when the mathematical result is exact although one of the arguments is a floating-point number, such as `(☆ 0 1.618)`, `(&slash; 0 1.618)`, `(&atan; 0 1.0)`, `(&expt; 2.0 0)`, `(&phase; 2.718)`.

##### Variable &warn-fprc;

If the variable &warn-fprc; is non-&nil;, a &warning-t; is emitted for every avoidable coercion from a rational number to a floating-point number. You can avoid such coercions by calling &float; to convert the particular rational numbers to your preferred floating-point type.

This variable helps you eliminate all occurrences of avoidable coercions to a floating-point number when a rational number result would be possible: set it to &t; to have &clisp; &signal; a &warning-t; in such situations; set it to &error; to have &clisp; &signal; an &error-t; in such situations, so that you can look at the stack &backtrace;.

##### Variable &phasecont;

A similar variable, &phasecont;, controls the return value of &phase; when the argument is an exact nonnegative &real-t;. Namely, if &phasecont; is non-&nil;, it returns a floating-point zero; if &phasecont; is &nil;, it returns an exact zero. Example: `(&phase; 2/3)`

### Complex Computations

Complex numbers can have a real part and an imaginary part of different types. For example, `(&sqrt; -9.0)` evaluates to the number `&sharp-C;(0 3.0)`, which has a real part of exactly &zero;, not only `0.0` (which would mean approximately 0).

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

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

### Rule of Canonical Representation for Complex Rationals

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

### Random-State Operations

To ease reproducibility, the variable &random-state-var; is initialized to the same value on each invocation, so that

    &sh-prompt; &clisp-cmd; &opt-norc; &opt-x; '(&random; 1s0)'

will always print the same number.

If you want a new random state on each invocation, you can arrange for that by using &init-function;:

    &sh-prompt; &clisp-cmd; &opt-norc; &opt-x; '(&savemem; "foo" :init-function (&lambda-m; () (&setq; &random-state-var; (&make-random-state; &t;))))'
    &sh-prompt; &clisp-cmd; &opt-norc; &opt-M; foo.mem &opt-x; '(&random; 1s0)'

or by placing `(&setq; &random-state-var; (&make-random-state; &t;))` into your &RC-file;.

# Characters

## Introduction to Characters

### Function &char-code;

&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

### Type &base-char-t;

The types EXT:STRING-CHAR and &base-char-t; are equivalent to &character-t;. EXT:STRING-CHAR used to be available as STRING-CHAR prior to removal from &ansi-cl; by &iss026;.

### Function &char-width;

`(&char-width; &ch-r;)` returns the number of screen columns occupied by &ch-r;. The value is

0

  for non-spacing characters (such as control characters and many combining characters);

2

  for double-width East Asian characters;

1

  for all other characters.

See also function &string-width;.

## Character sets

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

&unicode-only;

  More precisely, &clisp; uses the 21-bit &unicode32; character set (ISO 10646, also known as UCS-4).

&non-unicode-only;

  More precisely, &clisp; uses the ISO Latin-1 (ISO 8859-1) character set:

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

  &char-table-legend;

Standard characters

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

Semi-standard characters

&char-code-header;
#\Backspace | #x08
#\Tab | #x09
&lf-s; | #x0A
#\Page | #x0C
&cr-s; | #x0D

&nl-s; 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 .

## Character Scripts

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

## Character Attributes

Characters have no implementation-defined or &cltl1; font and bit attributes. All characters are simple characters.

### Input Characters

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; are equivalent to &eq; on 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; &nval-r;)`

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

&input-char; is ¬-e; a subtype of &character-t;.

&unix-w32-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;)`.

## Graphic Characters

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

## Alphabetic Characters

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

                 ABCDEFGHIJKLMNOPQRSTUVWXYZ
                 abcdefghijklmnopqrstuvwxyz

and the international alphabetic characters from the character set:

                 ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜßáíóúñÑªºãõØøÀÃÕ

etc.

## Characters With Case

### Function &char-invertcase;

`(&char-invertcase; &ch-r;)` returns the corresponding character in the other case for &char;, i.e., &char-upcase; for a lowercase character and &char-downcase; for an uppercase character; for a character that does not have a case attribute, the argument is returned. See also &string-invertcase; and &nstring-invertcase;.

### Case of Implementation-Defined Characters

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

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

## Ordering of Characters

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

The functions &char-equal; &char-not-equal;, &char-lessp;, &char-greaterp;, &char-not-greaterp;, &char-not-lessp; ignore bits and font attributes of their arguments.

## Character Names

Character names of non-&ascii; characters are the names defined by &unicode;, with spaces replaced by underscores, and converted to upper case. There are two exceptions, though:

#\U0001F514

  has the name `UNICODE_BELL`, because the name `BELL` is already taken by the &ascii; control character with code 7 (the audible bell character).

#\U0001F5CF

  has the name `UNICODE_PAGE`, because the name `PAGE` is already taken by the &ascii; control character with code 12 (the form feed or page separator character).

## Treatment of Newline during Input and Output

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:

&win32-only;

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

When reading from a file, &cr-c;/&lf-c; is converted to &nl-s; (the usual convention on &dos;), and &cr-c; not followed by &lf-c; is converted to &nl-s; as well (the usual conversion on MacOS, also used by some programs on &win32;). If you do not want this, i.e., if you really want to distinguish &lf-c;, &cr-c; and &cr-c;/&lf-c;, you have to resort to binary input (function &read-byte;).

Justification

Unicode Newline Guidelines say: Even if you know which characters represents NLF on your particular platform, on input and in interpretation, treat CR, LF, CRLF, and NEL the same. Only on output do you need to distinguish between them.

Rationale

In &clisp;, &nl-s; is identical to &lf-s; (which is specifically permitted by the &ansi-cl; in Character Names). Consider a file containing exactly this string: `(&concatenate; '&string-any; "foo" (&string; &lf-s;) "bar" (&string; &cr-s;) (&string; &lf-s;))` Suppose we open it with `(&open; "foo" &extfmt; &dos-k;)`. What should &read-line; return? Right now, it returns "foo" (the second &read-line; returns "bar" and reaches &eos;). If our i/o were faithful, &read-line; would have returned the string `(&concatenate; '&string-any; "foo" (&string; &lf-s;) "bar")`, i.e., a string with an embedded &nl-s; between "foo" and "bar" (because a single &lf-s; is not a &nl-s; in the specified &extfmt;, it will not make &read-line; return, but it &is-e; a &clisp; &nl-s;!) Even though the specification for &read-line; does not explicitly forbids newlines inside the returned string, such behavior would be quite surprising, to say the least. Moreover, this line (with an embedded &nl-s;) would be written as two lines (when writing to a &stream-t; with &extfmt; of &dos-k;), because the embedded &nl-s; would be written as &cr-c;+&lf-c;.

## Character Encodings

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

## Documentation of Implementation-Defined Scripts

See .

## Platform-Dependent Characters

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

Additional characters (&win32-only;)

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

Additional characters (&unix-only;)

&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-s; | #\Nl | &lf-s;
`(&code-char; #x0B)` | #\Vt
`(&code-char; #x0C)` | #\Page | #\Np
`(&code-char; #x0D)` | &cr-s; | #\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

## Conses as Lists

### Mapping Functions

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

Function &make-array;

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

Function &adjust-array; for displaced arrays

An array to which another array is displaced should not be shrunk (using &adjust-array;) in such a way that the other array points into void space. This cannot be checked at the time &adjust-array; is called!

## Array Elements

Array limits

&cpu-type-header;
&array-rank-limit; | 212 = 4096
&array-dimension-limit; | 224-1 = 16777215 | 232-1 = 4294967295
&array-total-size-limit; | 224-1 = 16777215 | 232-1 = 4294967295

# Strings

## Miscellaneous

### String Comparison

String comparison (&string-lst; and friends) is based on the function &char-leq; (see ). Therefore diphthongs do ¬-e; obey the usual national rules. Example: `o < oe < z < ö`.

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

    (&reduce; #'+ &string-r; &key-k; #'&char-width;)

### Functions &string-invertcase; and &nstring-invertcase;

`(&string-invertcase; &string-r; &key-amp; &start-r; &end-r;)` and `(&nstring-invertcase; &string-r; &key-amp; &start-r; &end-r;)` are similar to &string-upcase; et al: they use &char-invertcase; to invert the case of each characters in the argument string region.

# Sequences

## Additional Functions

### Function `EXT:TRIM-IF`

Function `(`EXT:TRIM-IF` &pred-r; &sequence-r;)` returns the portion of &sequence-r; without the leading and trailing elements which match &pred-r;.

## 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; sequence-form [result-form])
      {&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 &iss283;, 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; accept two additional keyword arguments &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

## Modifying Hash Table Keys

If you visibly modify a key, consequences are unpredictable:

    (&let; ((&ht-r; (&make-hash-table; :test '&equalp;)))
      (&setf; (&gethash; &ht-r; &ht-r;) &t;)
      (&gethash; &ht-r; &ht-r;))
    &nil; ;
    &nil;

because `(&setf; &gethash;)` modifies &ht-r;, the very next &gethash; does ¬-e; find it in itself.

## Function &make-hash-table;

&make-hash-table; accepts two additional keyword arguments `:INITIAL-CONTENTS` and `:WEAK`:

    (&make-hash-table; &key-amp; :TEST :INITIAL-CONTENTS :SIZE
                     :REHASH-SIZE :REHASH-THRESHOLD
                     :WARN-IF-NEEDS-REHASH-AFTER-GC :WEAK)

The &test-k; argument can be, other than one of the symbols &eq;, &eql;, &equal;, &equalp;, one of the symbols &fasthash-eq; and &stablehash-eq;. Both of these tests use &eq; as the comparison function; they differ in their performance characteristics.

&fasthash-eq;

  This uses the fastest possible hash function. Its drawback is that its hash codes become invalid at every &gc;ion (except if all keys are &immediate-o;s), thus requiring a reorganization of the hash table at the first access after each &gc;ion. Especially when generational &gc;ion is used, which leads to frequent small &gc;ions, large hash table with this test can lead to scalability problems.

&stablehash-eq;

  This uses a slower hash function that has the property that its hash codes for instances of the classes &symbol-t;, &standard-stablehash; (subclass of &standard-object-t;) and &structure-stablehash; (subclass of &structure-object-t;) are stable across GCs. This test can thus avoid the scalability problems if all keys, other than &immediate-o;s, are &symbol-t;, &standard-stablehash; or &structure-stablehash; instances.

One can recommend to use &fasthash-eq; for short-lived hash tables. For tables with a longer lifespan which can be big or accessed frequently, it is recommended to use &stablehash-eq;, and to modify the objects that are used as its keys to become instances of &standard-stablehash; or &structure-stablehash;.

When the symbol &eq; or the function `#'eq` is used as a &test-k; argument, the value of the variable `CUSTOM:*EQ-HASHFUNCTION*` is used instead. This value must be one of &fasthash-eq;, &stablehash-eq;.

*EQ-HASHFUNCTION*

Similarly, the &test-k; argument can also be one of the symbols `EXT:FASTHASH-EQL`, `EXT:STABLEHASH-EQL`, `EXT:FASTHASH-EQUAL`, `EXT:STABLEHASH-EQUAL`. The same remarks apply as for &fasthash-eq; and &stablehash-eq;. When the symbol &eql; or the function `#'eql` is used as a &test-k; argument, the value of the variable `CUSTOM:*EQL-HASHFUNCTION*` is used instead; this value must be one of `EXT:FASTHASH-EQL`, `EXT:STABLEHASH-EQL`. Similarly, when the symbol &equal; or the function `#'equal` is used as a &test-k; argument, the value of the variable `CUSTOM:*EQUAL-HASHFUNCTION*` is used instead; this value must be one of `EXT:FASTHASH-EQUAL`, `EXT:STABLEHASH-EQUAL`.

*EQL-HASHFUNCTION*
*EQUAL-HASHFUNCTION*

The `:WARN-IF-NEEDS-REHASH-AFTER-GC` argument, if true, causes a &warning-t; to be &signal;ed when an object is stored into the table which will force table reorganizations at the first access of the table after each &gc;ion. This keyword argument can be used to check whether &stablehash-eq; should be preferred over &fasthash-eq; for a particular table. Use `HASH-TABLE-WARN-IF-NEEDS-REHASH-AFTER-GC` to check and &setf; this parameter after the table has been created.

The `:INITIAL-CONTENTS` argument is an &alist; that is used to initialize the new hash table.

The `:REHASH-THRESHOLD` argument is ignored.

The `:WEAK` argument can take the following values:

- &nil; (default)
- &key-k;
- &value-k;
- &key-and-value-k;
- &key-or-value-k;

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.

Note that the only test that makes sense for weak hash tables are &eq; and its variants &fasthash-eq; and &stablehash-eq;.

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

See also .

### Interaction between &hash-table-t;s and &gc;ion

When a hash table contains keys to be compared by identity - such as &number-t;s in &hash-table-t;s with the &hash-table-test; &eq;; or &cons-t;es in tables which test with &eq; or &eql;; or &vector-t;s in tables which test with &eq;, &eql; or &equal;; or &standard-object-t; or &structure-object-t; instances in tables which test with &eq;, &eql;, &equal; or &equalp;; - the hash code will in general depend on the object's address in memory. Therefore it will in general be invalidated after a &gc;ion, and the hash table's internal structure must be recomputed at the next table access.

While `:WARN-IF-NEEDS-REHASH-AFTER-GC` can help checking the efficiency of a particular &hash-table-t;, the variable &warn-on-hashtable-needing-rehash-after-gc; achieves the same effect for all &hash-table-t;s in the system at once: when &warn-on-hashtable-needing-rehash-after-gc; is true and a &hash-table-t; needs to be rehashed after a &gc;ion, a warning is issued that shows the inefficient &hash-table-t;.

*WARN-ON-HASHTABLE-NEEDING-REHASH-AFTER-GC*

What can be done to avoid the inefficiencies detected by these warnings?

1. In many cases you can solve the problem by using the `STABLEHASH` variant of the hash test.

2. In other cases, namely &standard-object-t; or &structure-object-t; instances, you can solve the problem by making the key object classes inherit from &standard-stablehash; or &structure-stablehash;, respectively.

3. In the remaining cases, you should store a hash key inside the object, of which you can guarantee uniqueness through your application (for example the ID of an object in a database, or the serial number of an object), and use this key as hash key instead of the original object.

## Macro &defhash;

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

    (&defhash; string &string-eq; &sxhash;)
    STRING
    (&make-hash-table; :test 'string)
    #S(HASH-TABLE :TEST (#<SYSTEM-FUNCTION STRING=> . #<SYSTEM-FUNCTION SXHASH>))

(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;)broken!

is ¬-e; correct because

    (&areq; 1 1d0)
    &t;same object!
    (&areq; (&sxhash; 1) (&sxhash; 1d0))
    &nil;different buckets!

The correct way is, e.g.:

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

Note that &coerce;ing to a &short-float-t; does ¬-e; cons up &fresh; objects while &coerce;ing to a &double-float-t; does.

## Function &hash-table-test;

Function &hash-table-test; returns either one of

- &fasthash-eq;
- &stablehash-eq;
- `EXT:FASTHASH-EQL`
- `EXT:STABLEHASH-EQL`
- `EXT:FASTHASH-EQUAL`
- `EXT:STABLEHASH-EQUAL`
- &equalp;

(but ¬-e; &eq;, &eql; nor &equal; anymore), 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

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

&unix-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;.

&win32-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;.

&win32-cygwin-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-lisp; 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

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.

### Directory canonicalization

As permitted by the &make-pathname; specification, the &pathname-t; directory component is canonicalized when the pathname is constructed:

1. `""` and `"."` are removed

2. `".."`, `"*"`, and `"**"` are converted to `:UP`, &wild-k; and &wild-inferiors-k;, respectively

3. patterns `foo/../` are collapsed

### Platform-specific issues

&unix-only;
  &path-comps;
  &host-r;
  &always-nil;
  &device-r;
  &always-nil; &unix-win32-dir-name-type-version;

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

&win32-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;

  &unix-win32-dir-name-type-version;

  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 &dir-r;'s &startpoint-r; is not &absolute-k;, `(&parse-namestring; (&namestring; &path-r;))` will not be the same as &path-r;.

&unix-w32-only;

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

Name/type namestring split

&unix-w32-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")`.

## :UNSPECIFIC as a Component Value

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;, although it &is-e; a legal argument (treated as &nil;) to &user-homedir-pathname;.

The only use for `:UNSPECIFIC` is that it is returned by &pathname-device; for &logical-pathname-t;s, as required by .

## External notation

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

&unix-only;

  [ &file-slash; ] | &file-slash; denotes absolute pathnames
  { &name-r; &file-slash; } | each &name-r; is 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; &character-t;s, except &file-slash;).

&win32-only;

  [ [drivespec] : ] | a letter &file-star;|&file-letter-lc;|&file-letter-uc;
  { &name-r; [. &type-r;] \ } | each &name-r; is 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; &character-t;s, except &file-slash;, &file-bsla;, &file-colon;).

## Logical Pathnames

No notes.

## Miscellaneous

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-match-p;

&pathname-match-p; does not interpret missing components as wild.

### Function &translate-pathname;

&translate-pathname; accepts three additional keyword arguments: `(&translate-pathname; &source-r; from-wildname to-wildname &key-amp; &all-k; &merge-k; &absolute-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;.

If &absolute-k; is specified and non-&nil;, the returned pathnames are converted to absolute by merging in the current process' directory, therefore rendering pathnames suitable for the OS and external programs. So, to pass a pathname to an external program, you do `(&namestring; (&translate-pathname; &path-r; #P"" #P"" &absolute-k; &t;))` or `(&namestring; (&absolute-pathname; &path-r;))`.

### Function &translate-logical-pathname;

&translate-logical-pathname; accepts an additional keyword argument &absolute-k;, similar to .

### 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;. Note that this also disables treating &symbol-t;s as &path-des;s.

### Function &merge-pathnames;

`(&merge-pathnames; &path-r; [default-pathname])` returns a logical pathname only if default-pathname is a &logical-pathname-t;. To construct a logical pathname from a &string-t;, 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;. In fact, the above twice-default = once-default rule holds for all pathnames in &clisp;.

Conversely, 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-t; of files and/or directories, which are searched for in the &load-paths;, just like for &load-my;. When the element is a file, it is repeatedly &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;.

### Function &absolute-pathname;

`(&absolute-pathname; &path-r;)` converts the &path-r; to a physical pathname, then - if its directory component is not absolute - converts it to an absolute pathname, by merging in the current process' directory. This is like &truename;, except that it does not verify that a file named by the &path-r; exists, not even that its directory exists. It does no filesystem accesses, except to determine the current directory. This function is useful when you want to save a pathname over time, or pass a pathname to an external program.

# Files

## Directory is ¬-e; a file

&clisp; has traditionally taken the view that a directory is a separate object and ¬-e; a special kind of file, so whenever the standard says that a function operates on files without specifically mentioning that it also works on directories, &clisp; &sig-err; when passed a directory.

&clisp; provides separate directory functions, such as &delete-dir;, &rename-dir; et al.

You can use &directory; or &probe-path; to figure out whether a given namestring refers to a file or a directory.

### Function &probe-path;

Function `(&probe-path; &path-r; &key-amp; (&error-k; &t;))` figures out whether the argument refers to an existing directory or an existing regular file, and returns 4 values if the filesystem object exists:

1. &truename;

2. &absolute-pathname;

3. &file-write-date;

4. &file-size;

or &nil; if it does not exist. E.g., if you have a file &file-r;, a directory &dir-r;, a symbolic link `link-file` pointing to &file-r; and a symbolic link `link-dir` pointing to &dir-r;, then

    (&probe-path; #P"filename")
    #P"/.../filename"
    #P"/.../filename"
    3427467015
    3171976
    (&probe-path; #P"filename/")
    #P"/.../filename"
    #P"/.../filename"
    3427467015
    3171976
    (&probe-path; #P"directory")
    #P"/.../directory/"
    #P"/.../directory/"
    3426940352
    1024
    (&probe-path; #P"directory/")
    #P"/.../directory/"
    #P"/.../directory/"
    3426940352
    1024
    (&probe-path; #P"link-file")
    #P"/.../filename"
    #P"/.../link-file"
    3427467015
    3171976
    (&probe-path; #P"link-file/")
    #P"/.../filename"
    #P"/.../link-file"
    3427467015
    3171976
    (&probe-path; #P"link-dir")
    #P"/.../directory/"
    #P"/.../link-dir/"
    3426940352
    1024
    (&probe-path; #P"link-dir/")
    #P"/.../directory/"
    #P"/.../link-dir/"
    3426940352
    1024

This function may also &sig-err; if, e.g., its argument resides under a tree for which you do not have sufficient access privileges; unless &error-k; is &nil;, in which case &nil; is returned instead.

## File functions

### Function &probe-file;

&probe-file; cannot be used to check whether a directory exists. Use functions &probe-dir;, &probe-path; 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.

Use `OS:FILE-OWNER` to find the owner of the file. See also `OS:FILE-PROPERTIES` (&win32-only;).

### 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 &err-sig;. To remove a directory, use &delete-dir; instead.

### Function &rename-file;

This functions accepts and extra keyword argument &if-exists;. When it is &error-k; (the default), an &err-sig; if the destination pathname names an existing file, otherwise (e.g., if it is &overwrite-k;) the destination file atomically overwritten.

When &ansi; is non-&nil;, only the standard two arguments are accepted, and and &err-sig; when the destination pathname names an existing file.

This function cannot operate on directories, use &rename-dir; to rename a directory.

## Directory functions

### 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 &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 you want &all-e; the files &and-e; 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; "**/*"))`.

Keyword arguments accepted by &directory;

`:FULL`

  If this argument is non-&nil;, additional information is returned: for each matching file you get a &list-t; of at least four elements (file-pathname file-truename file-write-date-as-decoded-time file-length).

`:CIRCLE`

  If this argument is non-&nil;, &directory; avoids endless loops that may result from symbolic links.

&if-does-not-exist;

  This argument 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;

    an &err-sig; 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-k;

    Similar to `:DISCARD`, but also do ¬-e; &signal; an &error-t; 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 the current working directory, `(&cd;)` returns it.

&unix-only;

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

&win32-only;

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

### Function &default-dir;

`(&default-dir;)` is equivalent to `(&cd;)`. `(&setf; (&default-dir;) &path-r;)` is equivalent to `(&cd; &path-r;)`, except for the return value.

### Function `EXT:MAKE-DIRECTORY`

`(`EXT:MAKE-DIRECTORY` &dir-r;)` creates a new subdirectory.

### Function &delete-dir;

`(&delete-dir; &dir-r;)` removes an (empty) subdirectory.

### Function &rename-dir;

`(&rename-dir; old-directory new-directory)` renames a subdirectory to a new name.

# Streams

## Interactive Streams

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

### Initialization of Standard Streams

When run interactively, &clisp; creates a single terminal &stream-t; and binds &terminal-io-var; to it. All other standard streams (&standard-input-var;, &standard-output-var; &error-output-var;, &trace-output-var;, &query-io-var;, &debug-io-var;) are &synonym-stream-t;s pointing to &terminal-io-var;. This has the benefit of avoiding unwanted blank lines from &fresh-line;, see .

However, there may be situations, especially in &batch-mode;, when one wants to use a &c-lang;-style i/o where &standard-output-var; and &error-output-var; point to different OS &file-des; so that they can be redirected to files in the command line and examined separately. Often &clisp; can detect such situations (&stdout; and &stderr; not being the terminal) and handle them just as expected. However, there may be cases when one needs to do something like:

    (&setq; &standard-input-var; (&make-stream; &input-k;)
          &standard-output-var; (&make-stream; &output-k; &buffered; &t;)
          &error-output-var; (&make-stream; &error-k; &buffered; &t;))

in the &script; or &init-function;.

## Terminal interaction

See also .

### Command line editing with &readline;

Only in &clisp; linked against the &readline; library.

Input through &terminal-io-var; uses the &readline; library. Arrow keys can be used to move within the input history. The &tab-c; key completes the &symbol-t; name or &pathname-t; that is being typed. See readline user manual for general details and for &clisp;-specific extensions.

The &readline; library is ¬-e; used (even when &clisp; is linked against it) if the &stdin; and &stdout; do not both refer to the same terminal. This is determined by the function `stdio_same_tty_p` in file `src/stream.d`. In some exotic cases, e.g., when running under &gdb; in an `rxvt` window under &cygwin;, this may be determined incorrectly.

See also .

#### Extending completion

Variable `CUSTOM:*COMPLETION*`

The value should be a &function-t; of 3 arguments: &string-r;, &start-r; and &end-r;, which bound the text to be completed. The return value should be the list, whose &first; is the immediate replacement for the already typed text and &rest; is all the possible completions. If no completions are available, return &nil;.

Function `EXT:MAKE-COMPLETION`

Given a &list-t; of all valid inputs, return a valid value for `CUSTOM:*COMPLETION*`.

Function `EXT:LONGEST-COMMON-PREFIX`

Given a &list-t; of &vector-t;s, return the &vector-t; which is their longest common prefix. &vector-t; elements are compared using the &test-k; argument. Useful when writing your own `CUSTOM:*COMPLETION*` functions.

Dialog with user using completion

    (defun read-user-line (prompt completions)
      (princ prompt *query-io*)
      (force-output *query-io*)
      (let ((custom:*completion* (ext:make-completion completions)))
        (read-line *query-io*)))
    (read-user-line "??? " '("a" "z123" "z135" "b" "abcd"))
    ??? ab TAB
    ??? abcd
    (read-user-line "??? " '("a" "z123" "z135" "b" "abcd"))
    ??? TAB TAB
    a abcd b z123 z135
    ??? z TAB
    ??? z1TAB TAB
    z123 z135

To force the user to select one of the pre-specified inputs you need to do something like this:

    (defun read-user-line (prompt)
      (princ prompt *query-io*)
      (force-output *query-io*)
      (read-line *query-io*))
    (defun read-user-option (prompt options)
      (loop
        :with custom:*completion* = (ext:make-completion options)
        :for option = (read-user-line prompt)
        :when (find option options :text #'string=)
        :return options
        :do (format *query-io* "Invalid option ~S, please try again~%" option)))

#### Linking against &readline;

For &clisp; to use &readline; it has to be detected by the &configure; process.

- If you run it as

      &sh-prompt; ./configure --with-readline

  it will fail if it cannot find a valid modern &readline; installation.

- If you use the option `--without-readline`, it will not even try to find &readline;.

- The default behavior (`--with-readline=default`) is to use &readline; if it is found and link &clisp; without it otherwise.

You can find out whether &readline; has been detected by running

    &sh-prompt; grep HAVE_READLINE config.h

in your build directory.

### Macro &with-kbd;

&unix-w32-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-t; that reads the keystrokes from the keyboard. It returns every keystroke in detail as an &input-char; with the following slots (see for accessing them):

&ch-r;

  the &character-t; for standard keys (accessed with &character;)

  For non-standard keys &character; &sig-err;, use &char-key;:

      (&with-kbd;
       (&loop; :for &ch-r; = (&read-char; &kbd-in;)
         :for &key-r; = (&or-m; (&char-key; &ch-r;) (&character; &ch-r;))
         :do (&print; (&list; &ch-r; &key-r;))
         :when (&eql; &key-r; #\Space) :return (&list; &ch-r; &key-r;)))

&key-r;

  the key name, for non-standard keys (accessed with &char-key;):

  &unix-w32-only;

    &key-value-header;
    F1..F12 | `:F1`..`:F12`
    Insert | `:INSERT`
    Delete | `:DELETE`
    Home | &home-k;
    End | &end-k;
    Center | `:CENTER`
    PgUp | `:PGUP`
    PgDn | `:PGDN`
    Arrow keys | `:LEFT` `:RIGHT` `:UP` `:DOWN`

bits

  &hyper-k;

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

  &super-k;

    (&win32-only;) if pressed together with &shift; key(s) and if the keystroke would have been different without &shift;.

  &control-k;

    if pressed together with the &ctrl; key.

  &meta-k;

    (&win32-only;) if pressed together with the &alt; key.

font

  Always &zero;.

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.

Since &input-char; is ¬-e; a subtype of &character-t;, &read-line; on &kbd-in; is illegal.

## Binary Input and Output

### 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;, which should be a &stream-t; with &stream-element-type; &ubyte-8;. &eltype-r; should be &type-eq; to &ubyte-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;, which should be a &stream-t; with &stream-element-type; &ubyte-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;.

endianness

### 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-t; to &stream-r;, which should be a &stream-t; with &stream-element-type; &ubyte-8;. &eltype-r; should be &type-eq; to &ubyte-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;, which should be a &stream-t; with &stream-element-type; &ubyte-8;. &eltype-r; should be &type-eq; to &single-float-t; or &double-float-t;.

## Bulk Input and Output

### Bulk Input

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 :INTERACTIVE)` 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;, it does not block: it treats input unavailability as &eos;. When &no-hang; is &nil; and &interactive-r; is non-&nil;, it can block for reading the first byte but does not block for any further bytes.

  This function is especially efficient if &sequence-r; is a &ubyte-vec; and &stream-r; is a &file-pipe-socket-s; with &stream-element-type; &ubyte-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-r; is a &file-pipe-socket-s; with &stream-element-type; &character-t; or an &input-s; &string-stream-t;.

### Bulk Output

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; :NO-HANG :INTERACTIVE)` outputs the &integer-t;s of the subsequence of &sequence-r; specified by &start-k; and &end-k; to &stream-r;. When &no-hang; is non-&nil;, does not block. When &no-hang; is &nil; and &interactive-r; is non-&nil;, it can block for writing the first byte but does not block for any further bytes. Returns two values: &sequence-r; and the index of the first byte that was not output.

  This function is especially efficient if &sequence-r; is a &ubyte-vec; and &stream-r; is a &file-pipe-socket-s; with &stream-element-type; &ubyte-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-r;. Returns the &sequence-r; argument.

  This function is especially efficient if &sequence-r; is a &string-t; and &stream-r; is a &file-pipe-socket-s; 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 `(¬-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 &ubyte-8; or &sbyte-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 &ubyte-8; or &sbyte-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 &ubyte-8; or &sbyte-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.

&listen; on binary streams

The &ansi-cl; specification for &listen; mentions character availability as the criterion that determines the return value. Since a &character-t; is never available on a binary &stream-t; (i.e., a stream with &stream-element-type; being a subtype of &integer-t;), &listen; returns &nil; for such streams. (You can use &so-status; to check binary streams). Any other behavior would be hard to make consistent: consider a bivalent stream, i.e., a &stream-t; that can be operated upon by both &read-char; and &read-byte;. What should &listen; return on such a stream if what is actually available on the stream at the moment is only a part of a multi-byte character? Right now one can use first &so-status; to check if anything at all is available and then use &listen; to make sure that a full &character-t; is actually there.

## Newline Convention

### Should programs output a newline before or after each line of output?

The answer is complicated. There is an antagonism between the old Lisp way of outputting a newline before the line's contents (exemplified by the functions &print; and &pprint;) and the Unix way of outputting a newline after the line's contents. Which one is right?

A newline convention is, by definition, a consistent way to use the &terpri; and &fresh-line; functions or - in &format; notation - &format-percent; and &format-amp; directives in such a way that the resulting output is properly subdivided into lines.

Three newline conventions are conceivable:

1. Print a newline before the line, and nothing after it. As a format string: ~%First line.~%Second line.

2. Print a newline if needed before the line, and a newline always after it. As a format string: ~&First line.~%Second line.~%

3. Print nothing before the line, and a newline always after it. As a format string: First line.~%Second line.~%

The most important criterion is interoperability. Two newline conventions are interoperable if, when parts of a program use one of the convention and other parts of the program use the other conventions, lines are still properly separated. It is easily seen that &nlcA; and &nlcB; are interoperable, &nlcB; and &nlcC; are interoperable as well, but &nlcA; and &nlcC; are not interoperable: When an output with convention &nlcA; is followed by output in convention &nlcC;, two lines are appended without a line separator. This should not happen.

Therefore, in what follows, we consider five kinds of programs:

- &nlcA;: using convention &nlcA; exclusively,

- &nlcAB;: mixing conventions &nlcA; and &nlcB;,

- &nlcB;: using convention &nlcB; exclusively,

- &nlcBC;: mixing conventions &nlcB; and &nlcC;,

- &nlcC;: using convention &nlcC; exclusively.

Which of these five kinds of programs operation is satisfactory? Let us consider different criteria:

1. Do extra blank lines occur during normal operation?

2. What happens if &fresh-line; prints a newline when it is not needed, i.e. when it cannot tell for sure whether the current column is 0? (This situation happens, for example, when logging to a file: After the user has entered a line interactively, the column on screen is 0, but since the input has not been echoed in the log file, the column in the log file is usually not 0, and &fresh-line; &must-e; output a newline. Then a blank line is visible on the screen.)

3. What happens if &fresh-line; omits a newline when it would be needed? (This is more rare, but can happen, for example, when standard output and standard error are different streams but are joined outside the Lisp implementation, at the OS level. Such as in `lisp | cat`.)

4. Is it possible to reliably output a blank line before or after a paragraph of text? I.e. what happens with

   1. 1. ~%~%First line.~%Second line.

      2. ~%First line.~%Second line.~%

   2. 1. ~&~%First line.~%Second line.~%

      2. ~&First line.~%Second line.~%~%

   3. 1. ~%First line.~%Second line.~%

      2. First line.~%Second line.~%~%

5. Is it possible to optimize away blank lines? I.e. is it possible to avoid a blank line even though another piece of code uses one of A1 ... C2, without risking that adjacent lines be unseparated?

### Analysis

1. - &nlcA;: No extra blank lines.

   - &nlcAB;: An extra blank line each time one switches from convention &nlcB; to &nlcA;.

   - &nlcB;: No extra blank lines.

   - &nlcBC;: No extra blank lines.

   - &nlcC;: No extra blank lines.

2. - &nlcA;: No extra blank lines.

   - &nlcAB;: Blank lines can occur when convention &nlcB; is used.

   - &nlcB;: Blank lines can occur.

   - &nlcBC;: Blank lines can occur when convention &nlcB; is used.

   - &nlcC;: No extra blank lines.

3. - &nlcA;: No problem.

   - &nlcAB;: Lines can be unseparated when one switches from convention &nlcA; to &nlcB;.

   - &nlcB;: No problem.

   - &nlcBC;: No problem.

   - &nlcC;: No problem.

4. - &nlcA;: No problem.

   - &nlcAB;: The blank line is omitted when using A2 before switching to &nlcB;.

   - &nlcB;: No problem.

   - &nlcBC;: No problem.

   - &nlcC;: No problem.

5. - &nlcA;: Yes, using ~&First line.~%Second line. eats a previous blank line.

   - &nlcAB;: Not really: Using ~&First line.~%Second line. may eat a previous blank line or a following blank line, but you cannot know in advance which one.

   - &nlcB;: Yes, using ~&First line.~%Second line. eats a following blank line.

   - &nlcBC;: Impossible.

   - &nlcC;: Impossible. To optimize blank lines in case &nlcC; would require the opposite of &fresh-line;, namely a conditional newline that is annullated if the next output on the stream will be a newline. (&elastic-newline;, see below.)

### Conclusion

Each approach has its advantages and disadvantages.

When used globally (i.e. no interoperability requirements), &nlcA;, &nlcB;, &nlcC; can be compared as follows:

- &nlcA; and &nlcC; are equally perfect if eating blank lines is not a requirement.

- If eating blank lines is desirable, &nlcA; is perfect.

- &nlcB; is not so good, because it is suboptimal in case 2.

For &clisp; built-ins, however, the interoperability requirement with both &nlcA; and &nlcC; is a major requirement. Therefore we have to choose &nlcB;, and accept the drawbacks:

- &nlcAB;: An extra blank line each time one switches from convention &nlcB; to &nlcA;.

- &nlcB;: When logging to a file, blank lines can occur.

- &nlcAB;: When joining two output streams into one, lines can be unseparated.

- &nlcAB;: Blank lines after a paragraph can be eaten by &clisp;.

- &nlcAB;: Optimizing blank lines is not really possible.

And to minimize the drawbacks, we recommend the user programs to use approach &nlcB; or &nlcC;, but not &nlcA;.

Another drawback of &nlcB; is, however, that in interactive sessions the cursor is nearly always positioned at the beginning of a line, pointing the user's focus to the wrong point and taking away a screen line.

### Solution

To solve this, we introduce the concept of an elastic newline, output by the function &elastic-newline;. This is the converse of &fresh-line;: It waits for the next character and outputs a newline when the next character is not a newline; then the next character is processed normally. As a &format; directive, we write it &format-dot;. &elastic-newline; followed by &fresh-line; leads to exactly one newline always.

Elastic newline leads to a slightly different newline convention:

- &nlcBp;: Print a newline if needed before the line, and a newline if needed after it. As a format string: ~&First line.~%Second line.~.

The five programs being considered are now:

- &nlcA;: using convention &nlcA; exclusively,

- &nlcABp;: mixing conventions &nlcA; and &nlcBp;,

- &nlcBp;: using convention &nlcBp; exclusively,

- &nlcBpC;: mixing conventions &nlcBp; and &nlcC;,

- &nlcC;: using convention &nlcC; exclusively,

### Elastic Newline Analysis

1. - &nlcA;: No extra blank lines.

   - &nlcABp;: No extra blank lines.

   - &nlcBp;: No extra blank lines.

   - &nlcBpC;: No extra blank lines.

   - &nlcC;: No extra blank lines.

2. - &nlcA;: No extra blank lines.

   - &nlcABp;: Blank lines can occur when convention &nlcBp; is used.

   - &nlcBp;: Blank lines can occur.

   - &nlcBpC;: Blank lines can occur when convention &nlcBp; is used.

   - &nlcC;: No extra blank lines.

3. - &nlcA;: No problem.

   - &nlcABp;: Lines can be unseparated when one switches from convention &nlcA; to &nlcBp;.

   - &nlcBp;: Lines can be unseparated when one switches from one stream to another without performing a &force-output;. This is a general problem with buffered streams; &clisp;'s &fresh-line; contains a workaround that is limited to &standard-output-var; and &error-output-var;.

   - &nlcBpC;: No problem.

   - &nlcC;: No problem.

4. - &nlcA;: No problem.

   - &nlcABp;: The blank line is omitted when using A2 before switching to &nlcBp; or when using B2 before switching to &nlcA;.

   - &nlcBp;: No problem.

   - &nlcBpC;: No problem.

   - &nlcC;: No problem.

5. - &nlcA;: Yes, using ~&First line.~%Second line. eats a previous blank line.

   - &nlcABp;: Not really: Using ~&First line.~%Second line. may eat a previous blank line or a following blank line, but you cannot know in advance which one.

   - &nlcBp;: Yes, using ~&First line.~%Second line. eats a following blank line.

   - &nlcBpC;: Impossible.

   - &nlcC;: Yes, using First line.~%Second line.~. eats a following blank line.

Now criterium 1 is satisfied perfectly. We therefore choose &nlcBp;, not &nlcB;, for use inside &clisp;, and programs can use either &nlcA; or &nlcC; without problems during normal operation.

## Function &stream-external-format;

&stream-external-format; is &setf;able: `(&setf; (&stream-external-format; &stream-r; [&direction-r;]) &encoding-r;)`, &direction-r; can be &input-k;, &output-k;, or &nil;. If no &direction-r; is given, the operation is nonrecursive.

This will ¬-e; work on &terminal-io-var; et al, use &term-enc; instead.

## 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 &ubyte-8; or &sbyte-8;; or

- both equivalent to &ubyte-n; or &sbyte-n;, with the same &n-r;.

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

&clisp; expects to be able to do &character-t; i/o on standard streams like &terminal-io-var;, &standard-output-var;, &standard-input-var;, &error-output-var;, &query-io-var; et al, thus it is a &very-e; bad idea to change their &stream-element-type; even when you can. Use &make-stream; instead, see .

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

Since CGI (Common Gateway Interface) provides the form data for `METHOD="POST"` on the &stdin;, and the server will ¬-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 '&ubyte-8;)))
      (&with-open-stream; (in (&make-stream; &input-k; &eltype; '&ubyte-8;))
        (&read-sequence; buf in))
      buf)

## Function &make-stream;

Function &make-stream; creates a Lisp stream out of an OS &file-des;: `(&make-stream; &object-r; &key-amp; &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, that is, the &file-des; corresponding to &stdin; (0 on &unix;)

&output-k;

  denotes &clisp; process standard output, that is, the &file-des; corresponding to &stdout; (1 on &unix;)

&error-k;

  denotes &clisp; process error output, that is, the &file-des; corresponding to &stderr; (2 on &unix;)

&stream-t;

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

Beware of buffering!

When there are several Lisp &stream-t;s backed by the same OS &file-des;, the behavior may be highly confusing when some of the Lisp streams are &buffered;. Use &force-output; for &out-s;s, and bulk input for &in-s;s.

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

## Function &file-position;

&file-position; works on any &file-stream-t;.

&win32-only;

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

## Function &elastic-newline;

The function `(&elastic-newline; [&stream-r;])` is like &fresh-line; but the other way around: It outputs a conditional newline on &stream-r;, which is canceled if the next output on &stream-r; happens to be a newline. More precisely, it causes a newline to be output right before the next character is written on &stream-r;, if this character is not a newline. The newline is also output if the next operation on the stream is &fresh-line;, &finish-output;, &force-output; or &close;.

The functionality of &elastic-newline; is also available through the &format; directive &format-dot;.

A technique for avoiding unnecessary blank lines in output is to begin each chunk of output with a call to &fresh-line; and to terminate it with a call to &elastic-newline;.

See also .

## Function &open;

&open; accepts an additional keyword &buffered;.

The acceptable values for the arguments to the &file-pipe-socket-s; functions

&eltype;

  types equivalent to &character-t; or &ubyte-n;, &sbyte-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.

  See also .

&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;. This argument determines how the lisp &character-t; data is converted to/from the 8-bit bytes that the underlying OS uses.

  See also .

&buffered;

  &nil;, &t;, or &default-k;. Have &clisp; manage an internal buffer for input or output (in addition to the buffering that might be used by the underlying OS). Buffering is a known general technique to significantly speed up i/o.

  - for functions that create &socket-stream;s and pipes, &default-k; is equivalent to &t; on the input side and to &nil; on the output side; if you are transmitting a lot of data then using buffering will significantly speed up your i/o;

  - 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 out there!

### Variable &reopen;

When an already opened file is opened again, and ¬-e; both the existing and the new &stream-t;s are read-only (i.e., &direction-k; is &input-k; or `:INPUT-IMMUTABLE`), the streams can mess up each other and produce unexpected results. The user variable &reopen; controls how &clisp; handles the situation and can take 4 values:

&nil;

  do nothing: do not even check that there are other &stream-t;s pointing to the same file

&warn;

  &signal; a &warning-t; and proceed

&close;

  &close; the other &stream-t;s and proceed (this could be dangerous and is not generally recommended)

&error; (default)

  &signal; a &cont-err;

## Function &clear-input;

Calling &clear-input; on a &stream-t; removes the &eos; state, thus making it available for further input.

This allows reading from a file as it is being appended to, as if with `tail -f`.

## Function &close;

Function &close; is a &generic-function-t;, see .

When the &abort-k; argument is non-&nil;, &close; will not &sig-err; even when the underlying OS call fails.

&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 (with `(&close; &stream-r; &abort-k; &t;)`). This is ¬-e; 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 .

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

MAKE-BUFFERED-INPUT-STREAM
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; discards the characters collected so far.

`(EXT:MAKE-BUFFERED-INPUT-STREAM &func-r; &mode-r;)`

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 by the user. &func-r; should copy the &string-r; with ©-seq; or &subseq; before returning if the original &string-r; is to be modified. &mode-r; 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.

## Function `EXT:STREAM-HANDLES`

The function `(EXT:STREAM-HANDLES &stream-r;)` returns two values:

1. The OS &file-des; for the &input-s; side of the &stream-r;, or &nil; if the &stream-r; is an &output-s;-only &stream-t; or if there is no &file-des; associated with it.

2. The OS &file-des; for the &output-s; side of the &stream-r;, or &nil; if the &stream-r; is an &input-s;-only &stream-t; or if there is no &file-des; associated with it.

It is dangerous to &close; the &file-des;s returned by this function. This may lead to `EBADF` OS &error-t;s and, eventually, segmentation faults. Always use &close; on the original Lisp &stream-r;s instead.

# Printer

## Multiple Possible Textual Representations

### 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;, a readable syntax is used for closures:

interpreted closures

  &sharp-S;(&function-t; ...)

compiled closures

  `#Y(...)` (this is what you would see if you open a &clisp; &fasl-file; in a text editor)

This feature is turned off by &with-standard-io-syntax; because it is easy to get wrong (see below) and non-portable.

Closures often refer to value cells or other entities from the &lex-env;. The correct operation of a &function-t; may depend on the access to the same value cells as some other, related &function-t;s. If you want to &write; and &read; back &function-t;s so that their semantics is preserved, you have to &write; and &read; &all-e; &function-t;s that share some structure in the &lex-env; together, and you have to either bind &print-readably-var; to &t; or use &with-standard-io-syntax;:

    (&setf; (&values; my-pop my-push)
          `(&let; ((storage ()))
             (&values; (&lambda-m; () (&pop; storage))
                     (&lambda-m; (x) (&push; x storage)))))
    (&let; ((pair (&read-from-string;
                 (&with-standard-io-syntax;
                   (&let; ((&pr-closure; &t;))
                     (&prin1-to-string; (&cons; my-pop my-push)))))))
       (&setq; my-pop-1 (&car; pair)
             my-push-1 (&cdr; pair)))

Note that `my-pop` and `my-push` share environment between themselves but ¬-e; with `my-pop-1` and `my-push-1` which can be easily seen if you do

    (&let; ((&pr-closure; &t;) (&print-circle-var; &t;))
      (&print; (&list; my-pop my-push my-pop-1 my-push-1)))

but which is not at all obvious from the usual &sharp-lt; output.

&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-s;, then a &nl-s; is printed before the object. E.g., when you type `(&format; &t; "return value: ~S~%" &v-r;)` you want want to see a terse one-line output when &v-r; is something short (like &zero; or &nil; or &t;), but you probably want to see something nice, like

    return value:
    (long list which does not fit
     on one line)

instead of

    return value: (long list which does not fit
     on one line)

when it does not.

&ppr-first-newline; has no effect if &print-pretty-var; is &nil;.

&ppr-first-newline; is initially set to &t;.

## Printing Floats

In the absence of &write-float-decimal;, floating point numbers are output in radix 2. This function is defined in &floatprint-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 &float-t;s are printed.

## Printing Characters

Characters are printed as specified in &ansi-cl; using &sharp-back;, with one exception: when &pri-esc; is in effect, the space character is printed as `#\Space` when the variable &spacecharprint; is &nil;. When &spacecharprint; is non-&nil;, it is printed as `#\` ; this is how &ansi-cl; specifies it.

## Package Prefixes for Symbols

Variable &pr-sym-pack-prefix;

When &pr-sym-pack-prefix; is non-&nil;, the package prefix is not the &package-name; but the shortest (nick)name as returned by &package-shortest-name;. This variable is ignored when &print-readably-var; is non-&nil;.

## Printing Other Vectors

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

## Printing Other Arrays

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

As explicitly permitted by this section, specialized &bit-t; and &character-t; &array-t;s are printed with the innermost lists generated by the printing algorithm being instead printed using &bit-vector-t; and &string-t; syntax, respectively.

Variable &pr-empty-arr-ansi;

Empty &array-t;s, i.e., arrays with no elements and zero &array-total-size; (because one of its dimensions is zero) are printed with the readable syntax `#A(&eltype-r; &dimensions-r; &cont-r;)`, unless the variable &pr-empty-arr-ansi; is non-&nil;, in which case the arrays are printed using the &ansi-cl;-prescribed syntax `&sharp-A; &cont-r;` which often loses the dimension information.

### Printing Pathnames

Pathnames are printed as follows: If &print-escape-var; is &nil;, only the namestring is printed; otherwise it is printed with the &sharp-P; syntax, as per the &ansi-cl; issue &iss276;. But, if &print-readably-var; is true, we are in trouble as &sharp-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: `&sharp-minus;CLISP &sharp-P;"..." &sharp-plus;CLISP &sharp-S;(&pathname-t; ...)`. Otherwise, when the variable &pathprint; is non-&nil;, the &sharp-P; notation is used as per Resolution of Apparent Conflicts in Exceptional Situations.

The &sharp-S; notation for &pathname-t;s is used extensively in the &hyperspec; (see examples for &pathname;, &pathnamep;, &parse-namestring; et al), but was decided against, see &iss260;.

When both &print-readably-var; and &pathprint; are non-&nil; and the namestring will be parsed to a dissimilar object (with the current value of &parsedot;), an &error-t; of type &print-not-readable-t; is &signal;ed.

## The Lisp Pretty Printer

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

### Pretty Print Dispatch Table

A pprint dispatch table is a &cons; of a &symbol-t; &print-pprint-dispatch-var; and 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).

## Formatted Output

Function &format;

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

&format; ~!

The additional &format; instruction `~.` is a kind of opposite to `~&`: It outputs a conditional newline, by calling the function &elastic-newline;. `~&n-r;.` outputs n-1 newlines followed by an &elastic-newline;. `~0.` does nothing.

&format; ~.

&format; &format-r; and &format; &format-rs; can output only integers in the range `|&n-r;| < 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-r;| < 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.

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

## Macro &print-unreadable-object;

Variable &pr-unreadable-ansi;

The macro &print-unreadable-object;, when invoked without body forms, suppresses the trailing space if only the type is to be printed, and suppresses the leading space if only the identity is to be printed. This behaviour can be turned off set setting the variable &pr-unreadable-ansi; to a non-&nil; value: in this case, a trailing or leading space are output, as prescribed by &ansi-cl;.

## Miscellaneous Issues

&print-case-var; controls the output not only of symbols, but also of characters and some `unreadable` objects.

&unix-w32-only;

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

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

# Reader

## Effect of Readtable Case on the Lisp Reader

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

## The &rec-p; argument

When non-&nil; &rec-p; argument is passed to a top-level &read; call, an &err-sig;.

# System Construction

The compiler can be called not only by the functions &compile;, &compile-file-my; and &disassemble;, but also by the declaration &compile-decl;.

## Function &compile-file;

&compile-file; compiles a file to a platform-independent &bytecode;:

    (&compile-file; &filename-r; &key-amp; &outfile-k; :LISTING &extfmt;
                                ((&warnings-k; &compile-warn;) &compile-warn;)
                                ((&verbose-k; &compile-verbose-var;) &compile-verbose-var;)
                                ((&print-k; &compile-print-var;) &compile-print-var;))

Options for &compile-file;

&filename-r;

  the file to be compiled, 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;.

&extfmt;

  the &encoding; of the &filename-r;.

&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; (initially set to &t;), &compile-verbose-var; (initially set to &t;, affected by &opt-v;) &compile-print-var; (initially set to &nil;, affected by &opt-v;) 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.

*COMPILE-WARNINGS*

### Output files

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-my; function
auxiliary output file | only if &outfile-k; is not &nil; | &lib-file; | used by &compile-file; when compiling a &require-my; 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"` | &ffi-pac;; this file is created only if the source contains &ffi-pac; forms

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!

### Return values

As per &ansi-cl;, &compile-file; returns 3 values:

output-truename

  the truename of the output &fasl-file;, or &nil; if the file could not be created, in which case the compilation is considered to have failed

warnings-p

  &nil; if no conditions of type &error-t; or &warning-t; were detected during compilation, and the number of such conditions otherwise

failure-p

  &nil; if no conditions of type &error-t; or &warning-t; (other than &style-warning-t;) were detected during compilation, and the number of such conditions otherwise

Since &clisp; tends to be relatively garrulous with warnings (see, e.g., ), the non-&nil; tertiary return value (called failure-p by the &ansi-cl;) does ¬-e; indicate a failure of compilation. The correct way to check whether &compile-file; has failed is the primary return value.

## 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-my;ed if the required module is not already present.

### Return value

When the module is already present, &nil; is returned; otherwise returns the &truename; which was loaded to satisfy the &require;ment (or &list-t; thereof iff the second argument is a &list-t;).

### Additional &load-my; locations

In addition to (and &before-e;) &load-paths;, &require; tries to find the file to &load-my; in the following locations:

- &dynmod-only;

  The system-wide external modules directory `(&merge-pathnames; "dynmod/" &libdir;)`.

- &dynmod-only;

  The user external modules directory `(&merge-pathnames; "dynmod/" &user-libdir;)` (when &user-libdir; is non-&nil;).

- When &require; was called while &load-my;ing, the directory with the file being loaded (i.e., `(&make-pathname; :name &nil; :type &nil; :defaults &load-truename-var;)`).

### User variable &module-providers;

When &require; is called without the second (pathname) argument, the elements of the &module-providers; &list-t; are called one by one on the first (module name) argument until one of them returns non-&nil;. If all of them return &nil;, &load-my; is called as described above.

Initially the lisp is empty; `(require "&asdf-mod;")` modifies it (if &clisp; was configured with the option `--with-module=asdf`).

### Interaction with &compile-file-my;

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

It is a &very-e; bad idea to name your files the same way as &clisp; modules (whether system-supplied or user-installed) because then &require-my; will use different files at compile and execution times.

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 ¬-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 &opt-c; foo

    bar.fas: bar.lisp foo.fas
    	clisp &opt-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-cmd; &opt-i; foo &opt-c; bar

Thus, you do not need to `(&load-my; &foo-f;)` in order to `(&compile-file-my; `#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; accepts four additional keyword arguments &echo-k;, &compiling-k;, &extra-file-types-k;, and &obsolete-action-k;.

    (&load; &filename-r; &key-amp; ((&verbose-k; &load-verbose-var;) &load-verbose-var;)
                        ((&print-k; &load-print-var;) &load-print-var;)
                        ((&echo-k; &load-echo;) &load-echo;) &if-does-not-exist;
                        ((&compiling-k; &load-comp;) &load-comp;) &extra-file-types-k;
                        ((&obsolete-action-k; &load-obs;) &load-obs;)
                        (ignore-pathname-defaults nil))

&verbose-k;

  causes &load; to emit a short message that a file is being loaded. The default is &load-verbose-var;, which is initially &t;, but can be changed by the &opt-v; option.

&print-k;

  causes &load; to print the value of each form. The default is &load-print-var;, which is initially &nil;, but can be changed by the &opt-v; option.

&echo-k;

  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;, but can be changed by the &opt-v; option.

  *LOAD-ECHO*
&compiling-k;

  causes each form read to be compiled on the fly. The compiled code is executed at once and - in contrast to &compile-file-my; - not written to a file. The default is &load-comp; , which is initially &nil;, but can be changed by the &opt-C; option.

  *LOAD-COMPILING*
&extra-file-types-k;

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

  *SOURCE-FILE-TYPES*
  *COMPILED-FILE-TYPES*

  When &filename-r; does not specify 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;

  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`

    delete the &fasl-file; and proceed as with &nil;

  &error-k;

    &signal; an &error-t;

  `:COMPILE`

    recompile the source file (if found in &load-paths;) and &load; the result

  &nil; (default)

    &warn; and look for another matching file

  If no file can be loaded and &if-does-not-exist; is non-&nil;, an &err-sig;. The default is &load-obs; , which is initially &nil;.
  *LOAD-OBSOLETE-ACTION*
`:IGNORE-PATHNAME-DEFAULTS`

  Do not merge &default-pathname-defaults-var; to the argument using &merge-pathnames; (as required by &ansi-cl;) and rely on &load-paths; instead.

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

When evaluation of a read form &sig-err;, three &restart-t;s are available:

`SKIP`

  Skip this form and read the next one.

`RETRY`

  Try to evaluate this form again.

`STOP`

  Stop loading the file.

On success, &load; returns the &truename; of the file which it loaded, or the &filename-r; argument if it is a &stream-t; but not a &file-stream-t;.

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-my;, &require-my;, &compile-file-my; and &load-logical-pathname-translations;.

## Variable &features-var;

The variable &features-var; initially contains the following symbols

Default &features-var;

`:CLISP`

  the name of this implementation

`:ANSI-CL`

  &clisp; purports to conform to &ansi-cl;

`:COMMON-LISP`

  required by &ansi-cl;

`:INTERPRETER`

  &eval; is implemented

`:COMPILER`

  &compile; and &compile-file-my; are implemented

`:SOCKETS`

  see

`:MT`

  see

`:GENERIC-STREAMS`

  see

`:LOGICAL-PATHNAMES`

  Logical Pathnames are implemented

`:FFI`

  if a foreign function interface (see ) is supported (Many &unix;, &win32; platforms only)

`:GETTEXT`

  if internationalization (see ) using the &ggettext; package is supported (most &unix; platforms only)

`:UNICODE`

  if &unicode; (ISO 10646) characters are supported (see )

`:LOOP`

  extended &loop; form is implemented

`:CLOS`

  &clos; is implemented

`:MOP`

  &mop; is implemented

`:WORD-SIZE=64`

  if &clisp; was built for a 64-bit CPU. This could be useful on platforms with 64-bit CPUs which have a 32-bit mode emulation (e.g., i386 is emulated on x86_64 and ia64) so that the user can decide which ABI library to load dynamically using &ffi-pac;.

`:WIN32`

  if &hw; = PC (clone) and &os; = &win32; (Windows 95/98/Me/NT/2000/XP)

`:PC386`

  if &hw; = PC (clone). It can be used as an indicator for the mainstream hardware characteristics (such as the existence of a graphics card with a non-graphics text mode, or the presence of a keyboard with arrows and Insert/Delete keys, or an ISA/VLB/PCI bus) or software characteristics (such as the &ctrl;&alt;Delete keyboard combination).

&unix-k;

  if &os; = &unix; (in this case the &hw; is irrelevant!)

`:BEOS`

  if &os; = &beos; (in that case &unix-k; is also present)

`:HAIKU`

  if &os; = &haiku; (in that case &unix-k; is also present)

`:CYGWIN`

  if &clisp; is using the &cygwin; &unix; compatibility layer on top of &win32; (in that case &unix-k; is also present)

`:MACOS`

  if &os; = &macosx; (in that case &unix-k; is also present)

Each &module; should add the appropriate keyword, e.g., `:SYSCALLS`, `:DIRKEY`, `:REGEXP`, `:PCRE`, etc.

## Function `EXT:FEATUREP` [CLRFI-1]

`(EXT:FEATUREP &form-r;)` provides run-time access to the read-time conditionals &sharp-plus; and &sharp-minus;. &form-r; is a &feature-expr;.

## Function &compiled-file-p; [CLRFI-2]

`(&compiled-file-p; &filename-r;)` returns non-&nil; when the file &filename-r; exists, is readable, and appears to be a &clisp;-compiled &fasl-file; file compatible with the currently used &bytecode; format.

System definition facilities (such as &asdf; or &defsystem;) can use it to determine whether the file needs to be recompiled.

# Environment

## Top Level Loop

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, in any case, without surrounding quotes or &whitespace;. 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` | print a list of available commands
`LocalSymbols` | `:ls` | print the list of &symbol-t;s &intern;ed in a given &package-t;.

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 &cur-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 &lex-env; of the &cur-frame; and at the same time in the &dyn-env; of the debugger's caller. This means that to inspect or modify a &lex-var; all you have to do is to move the &cur-frame; to be just below the frame that corresponds to the form or the function call that binds that variable.

Stack Printing Mode

There is a current stack mode which defines in how much detail the stack is shown by the stack-related debugger commands (&backtrace; et al):

1. All the stack elements are considered. This mode works fine for debugging compiled functions.

2. All the frames are considered.

3. Only lexical frames (frames that correspond to special forms that modify the &lex-env;) are considered.

4. Only &eval; and &apply; frames are considered. Every evaluation of a form in the interpreter corresponds to an &eval; frame. This is the default.

5. Only &apply; frames are considered. Every invocation of an interpreted function corresponds to one &apply; frame.

Commands common to the debugger and the stepper

&cmd-abbrev-oper-header;
`Error` | `:e` | print the last error object.
`Inspect` | `:i` | &inspect-my; the last error object.
`Where` | `:w` | show the &cur-frame;.
`Up` | `:u` | go up one frame, i.e., to the caller if in mode-5
`Down` | `:d` | do down one frame, i.e., to the callee if in mode-5
`Top` | `:t` | go to top frame, i.e., to the top-level form if in mode-4
`Bottom` | `:b` | go to bottom (most recent) frame, i.e., most probably to the form or function that caused the debugger to be entered.
`Mode` &stack-mode; | `:m` &stack-mode; | set the current stack printing mode
`Frame-limit` &l-r; | `:fl` | set the &frame-limit;: this many frames will be printed by &backtrace; at most.
&backtrace; [&stack-mode; [&l-r;]] | `:bt` [&stack-mode; [&l-r;]] | list the stack in the given &stack-mode;, bottom frame first, top frame last; at most &l-r; frames are printed; calls &show-stack;.

If the &cur-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+` | set 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-` | remove a breakpoint from the current frame.
`Redo` | `:rd` | re-evaluate the corresponding form or function call. This command can be used to restart parts of a computation without aborting it entirely.
`Return` &value-r; | `:rt` &value-r; | leave the current frame, returning the given value.

Commands specific to the debugger

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

### User-defined Commands

You can set &user-commands; to a list of &function-t;s, each returning a &list-t; of bindings, i.e., either a

&string-t;

  the help string printed by &help; in addition to the standard &clisp; help

&cons-t; `(&string-t; . &function-t;)`

  the actual binding: when the user types the string, the function is called on the remainder of the string, i.e., the part of the string after the command.

E.g.,

    (setq &user-commands;
          (list (lambda () (list (format nil "~2%User-defined commands:")))
                (lambda ()
                  (flet ((panic (argline)
                           (format t "don't panic~@[ because of ~A~], ~D~%"
                                   (and (plusp (length argline)) argline)
                                   (random 42))))
                    (list (format nil "~%panic   :p    hit the panic button!")
                          (cons "panic" #'panic)
                          (cons ":p" #'panic))))
                (lambda ()
                  (let ((curses #("ouch" "yuk" "bletch")))
                    (flet ((swear (argline)
                             (format t "~A: ~A!~%" argline
                                     (aref curses (random (length curses))))))
                      (list (format nil "~%swear   :e    curse")
                            (cons "swear" #'swear)
                            (cons ":e" #'swear)))))))

## Debugging Utilities

### Function &disassemble;

&unix-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-t;, a special operator handler, a &symbol-t; denoting one of these, an &integer-t; (address), or a &string-t;.

### 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 &show-stack;

The function &show-stack; is called by the &backtrace; command.

It prints to &standard-output-var; and accepts 3 optional arguments:

1. &stack-mode;

2. &frame-limit;

3. start-frame

It can used to find out what all the threads are up to:

    (&loop; :with out = &standard-output-var; :for &thr; :in (&list-threads;) :do
       (&format; out "===~A===~;" &thr;)
       (&thread-interrupt; &thr; :function
         (&lambda-m; () (&let; ((&standard-output-var; out)) (&show-stack; 1 3)))))

### Function &documentation;

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

### Function &describe;

When &browser; is non-&nil;, and &clhs-root; returns a valid URL, &describe; on a standard &cl; symbol will point your web browser to the appropriate &hyperspec; page.

Also, when &browser; is non-&nil;, and &impnotes-root; returns a valid URL, &describe; on symbols and packages documented in these implementation notes will point your web browser to the appropriate page.

To do this, &describe; will retrieve the appropriate tables from &clhs-root; and &impnotes-root; on the first relevant invocation. These operations are logged to &http-log-stream;.

Function &clhs-root;

Function &clhs-root; is defined in &config-lisp;. By default it looks at `(&getenv; "CLHSROOT")` and &clhs-root-default;, but you may redefine it in &config-lisp; or &RC-file;. The return value should be a &string-t; terminated with a &file-slash;, e.g., or `/usr/doc/HyperSpec/`. If the return value is &nil;, the feature is completely disabled. &clhs-root-default; is initialized in &config-lisp; based on the `--hyperspec` passed to the top-level &configure; script when &clisp; was built.

Function &impnotes-root;

Function &impnotes-root; is defined in &config-lisp;. By default it looks at `(&getenv; "IMPNOTES")` and &impnotes-root-default;, but you may redefine it in &config-lisp; or &RC-file;. The return value should be a &string-t; terminated with a &file-slash;, e.g., , or the path to the monolithic page, e.g., or `/usr/doc/clisp/impnotes.html`. If the return value is &nil;, the feature is completely disabled.

### Macro &trace;

`(&trace; &funcname-r; ...)` makes the functions &funcname-r;, ... traced. Each &funcname-r; should be either a &funname; or a &list-t; `(&funcname-r; &key-amp; `:SUPPRESS-IF` `:MAX-DEPTH` `:STEP-IF` `:BINDINGS` `: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

`:MAX-DEPTH` &form-r;

  no trace output as long as `(> *trace-level* &form-r;)`. This is useful for tracing functions that are use by the tracer itself, such as &print-object;, or otherwise when tracing would lead to an infinite recursion.

`:STEP-IF` &form-r;

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

`:BINDINGS` ((&var-r; &form-r;)...)

  binds &var-r;s to the result of evaluation of &form-r;s around evaluation of all of the following forms

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

#### Trace output

&trace; prints this line before evaluating the form: `trace level. Trace: &form-r;` and after evaluating the form it prints: `trace level. Trace: &funcname-r; ==> &res-r;` where trace level is the total nesting level.

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

#### Examples

Identifying Individual Calls in &trace;

Suppose the trace level above is not enough for you to identify individual calls. You can give each call a unique id and print it:

    (defun f0 (x)
      (cond ((zerop x) 1)
            ((zerop (random 2)) (* x (f0 (1- x))))
            (t (* x (f1 (1- x))))))
    F0
    (defun f1 (x)
      (cond ((zerop x) 1)
            ((zerop (random 2)) (* x (f0 (1- x))))
            (t (* x (f1 (1- x))))))
    F1
    (defvar *f0-call-count* 0)
    *F0-CALL-COUNT*
    (defvar *id0*)
    *ID0*
    (defvar *cc0*)
    *CC0*
    (defvar *f1-call-count* 0)
    *F1-CALL-COUNT*
    (defvar *id1*)
    *ID1*
    (defvar *cc1*)
    *CC1*
    (trace (f0 :bindings ((*cc0* (incf *f0-call-count*))
                          (*id0* (gensym "F0-")))
               :pre-print (list 'enter *id0* *cc0*)
               :post-print (list 'exit *id0* *cc0*))
           (f1 :bindings ((*cc1* (incf *f1-call-count*))
                          (*id1* (gensym "F1-")))
               :pre-print (list 'enter *id1* *cc1*)
               :post-print (list 'exit *id1* *cc1*)))
    ;; Tracing function F0.
    ;; Tracing function F1.
    (F0 F1)
    (f0 10)
    1. Trace: (F0 '10)
    (ENTER #:F0-2926 1)
    2. Trace: (F1 '9)
    (ENTER #:F1-2927 1)
    3. Trace: (F0 '8)
    (ENTER #:F0-2928 2)
    4. Trace: (F1 '7)
    (ENTER #:F1-2929 2)
    5. Trace: (F1 '6)
    (ENTER #:F1-2930 3)
    6. Trace: (F1 '5)
    (ENTER #:F1-2931 4)
    7. Trace: (F1 '4)
    (ENTER #:F1-2932 5)
    8. Trace: (F0 '3)
    (ENTER #:F0-2933 3)
    9. Trace: (F1 '2)
    (ENTER #:F1-2934 6)
    10. Trace: (F0 '1)
    (ENTER #:F0-2935 4)
    11. Trace: (F1 '0)
    (ENTER #:F1-2936 7)
    (EXIT #:F1-2936 7)
    11. Trace: F1 ==> 1
    (EXIT #:F0-2935 4)
    10. Trace: F0 ==> 1
    (EXIT #:F1-2934 6)
    9. Trace: F1 ==> 2
    (EXIT #:F0-2933 3)
    8. Trace: F0 ==> 6
    (EXIT #:F1-2932 5)
    7. Trace: F1 ==> 24
    (EXIT #:F1-2931 4)
    6. Trace: F1 ==> 120
    (EXIT #:F1-2930 3)
    5. Trace: F1 ==> 720
    (EXIT #:F1-2929 2)
    4. Trace: F1 ==> 5040
    (EXIT #:F0-2928 2)
    3. Trace: F0 ==> 40320
    (EXIT #:F1-2927 1)
    2. Trace: F1 ==> 362880
    (EXIT #:F0-2926 1)
    1. Trace: F0 ==> 3628800
    3628800
    *f0-call-count*
    4
    *f1-call-count*
    7

### Function &inspect;

The function &inspect; accepts a keyword argument `:FRONTEND`, which specifies the way &clisp; will interact with the user, and defaults to `CUSTOM:*INSPECT-FRONTEND*`.

Available `:FRONTEND`s for &inspect; in &clisp;

`:TTY`

  The interaction is conducted via the &terminal-io-var; stream. Please use the &help; 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.

The function &inspect; also accepts a keyword argument &browser-k;, which specifies the browser used by the `:HTTP` front-end and defaults to `CUSTOM:*INSPECT-BROWSER*`.

The function &inspect; binds some pretty-printer variables:

Variable | Bound to
--- | ---
&print-length-var; | `CUSTOM:*INSPECT-PRINT-LENGTH*`
&print-level-var; | `CUSTOM:*INSPECT-PRINT-LEVEL*`
&print-lines-var; | `CUSTOM:*INSPECT-PRINT-LINES*`

User variable `CUSTOM:*INSPECT-LENGTH*` specifies the number of sequence elements or slots printed in detail when a sequence or a structure or a &clos; object is inspected.

*INSPECT-LENGTH*

### Macro &time;

The timing data printed by the macro &time; includes:

- the real time (wall time, &get-internal-real-time;),

- the run time (processor time for this process, &get-internal-run-time;),

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

TIMES

### 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; (set in &config-lisp;). If the argument is a function name which was defined in the current session (not loaded from a file), the program text to be edited is a pretty-printed version (without comments) of the text which was used to define the function.

*EDITOR*

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

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

Variable &apropos-do-more;

You can make &apropos; print more information about the symbols it found by setting &apropos-do-more; to a list containing some of &function-k;, `:VARIABLE`, &type-k;, and &class-k; or just set it to &t; to get all of the values.

Variable &apropos-matcher;

You can make &apropos; and &apropos-list; be more flexible in their search by setting &apropos-matcher; to a &function-t; of one argument, a pattern (a &string-t;), returning a new &function-t; of one argument, a &symbol-t; name (also a &string-t;), which returns non-&nil; when the symbol name matches the pattern for the purposes of &apropos;. When &apropos-matcher; is &nil;, &search; is used. Some &module;s come with functions which can be used for &apropos-matcher;, e.g., &re-matcher;, `POSIX:FNMATCH-MATCHER`, `PCRE:PCRE-MATCHER`.

### 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 ¬-e; a &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; (source target) (dribble-toggle *loggable* s)
        (&when; (&streamp; source) (&setq; *loggable* source))
        target))
    (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 `src/dribble.lisp` in the &clisp; source tree.

#### Scripting and &dribble;

&dribble; works by operating on &terminal-io-var;, thus is does ¬-e; work when &clisp; acts as a script interpreter (see ).

Traditionally, &cl; implementations set &standard-input-var;, &standard-output-var;, and &error-output-var; to a &synonym-stream-t; pointing to &terminal-io-var;, and &clisp; is no exception. Thus changing &terminal-io-var; to a dribble stream affects all standard i/o.

On the other hand, when &clisp; acts as a script interpreter, it adheres to the &unix; &stdio; conventions, thus &standard-input-var;, &standard-output-var;, and &error-output-var; are normal &file-stream-t;s, and thus are ¬-e; affected by &dribble; (&terminal-io-var; - and thus `(&print; ... &t;)` - &is-e; still affected). The &ansi-cl; explicitly permits this behavior by stating

> &dribble; is intended primarily for interactive debugging; its effect cannot be relied upon when used in a program.

## Environment Inquiry

### Function &room;

The function &room; returns five values:

1. space occupied by Lisp objects (in bytes)

2. space available for allocating Lisp objects until the next &gc;ion is triggered (in bytes)

3. space permanently allocated (in bytes)

4. the number of times &gc;ion was done in this &clisp; session

5. the cumulative space freed by all the &gc;ions in this &clisp; session (in bytes)

6. the total time (in &internal-time-units-per-second;) spent collecting garbage

ROOM

### Function `EXT:GC`

GC

This function starts a global &gc;ion and returns the same values as &room;.

When the optional parameter is non-&nil; also invalidates just-in-time compiled objects.

### Machine

&unix-only;

  The functions &short-site-name;, &long-site-name; should be defined in a site-specific &config-lisp; file. The default implementations try to read the value of the &env-var; `ORGANIZATION`, and, failing that, call `uname`.

&win32-only;

  The functions &short-site-name;, &long-site-name; should be defined in a site-specific &config-lisp; file. The default implementations try to read the registry.

### 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 &uni-time; (like `3141592654`). When running on a different machine, it appends the &machine-instance; of the machine on which it was built.

### Function &argv;

This function will return a &fresh; &simple-vector-t; of &string-t; command line arguments passed to the runtime, including those already processed by &clisp;. Use &args; instead of this function to get the arguments for your program.

## Time

Default Time Zone

&no-platform-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 &TZ; in a &dec-time; does not necessarily have be an &integer-t;, but (as &float-t; or &rational-t; number) it should be a multiple of `1/3600`.

Time granularity

platform | &unix; | &win32;
--- | --- | ---
&internal-time-units-per-second; | 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.

# Glossary

No notes.

# Appendix

No notes.