     [file macros.txi not included]

ecl is an implementation of clisp designed for being embeddable into C based applications.

Copyright © 2000, Juan Jose Garcia-Ripoll

Copyright © 1990, Giuseppe Attardi

Top
***

ecl is an implementation of clisp originally designed for being embeddable into C based applications. This document describes the ecl implementation and how it differs from ANSI and Steele:84. See ecldev for details about the implementation and how to interface with other languages.

Introduction
************

ecl is an implementation of the clisp language that was developed by Giuseppe Attardi's up from the Kyoto Common-Lisp. See Credits for the history of the code you are up to use.

ecl (ECL for short) uses standard C calling conventions for Lisp compiled functions, which allows C programs to easily call Lisp functions and vice versa. No foreign function interface is required: data can be exchanged between C and Lisp with no need for conversion.

ecl is based on a Common Runtime Support (CRS) which provides basic facilities for memory management, dynamic loading and dumping of binary images, support for multiple threads of execution.  The CRS is built into a library that can be linked with the code of the application.  ecl is modular: main modules are the program development tools (top level, debugger, trace, stepper), the compiler, and CLOS.  A native implementation of CLOS is available in ecl: one can configure ecl with or without CLOS.  A runtime version of ecl can be built with just the modules which are required by the application.

The ecl compiler compiles from Lisp to C, and then invokes the GNU C compiler to produce binaries. While former releases of ECL adhere to the the reference of the language given in Steele:84, the aim of ecl is now to achieve maximum compliance with ansi, the most up to date standard for clisp.

Throughout this manual we will describe the ecl implementation and how it differs from ANSI and Steele:84. In general, as work in ecl is completed section by section, we will drop compatibility with Steele:84 and the corresponding chapter will be updated to document only the differences with ANSI.

Credits
=======

The ecl project is an implementation of the clisp language that aims to comply with the ansi standard. The first ECL implementations were developed by Giuseppe Attardi's who produced an interpreter and compiler fully conformat with the Common-Lisp as reported in Steele:84. ECL derives itself mostly from Kyoto clisp, an implementation developed at the Research Institute for Mathematical Sciences (RIMS), Kyoto University, with the cooperation of Nippon Data General Corporation.  The main developers of Kyoto clisp were Taiichi Yuasa and Masami Hagiya, of the Research Institute for Mathematical Sciences, at Kyoto University.

I must thank Giuseppe Attardi, Yuasa and Hagiya for their wonderful work with preceding implementations and for putting them in the Public Domain under the GNU General Public License as published by the Free Software Foundation. Without them this product would have never been possible.

This document is an update of the original ECL documentation, which was based in part on the material in Yuasa:85

The following people or organizations must be credited for support in the development of Kyoto clisp: Prof. Reiji Nakajima at RIMS, Kyoto University; Nippon Data General Corporation; Teruo Yabe; Toshiyasu Harada; Takashi Suzuki; Kibo Kurokawa; Data General Corporation; Richard Gabriel; Daniel Weinreb; Skef Wholey; Carl Hoffman; Naruhiko Kawamura; Takashi Sakuragawa; Akinori Yonezawa; Etsuya Shibayama; Hagiwara Laboratory; Shuji Doshita; Takashi Hattori.

William F. Schelter improved KCL in several areas and developed Austin Kyoto clisp (AKCL). Many ideas and code from AKCL have been incorporated in ecl.

The following is the full list of contributors to ECL: Taiichi Yuasa and Masami Hagiya (KCL), William F. Schelter (Dynamic loader, conservative Gc), Giuseppe Attardi (Top-level, trace, stepper, compiler, CLOS, multithread), Marcus Daniels (Linux port) Cornelis van der Laan (FreeBSD port) David Rudloff (NeXT port) Dan Stanger, Don Cohen, and Brian Spilsbury.

We have to thank for the following pieces of software that have helped in the development of ecl

Bruno Haible
     For the Cltl2-compliance test

Peter Van Eynde
     For the ANSI-compliance test

Symbolic's Inc.
     For the ANSI-compliant LOOP macro.

The ecl project also owes a lot to the people who have tested this program and contributed with suggestions and error messages: Eric Marsden, Hannu Koivisto and Jeff Bowden, and others whose name I may have omitted.

Copyright
=========

Copyright © 2000 Juan Jose Garcia Ripoll

Copyright © 1990, 1991, 1993 Giuseppe Attardi

Copyright © 1984 Taiichi Yuasa and Masami Hagiya

All Rights Reserved

Summary:

     Permission is granted to use, copy, modify this program, EXCEPT that the copyright notice must be reproduced on copies, and credit should be given to the authors where it is due. WE MAKE NO WARRANTY AND ACCEPT NO LIABILITY FOR THIS PROGRAM.

In detail:

 1. Permission to use, copy, modify this software and its documentation for any purpose is hereby granted without fee, provided that

       * the above copyright notice appears in all copies,

       * both that copyright notice and this permission notice appears in supporting documentation, and that

       * you cause modified files to carry prominent notices stating that you changed the files and the date of any change.

 2. Please notify us if you are going to sell this software or its documentation for profit.

 3. WE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL WE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Additionally:

     ecl is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version; see file 'Copying'.

     This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for more details.

     You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Address for reporting bugs, comments, suggestions:

     worm@arrakis.es

Building ECL
============

 1. Obtain the distribution from http://ecls.sourceforge.net. The distribution is in a gzip-compressed tar file named like ecl.tgz

 2. Prepare a directory (hereafter called ECL directory) for ECL.  In the following examples, we suppose that the ECL directory is /usr/local/ecl.

 3. Extract the content from the compressed tar file.

          $ zcat ecl.tgz | tar xf -

 4. An auto configuration mechanism allows you to perform a standard installation with the following commands:

          $ ./configure

     This example will prepare to install executable files, manual pages and info files in standard directories like /usr/local/bin, /usr/local/man/man1, /usr/local/info.

 5. If you don't have access rights to these directories, you should give to configure alternate places.  Try ./configure --help for instructions on how to supply this information to configure, but a good starting point is

          $ ./configure --prefix=$HOME

 6. Next you must build the program and install it

          $ make
          $ make install

At the end of installation, the destination directories will contain several files. If you have not modified these directories when invoking configure the layout should be

Executable files:
$HOME/bin/ecl            the ecl interpreter and compiler
Help documents:
$HOME/lib/ecl/help.doc   data for the online help
$HOME/man/man1/ecl.1     manual page for ecl
$HOME/info/ecl.info      this manual you are reading
Library files and headers:
$HOME/lib/ecl/libecl.a   the core library in C
$HOME/lib/ecl/libgmp.a   GNU library for bignums
$HOME/lib/ecl/libgc.a    Boehm-Weiser garbage collector
$HOME/lib/ecl/*.a        Other lisp compiled code
$HOME/lib/ecl/ecl/       Header files

You can remove all intermediate files produced during installation with the command make clean.

Entering and leaving ecl
========================

ecl is invoked by the command ecl.

     % ecl
     ECL (Embeddable Common-Lisp) 0.0e
     Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
     Copyright (C) 1993 Giuseppe Attardi
     Copyright (C) 2000 Juan J. Garcia-Ripoll
             ECL is free software, and you are welcome to redistribute it
     under certain conditions; see file 'Copyright' for details.
     Type :h for Help.  Top level.
     >

When invoked, ecl will print the banner and initialize the system.  The date in the ecl banner identifies the revision of ecl.  Version (0.8) 05/14/1993 is the value of the function lisp-implementation-version.

If there exists a file named init.lsp in the current working directory, ecl successively evaluates the forms in the file, immediately after the system initialization.  The user may set up his or her own ecl environment (e.g., the memory configuration) with init.lsp.

After the initialization, ecl enters the top-level loop and prints the prompt `>'.

     Type :h for Help.  Top level.
     >

The prompt indicates that ecl is now ready to receive a form from the terminal and to evaluate it.

Usually, the current package (i.e., the value of *PACKAGE*) is the user package, and the prompt appears as above.  If, however, the current package is other than the user package, then the prompt will be prefixed by the package name.

     > (in-package 'cl)
     #<"COMMON-LISP" package>
     COMMON-LISP> (in-package 'system)
     #<"SYSTEM" package>
     SYSTEM>

To exit from ecl, call the function quit.

     >(quit)
     Bye.
     %

Alternatively, you may type D, i.e. press the key D while pressing down the control key (Ctrl).

     >DBye.
     %

You can disable D as the exit command by setting to T the following variable:
 -- System: *ignore-eof-on-terminal-io*
     This variable controls whether an end of file character (normally D) should terminate the session. The default value is nil.

The top-level loop of ecl is almost the same as that defined in Section 20.2 of Steele:84.  Since the input from the terminal is in line mode, each top-level form should be followed by a newline.  If more than one value is returned by the evaluation of the top-level form, the values will be printed successively.  If no value is returned, then nothing will be printed.

     >(values 1 2)
     1
     2
     >(values)

     >

When an error is signalled, control will enter the break loop.

     >(defun foo (x) (bar x))
     foo

     >(defun bar (y) (bee y y))
     bar

     >(foo 'lish)
     Error: The function BEE is undefined.
     Error signalled by BAR.

     Broken at BAR.
     >>

`>>' in the last line is the prompt of the break loop.  Like in the top-level loop, the prompt will be prefixed by the current package name, if the current package is other than the user package.

To go back to the top-level loop, type :q

     >>:q

     Top level.
     >

See Section 5.4 for the details of the break loop.

The terminal interrupt (usually caused by typing C (Control-C)) is a kind of error.  It breaks the running program and calls the break level loop.

Example:

     >(defun foo () (do () (nil)))
     foo

     >(foo)
     C
     Correctable error: Console interrupt.
     Signalled by DO.

     Broken at FOO.
     >>

Standards
*********

ecl supports all clisp data types exactly as defined in the Steele:84.  This chapter simply complements Chapter 2 of Steele:84, by describing implementation dependent features of clisp data types.  Each section in this chapter corresponds to the section in Chapter 2 of Steele:84, with the same section title.

Numbers
=======

Integers
--------

Fixnum's in ecl are those integers in the range (-2^29) to (2^29-1), inclusive.  They are represented as immediate data, so no memory allocation is involved when using fixnum's.  Other integers are bignums. Thus 25 factorial (25!)

     15511210043330985984000000

is definitely a bignum in ecl.

clisp constants related to integers have the following values in ecl.

     most-positive-fixnum = 536870911 = 2^29-1
     most-negative-fixnum = -536870912 = - 2^29
     boole-1 = 3
     boole-2 = 5
     boole-and = 1
     boole-andc1 = 4
     boole-andc2 = 2
     boole-c1 = 12
     boole-c2 = 10
     boole-clr = 0
     boole-eqv = 9
     boole-ior = 7
     boole-nand = 14
     boole-nor = 8
     boole-orc1 = 13
     boole-orc2 = 11
     boole-set = 15
     boole-xor = 6

See Chapter 12 of Steele:84 for their meanings.

Ratios
------

There are no implementation-dependent features for ratios.

Floating-Point Numbers
----------------------

ecl supports two floating point formats: single-float and double-float.  These are implemented with IEEE single and double float arithmetic, respectively.  short-float is a synonym for single-float, and long-float is a synonym for double-float.  The initial value of read-default-float-format is single-float.

Both single-float and double-float are represented with a pointer descriptor, so float operations can cause number consing.  Number consing is greatly reduced if type declarations are supplied in programs.

An expression such as (eql 1.0s0 1.0d0) is false, but (eql 1.0f0 1.0d0) is true.  Similarly, (typep 1.0l0 'short-float) is false, but (typep 1.0l0 'double-float) is true.  For output purposes all floating-point numbers are assumed to be of single or double format.

The floating-point precisions and exponent sizes are:

Format   precision   exponent
Short    24 bits   8 bits
Single   24 bits   8 bits
Double   53 bits   11 bits
Long     32 bits   11 bits

There is no ``minus zero.'' (eql 0.0 -0.0) is true.

Complex Numbers
---------------

There are no implementation-dependent features for complex numbers.

Characters
==========

ecl is fully ansi compliant in all aspects of the character data type, with the following peculiarities.

Character types
---------------

In ecl the extended-character is empty, and all characters are implemented using 8-bit codes.

Standard Characters
-------------------

ecl supports all standard and semi-standard characters listed in Section 2.2.1 of Steele:84.  Non-printing characters have the following character codes.

Character       Code (in octal)
#back Null         000
#back Space        040
#back Newline      012
#back Backspace    010
#back Tab          011
#back Linefeed     012
#back Page         014
#back Return       015
#back Rubout       177

Note that #back Linefeed is synonymous with #back Newline and thus is a member of standard-char.  Other semi-standard characters are not members of standard-char.

Line Divisions
--------------

Since ecl represents the #back Newline character by a single code 12, problems with line divisions discussed in Section 2.2.2 of the Steele:84 are absent in ecl.

Non-standard Characters
-----------------------

ecl supports no additional non-standard characters.

Character Attributes
--------------------

Characters in ecl have no attributes, and thus it lacks the functions and variables #'char-bits, #'char-font, char-bits-limit, etc, defined in Chapter 13 of Steele:84.

Symbols
=======

The print name of a symbol may consist of up to 16777216 (i.e., the value of array-total-size-limit) characters.  However, when a symbol is read, the number of characters (not counting escape characters) in the print name is limited to 2048.

It is not recommended to write on the strings which have been passed to #'make-symbol or returned from #'symbol-name.

List and Conses
===============

There are no implementation-dependent features for lists and conses.

Arrays
======

When the value of the clisp variable *print-array* (see Section 22.1.6 of Steele:84) is nil, then bit-vectors are printed as #<a bit-vector ADDRESS>, other vectors are printed as #<a vector ADDRESS>, and other arrays are printed as #<an array ADDRESS>. The default value for *print-array* is nil.

ecl arrays can have up to 64 dimensions. clisp constants related to arrays have the following values in ecl.

array-rank-limit   64
array-dimension-limit   most-positive-fixnum
array-total-size-limit   array-dimension-limit

See Section 17.1 of Steele:84 for their meanings.

Vectors
-------

In ecl, array elements are represented in one of six ways depending on the type of the array.

Array Type   Element Representation
(array t) and (vector t)
a cell pointer
(array fixnum) and (vector fixnum)
32 bit signed integer
(array string-char) and string
8 bit code
(array short-float) and (vector short-float)
32 bit floating point
(array long-float) and (vector long-float)
64 bit floating point
(array bit) and bit-vector
1 bit bit

Strings
-------

The ecl implementation of strings is ansi compliant. Four types 'string, 'base-string, 'simple-string and 'simple-base-string are defined, but due to the lack of extended characters 'base-string and 'simple-base-string are simple aliases of 'string and 'simple-string.

A string may consists of up to 16777216 (i.e., the value of array-total-size-limit) characters.  However, when a string is read, the number of characters in it (not counting escape characters) is limited to 2048.

Bit-Vectors
-----------

There are no implementation-dependent features for bit-vectors.

Hash Tables
===========

All hash tables are printed as #<a hash-table ADDRESS>.

Readtables
==========

All readtables are printed as #<a readtable ADDRESS>.

Packages
========

The following packages are built into ecl.

Name   Nicknames
common-lisp   cl, lisp
common-lisp-user   cl-user, user
system   si
keyword

For instance, the system package has two nicknames sys and si; system:symbol may be written as sys:symbol or si:symbol.

Depending on the configuration option by which ecl has been built, additional packages may be available: compiler, clos and xlib.

The compiler package contains symbols used by the ecl compiler. Other packages are described in Section 11.6 of Steele:84.  The clos package is used for the internal symbols of the clisp Object System, which is described in Chapter 14.  The xlib package is used for the internal symbols of CLX, the clisp Language X Interface to the X Window System, which is described in a separate manual.

Packages are printed as #<PACKAGE-NAME package>.

Pathnames
=========

ecl provides a # macro #P" that reads a pathname: #P"STRING" is equivalent to (pathname "STRING").  For example, #P"foo.lsp" is equivalent to (pathname "foo.lsp"). The same format is used when a pathname is printed.

The initial value of the clisp variable *DEFAULT-PATHNAME-DEFAULTS* is #P"" (or, equivalently, (pathname "")).

A pathname in the file system of clisp consists of six elements: host, device, directory, name, type and version.

Let me briefly explain how ecl converts a namestring into a pathname. First ecl tries parsing the namestring using the logical pathnames syntax, which is as follows
        [hostname:][;][directory-item;]*[name][.type[.version]]
        hostname = word
        directory-item = wildcard-word
	type, name = wildcard-word without dots
	version = NEWEST, newest or a number

Here, WORD is a sequence of one or more characters excluding the #\Null character and the asterisk `*'. And WILDCARD-WORD is a sequence of any character excluding #\Null and consecutive asterisks (i.e.  "**" is not allowed).

If HOSTNAME is not found or it is not a logical hostname, then ecl tries the physical pathname syntax,
        [device:][[//hostname]/][directory-item/]*[name][.type]
        device, hostname = word
        directory-item, type = wildcard-word
	name = a wildcard-word with maybe a single leading dot

If this syntax also fails, then the namestring is not a valid pathname string.

It is important to remark that in ecl, all physical namestrings result into pathnames with a version equal to :NEWEST. Pathnames which are not logical and have any other version (i. e. NIL or a number), cannot be printed readably, but can produce a valid namestring which results of ignoring the version.

The following rules apply to both physical and logical namestrings. First, if a namestring contains one or more periods `.', the last period separates the namestring into the file name and the filetype.

     "foo.lsp"
         name:          "foo"
         type:          "lsp"

     "a.b.c"
         name:          "a.b"
         type:          "c"

If a namestring ends with a period, the filetype becomes the null string.
     "foo."
          name:          "foo"
          type:          ""  (null string)

If a namestring begins with a period, the file name becomes nil.
     ".lsp"
          name:          nil
          type:          "lsp"

If a namestring contains no period, the filetype is nil.
    "foo"
          name:          "foo"
          type:          nil

In a pathname, the file directory is represented as a list which always begins with either :relative or :absolute
     "common/demo/foo.lsp"
     ";common;demo;foo.lsp"
          directory:     (:relative "common"   "demo")
          name:          "foo"
          type:          "lsp"
     "/common/demo/foo.lsp"
     "common;demo;foo.lsp"
          directory:     (:absolute "common"   "demo")
          name:          "foo"
          type:          "lsp"

If a namestring does not contain a directory, the directory component of the pathname is nil.
     "foo.lsp"
          directory:     nil
          name:          "foo"
          type:          "lsp"

The abbreviation symbols `.' and `..' may be used in a namestring, but only the second one is translated to a standard keyword
     "./demo/queen.lsp"
          directory:     (:relative "." "demo")
          name:          "queen"
          type:          "lsp"

     "../../demo/queen.lsp"
          directory:     (:relative @pxlref{:up} :up "demo")
          name:          "queen"
          type:          "lsp"

The part of a namestring after the last directory separator (`/' or `;') is always regarded as representing the file name and the filetype.  In order to represent a pathname with both the name and the filetype nil, end the pathname with a slash.
     "/usr/common/"
          directory:     (:absolute "usr" "common")
          name:          nil
          type:          nil

     "/usr/common/.lsp"
          directory:     (:absolute "usr" "common")
          name:          ".lsp"
          type:          nil

`*' in the place of file name or filetype becomes  :wild
     "*.lsp"
          name:          :wild
          type:          "lsp"

     "foo.*"
          name:          "foo"
          type:          :wild

Streams
=======

Streams are printed in the following formats.

#<input stream FILE-NAME>
     An input stream from the file FILE-NAME.

#<output stream FILE-NAME>
     An output stream to the file FILE-NAME.

#<string-input stream from STRING>
     An input stream generated by (make-string-input-stream STRING ).

#<a string-output stream>
     An output stream generated by the function make-string-output-stream.

#<a two-way stream>
     A stream generated by the function make-two-way-stream.

#<an echo stream>
     A bidirectional stream generated by the function make-echo-stream.

#<synonym stream to SYMBOL>
     The stream generated by (make-synonym-stream SYMBOL ).

#<a concatenated stream>
     An input stream generated by the function make-concatenated-stream.

#<a broadcast stream>
     An output stream generated by the function make-broadcast-stream.

Random-States
=============

ecl provides a # macro `#$' that reads a random state. #$INTEGER is equivalent to (make-random-state INTEGER).  The same format is used when a random state is printed.

Structures
==========

There are no implementation-dependent features for structures.

Functions
=========

All functions in ecl are either compiled into bytecodes to be interpreted, or they are translated into C and then compiled using a native C compiler. Interpreted functions are printed using the formats
     #<interpreted-function @var{name}>
     #<interpreted-function @code{address}>

Compiled functions (including compiled macro-expansion functions) are printed in the following formats.
     #<compiled-function @var{name}>
     #<compiled-closure nil>

The output of (symbol-function FUN) is a list, is either a function object if 'fun is has a function definition, (macro . function-object) if 'fun is a macro, and 'special if 'fun is a special form.

ecl usually drops the source code of a function unless the global variable SI:*KEEP-DEFINITIONS* was true when the function was translated into bytecodes. Therefore, if you wish to use #'compile and #'disassemble on defined functions, you should issue (setq si:*keep-definitions* t) at the beginning of your session.

clisp constants related to functions have the following values in ecl.
     call-arguments-limit = 64
     lambda-list-keywords = (@optional{} @rest{} @keys{} @allow{}
                               @aux{} &whole &environment &body)
     lambda-parameters-limit = 64
      multiple-values-limit = 32

Refer to Steele:84 for their meanings.

Unreadable Data Objects
=======================

There are no implementation-dependent features for unreadable data objects.

Overlap types
=============

In ecl, the types number and array are certainly subtypes of common, since ecl does not extend the set of objects of these types.

Input and Output
****************

Read macros
===========

#P"
     #"STRING" reads a pathname. #"STRING" is equivalent to (pathname "STRING").

#$
     #$INTEGER reads a random state. #$INTEGER is equivalent to (make-random-state INTEGER).

The # macro '#,' works as described in Steele:84, only if it is included in a constant object.  The forms immediately after `#,' below will be evaluated when the compiled code is loaded.

     '#,x
     '(a b c (d #,e f) g)
     #(1 2 3 #,(+ a b c) 5 6)
     #C(0.0 #,(exp 1))

Otherwise, the effect of using '#,' is unpredictable.  Note that, when interpreted code is loaded, '#,' has the same effect as the # macro '#.'.

Input and Output Functions
==========================

The input and output functions of ecl almost follow the definitions in Chapter 22 of Steele:84.  Most of the differences come from the fact that, in ecl, input from the terminal is always in line mode and binary I/O is not supported.

In ecl, *terminal-io* is a two-way stream from the standard input and to the standard output.  The echoing to the terminal is performed by the underlying operating system.  In particular, when a disk file is assigned to the standard output, nothing will be echoed at the terminal.

Those functions that deviate from the definitions in Steele:84 are listed below.

 -- Function: load PATHNAME keys :print :verbose :if-does-not-exist
     If PATHNAME does not specify the filetype of the input file, then load uses the association list SI::*LOAD-SEARCH-LIST* to find out a suitable filetype and the function to load it. Typically, this search list is made of the elements .fas, .lsp and .lisp, in this order. If everything fails, a file without filetype will be loaded.

 -- Function: open
     Streams can only have element type base-char, (signed-byte 8) and (unsigned-byte 8). The :external-format is always :default.

 -- Function: close
     The keyword variable :ABORT is always ignored.

 -- Function: listen
     This routine requires some low level functions which are not available on all platforms (For instance on Windows). When ECL is not able to determine whether a stream is interactive, listen returns true unless an end of file has been previously detected.

 -- Function: clear-input
     The functions clear-input and clear-output do nothing.

 -- Function: read-char-no-hang
     read-char-no-hang is equivalent to read-char.

The functions princ, write-char and write-byte do not always flush the stream.  The stream is flushed when

 1. a newline character is written, or

 2. the input from the terminal is requested in the case that these functions operate on *terminal-io*

Network Streams
===============

With a configuration option, the following function is available which opens streams across network connections.

 -- Function: open-client-stream host port
     The string HOST indicates the name of the host, while PORT is an integer which identifies the port number to which to connect.  This function returns a two-way stream which can be used in any of the stream operations.

 -- Function: open-server-stream host port
     A stream connected to port number PORT is created to which clients can connect.  This function returns a two-way stream which can be used in any of the stream operations.

CLOS Streams
============

When the optional CLOS subsystem is available, an interface is provided by ecl for using CLOS objects as clisp input/output character streams. Such support can be used for instance to build interactive character streams, which may be used by applications as the stream argument for clisp I/O functions such as read, listen, prin1, etc.  The fundamental interface to clos-stream objects consists of (generic) functions which implement the basic clisp character stream operations (see clisp, Chapter 22) but whose details are implementation dependent.

The following functions are automatically invoked by ecl when a stream operation involves a CLOS object as a stream parameter. The programmer should define these methods for any class of objects which are to be used for character input/output.

CLOS Stream Input
-----------------

Character input from an clos-stream is implemented by the following methods.

 -- Method: stream-read-char (object clos-stream)
     Returns the next character object read from the CLOS stream OBJECT.

 -- Method: stream-unread-char (object clos-stream) character
     Unreads the character object CHARACTER from the CLOS stream OBJECT. CHARACTER will be the next character read by stream-read-char.

 -- Method: stream-listen (object clos-stream)
     Returns nil is no character is immediately available from the CLOS stream OBJECT. Otherwise, the next character is returned, as if stream-peek-char had been called.

 -- Method: stream-clear-input object
     Clears any buffered characters on the CLOS stream OBJECT. Returns nil.

CLOS Stream Output
------------------

Character output from an clos-stream is implemented by the following methods.

 -- Method: stream-write-char (object clos-stream) character
     Outputs the character CHARACTER to the CLOS stream OBJECT and returns it.

 -- Method: stream-clear-output (object clos-stream)
     Aborts any outstanding output operation on the CLOS stream OBJECT and returns nil.

 -- Method: stream-force-output (object clos-stream)
     Initiates the emptying of the internal buffers on the CLOS stream OBJECT and returns nil.

CLOS Stream common
------------------

The following functions should be available for all CLOS streams.

 -- Method: stream-interactive-p (object clos-stream)

 -- Method: stream-close (object clos-stream)
     Closes the stream for any further input or output.

Memory Management
*****************

The following sections only apply to the ecl original garbage collector. If ecl is not compiled with --disable-boehm, then an alternative, less restrictive garbage collector is installed, with the disadvantage that many of the following functions #'room, si:*gc-verbose*, ... do no longer work.

Implementation Types
====================

Each ecl object belongs to one of the 22 implementation types.  The implementation types are shown in Table 4-1 with the corresponding clisp data types.  In the table, the compiled functions are divided into three implementation types; cfun is the type of compiled functions without environment, cclosure is the type of compiled functions with environment (i.e., the type of compiled closures) and gfun is the type of compiled generic functions of CLOS.

Table 4-1  Implementation Types

Implementation Type   clisp Data Type
cons   cons
fixnum   fixnum
bignum   bignum
ratio   ratio
short-float   short-float
long-float   long-float (= double-float = single-float)
complex   complex
character   character
symbol   symbol
package   package
hash-table   hash-table
array   (and array (not vector))
vector    (and vector (not string) (not bit-vector))
string   string
bit-vector   bit-vector
structure   structure
stream   stream
random-state   random-state
readtable   readtable
cfun   compiled-function  without environment
cclosure   compiled-function  with environment
gfun   none (CLOS generic-function)
instance   none (CLOS instance)
thread   none (thread)

Each object is represented by a cell allocated in the heap area of the interpreter.  The size of the cell is determined by the implementation type of the object.

The implementation types are classified according to the size of the cells for the objects of the type, as shown in Table 4-2.  The size of the cells in the same type class is the same.

Table 4-2  Classification of Implementation Types

1   CONS BIGNUM RATIO COMPLEX STRUCTURE
2   SHORT-FLOAT RANDOM-STATE READTABLE
3   LONG-FLOAT CFUN CCLOSURE
4   SYMBOL
5   PACKAGE
6   ARRAY HASH-TABLE VECTOR BIT-VECTOR STREAM
7   STRING
8   PATHNAME

For objects of the (implementation) types readtable, symbol, package, array, hash-table, vector, bit-vector, stream, cclosure, string, cfun, and structure (or instance), the cell is simply a header of the object.  The body of the object is allocated separately from the cell and is managed in a different manner.  The memory space occupied by the body of such an object is called a block.  A block is either contiguous or relocatable depending on the area in which it is allocated.  The difference between the two areas will be explained below.  Table 4-3 lists these types, along with the contents of the body and the kind of the block.

Table 4-3  Types with Bodies

readtable   read table   contiguous
symbol   symbol name   relocatable
package   hash table   contiguous
array   array body   relocatable or contiguous
hash-table   hash table   relocatable
vector   vector body   relocatable or contiguous
bit-vector   bit-vector body   relocatable or contiguous
stream   I/O buffer   contiguous
cclosure   code   contiguous
string   string body   relocatable or contiguous
cfun   code   contiguous
structure   structure body   relocatable
instance   instance slots   relocatable
thread   thread data   contiguous

Usually, the body of an array, a vector, a bit-vector, or a string is allocated as a relocatable block.  In ecl, the function make-array takes an extra keyword argument static.  If the static argument is supplied with a non-nil value, then the body of the array is allocated as a contiguous block.

Heap and Relocatable Areas
==========================

The memory space of ecl is divided into two parts: the heap area and the relocatable area.  Both areas occupy a contiguous space in the memory.

Cells of ecl objects are allocated in the heap.  ecl divides the heap into pages (1 page = 2048 bytes), and each page consists of cells in the same type class (see Table 4-2).  Cells in different type classes are allocated in different pages.  Some blocks are also allocated in the heap: They are called contiguous blocks.  The pages for contiguous blocks contain only contiguous blocks.  Thus each page in the heap is either a page for cells in a particular type class, or a page for contiguous blocks.  Blocks not in the heap are called relocatable blocks and are allocated in the relocatable area.

The user may specify the maximum number of pages that can be allocated for each type class by calling the ecl specific function allocate.  There is also a limit on the number of pages for contiguous blocks; the limit can be altered by calling the ecl specific function allocate-contiguous-pages size of the relocatable area is specified by the ecl specific function allocate-relocatable-pages.  See Section 4.4 for these functions.

In some installations of ecl, the total amount of memory that ecl can use is limited.  In such cases, the entire memory may become exhausted before the maximum number of pages for each type class, for contiguous blocks, or for the relocatable area have been allocated.

The heap lies in a part of memory with lower address than the relocatable area and there is a ``hole'' between the two areas (see Figure 4-1).  On request for a new page of heap, the page with the lowest address in the hole is used.  When the hole is exhausted, the relocatable area is shifted toward the higher address space and a new hole of an appropriate size is created between the two areas.

Figure 4-1  Heap and Relocatable Area
    Lower address                         Higher address
    +--------------+-------------------+---------------+
    + HEAP         |   HOLE            | RELOCATABLE   |
    +--------------+-------------------+---------------+

The Garbage Collector
=====================

ecl uses a conservative garbage collection technique for collecting the C stack and a type accurate technique for areas containing Lisp objects. Scanning conservatively the C stack, looking for potential pointers to Lisp objects, ensures that no live Lisp objects get collected, even if they are passed to external procedures in C or some other language.  This approach greatly simplifies integration of Lisp and C code, since it is not necessary to protect Lisp object form collection when a foreign function is invoked.

The garbage collector of ecl has three levels according to what it collects:

 1. cells

 2. cells and relocatable blocks

 3. cells, relocatable blocks and contiguous blocks.

In levels 2 and 3, the relocatable area is shifted to the higher address space to reserve an appropriate number of pages in the hole.

For each type class, ecl keeps a free list of unused cells, and when the free list is exhausted, a new page is allocated, or the garbage collector is invoked, depending on whether the maximum number of pages for that class have been allocated or not.

The garbage collector does not compact the heap.  That is, cells and contiguous blocks are never moved to another place.  Moreover, once a page is allocated for a particular type class or for contiguous blocks, that page will never be freed for other classes, even if the entire page becomes garbage.

On the other hand, the relocatable area is compacted during level 2 and level 3 of garbage collection.  A relocatable block is really relocatable.

The garbage collector is automatically invoked in one of the following situations.  The number in the parentheses indicates the level of garbage collection that is performed.

 1. The free list of a certain type class is exhausted after the maximum number of pages have been allocated for that type class (1).

 2. The hole is exhausted (2).

 3. The relocatable area is exhausted after the maximum number of pages have been allocated for the relocatable area (2).

 4. The contiguous blocks are exhausted after the maximum number of pages have been allocated for contiguous blocks (3).

The garbage collector is also invoked by the following ecl specific function.

 -- Function: system gc x
     The garbage collector is invoked with the level specified by X.  If X is nil, the garbage collector is invoked for level 1 garbage collection.  If X is true, it is invoked for level 3 garbage collection.  Otherwise, it is invoked for level 2 garbage collection.  If sys:*gc-verbose* is non-nil, then it print messages at the start and end of each garbage collection.

*gc-verbose*[system] This variable controls whether to print messages at the start and end of each garbage collection.  If sys:*gc-verbose* is nil, gc fore goes printing any messages.  The default value is T.

Allocation Functions
====================

The following functions are used to set or inspect the (maximum) number of pages for each type class, for contiguous blocks, or for relocatable blocks.

 -- extensions: allocate type number
     Sets the maximum number of pages for the type class of the implementation type TYPE to NUMBER.  If more than NUMBER pages have already been allocated, an error is signalled.

 -- sys: allocated-pages type
     Returns the number of pages currently allocated for the type class of the implementation type TYPE.

 -- sys: maximum-allocatable-pages type
     Returns the current maximum number of pages for type class of the implementation type TYPE.

 -- sys: allocate-contiguous-pages number
     Sets the maximum number of pages for contiguous blocks to NUMBER.

 -- sys: allocated-contiguous-pages
     Returns the number of pages allocated for contiguous blocks.

 -- sys: maximum-contiguous-pages
     Returns the current maximum number of pages for contiguous blocks.

 -- sys: allocate-relocatable-pages number
     Sets the maximum number of pages for relocatable blocks to NUMBER.  The relocatable area is expanded to NUMBER pages immediately. Therefore,``the current maximum number'' and ``the number of pages allocated'' have the same meanings for relocatable blocks.

 -- sys: allocated-relocatable-pages
     Returns the number of pages allocated for relocatable blocks.

If the pages for a particular type class are exhausted after the maximum number of pages for that class have been allocated, and if there remain no free cells (actually, if there remain very few cells), ecl behaves as directed by the argument that was initially passed to the ecl specific function (si::ignore-maximum-pages).  If the value is nil, then ecl signals a correctable error and enters the break loop. The user can reset the maximum number by calling allocate and then continue the execution of the program by typing r.

Example:

     >(make-list 100000)

     Correctable error: The storage for CONS is exhausted.
                        Currently, 531 pages are allocated.
                        Use ALLOCATE to expand the space.
     Signalled by MAKE-LIST.

     Broken at FUNCALL.
     >>(ALLOCATE 'CONS 1000)
     t

     >>:r

     (nil nil nil nil nil nil nil nil nil nil ............

The user can also reset the maximum number of pages for relocatable blocks and for contiguous blocks in a similar manner.  On the other hand, if the value of (si::ignore-maximum-pages) is non-nil, then ecl automatically increments the maximum number of pages for the class by 50 percent.  The initial value of (si::ignore-maximum-pages) is true.

Storage Information
===================

 -- Function: room optional x
     The function room prints the storage information.  The argument X  is simply ignored and the output of room  is always in the same format.  room  prints the following information:

  * for each type class

       * the number of pages so-far allocated for the type class

       * the maximum number of pages for the type class

       * the percentage of used cells to cells so-far allocated

       * the number of times the garbage collector has been called to collect cells of the type class

       * the implementation types that belong to the type class

  * the number of pages actually allocated for contiguous blocks

  * the maximum number of pages for contiguous blocks

  * the number of times the garbage collector has been called to collect contiguous blocks

  * the number of pages in the hole

  * the maximum number of pages for relocatable blocks

  * the number of times the garbage collector has been called to collect relocatable blocks

  * the total number of pages allocated for cells

  * the total number of pages allocated

  * the number of available pages

  * the number of pages ecl can use.

The number of times the garbage collector has been called is not shown, if the number is zero.

In the following example, the maximum of 531 pages have already been allocated for the type class to which cons belongs, but only 16.9 percent of the cells are actually used.  The garbage collector was once invoked to collect cells in this type class.

     > (room)
      200/200   48.4%    CONS BIGNUM RATIO COMPLEX STRUCTURE
        1/5      7.4%    SHORT-FLOAT RANDOM-STATE READTABLE
       10/34    99.3%    LONG-FLOAT CFUN CCLOSURE
       47/64    71.9%    SYMBOL
        1/1      8.9%    PACKAGE
        2/69    81.8%    ARRAY HASH-TABLE VECTOR BIT-VECTOR STREAM
       16/40    95.9%    STRING
        1/1      6.8%    PATHNAME

        0/271            contiguous (1 blocks)
          127            hole
          40     3.4%    relocatable

       278 pages for cells
       445 total pages
     14709 pages available
      1230 pages in heap but not gc'd + pages needed for gc marking
     16384 maximum pages

Program Development Facilities
******************************

The Tracer
==========

The Tracer causes selected functions to be traced.  When such a traced function is invoked, it prints

       LEVEL > (NAME   ARG1   ...   ARGN)

On return from a traced function, it prints

       < LEVEL  (NAME   VALUE1   ...   VALUEN)

NAME is the name of the traced function, ARGS are the arguments, and VALUES are the return values.  LEVEL is a number which is incremented each time a traced function is invoked and is decremented at the completion of the invocation.  Trace print-outs are indented according to the LEVEL.

In the current version of ecl, macros and special forms cannot be traced.

 -- Macro: trace {function-name | (function-name {keys form}*)}*

     Causes one or more functions to be traced.  Each FUNCTION-NAME must be a symbol which is not evaluated.  If a function is called from a compiled function in the same file, tracing will not be enabled.  If this is the case, to enable tracing, recompile the caller with a notinline declaration for the called function. trace returns a name list of those functions that were traced by the call to trace.  If no FUNCTION-NAME is given, trace simply returns a name list of all the currently traced functions.

     Trace options can cause the normal printout to be suppressed, or cause extra information to be printed.  Each option is a pair of an option keyword and a value form. If an already traced function is traced again, any new options replace the old options.  FORM is an expression to be evaluated in an environment where SYS::ARGLIST is bound to the current list of arguments to the function.

     The following options are defined:

     cond FORM

     cond-before FORM

     cond-after FORM
          If cond-before is specified, then trace does nothing unless FORM evaluates to true at the time of the call.  cond-after is similar, but suppresses the initial printout, and is tested when the function returns.  cond tries both before and after.

     step FORM
          If FORM evaluates to true, the stepper is entered.

     break FORM

     break-after FORM
          If specified, and FORM evaluates to true, then the debugger is invoked at the start of the function or at the end of the function according to the respective option.

     print FORM

     print-after FORM
          In addition to the usual printout, the result of evaluating FORM is printed at the start of the function or at the end of the function, according to the respective option.  Multiple print options cause multiple values to be

 -- Macro: untrace {function-name}*

     Causes the specified functions to be not traced any more.  FUNCTION-NAMES must be symbols and they are not evaluated. untrace returns a name list of those functions that were untraced by the call to untrace.  If no FUNCTION-NAME is given, untrace will untrace all the currently traced functions and will return a list of their names.

The Stepper
===========

 -- Macro: step form

     Starts evaluating the FORM in the single-step mode.  In this mode, before any form is evaluated, the Stepper will print the form and prompt the user for a Stepper command.  The Stepper binds the two variables print-level and print-length both to 2, so that the current form may not occupy too much space on the screen.  A Stepper command will be executed when the user types the single character for the command followed by the required arguments, if any, and presses the newline key.  If the user presses the newline key without having typed any character, then the Stepper will assume that the Stepper command n was abbreviated.

The stepper commands are:

Newline
     Next.  Evaluates the current form in the single-step mode.

s, skip
     Skip.  Evaluates the current form in the ordinary mode.  The single-step mode will be resumed at completion of the evaluation.

b, back
     Backwards.  Steps back to previous step form.

pr, print
     Print.  Pretty-prints the current form.

form
     Form. Return the current form.  Nothing is done, but the current form is returned as the value of this command.  As a consequence, it is printed by the top level in the usual way and saved in the variable *.  The main purpose of this command is to allow the current form to be examined further by accessing *.

ret, return
     Return. Return without evaluating the current form.

x, exit
     Exit.  Evaluates the current form and any other forms in the ordinary mode.

?
     Help. Lists the commands.

Errors
======

*break-enable*

This variable is used to determine whether to enter the break loop (see Section 5.4) when an error occurs.  Even the function break checks this variable.  Initially, this variable is set to true, and thus an error will invoke the break loop.  If the value is nil, functions that cause fatal errors, such as  error, will just print an error message and control will return to the top-level loop (or to the current break loop, if already in the break loop).  Functions that cause correctable errors, such as cerror, will print an error message and a ``continue message'', and control will return to the next form.  In ecl, backtrace is not part of an error message, but a break loop command will print backtrace.  Therefore, if break-enable is nil, no backtrace appears on the screen.

When the break loop is entered, break-enable will be bound to nil.

The Break Loop
==============

The break loop is a read-eval-print loop similar to the top-level loop.  In addition to ordinary Lisp forms, the break loop accepts various commands with which the user can inspect and modify the state of the program execution.  Each break loop command is identified with a keyword (i.e., a symbol in the keyword package).  A break loop command is executed when the user inputs a list whose first element is the keyword that identifies the command.  The rest of the list is the arguments to the command.  They are evaluated before being passed to the command.  If the command needs no arguments, then the user may input only the keyword.  It is an error if the given keyword does not identify any command.  Any other input to the break loop is regarded as an ordinary Lisp form; the form will be evaluated and the resulting values will be printed on the terminal.

There can be several instances of the break loop at the same time, and each such instance is identified by a level number.  When the break loop is entered during execution in the top-level loop, the break loop instance is given the level number 1.  The break loop instance that is entered from the level n break loop is given the level number N+1.  The prompt of the level n break loop is N+1 consecutive >'s, occasionally prefixed with the name of the current package.

The break loop keeps track of the invocation sequence of functions (including special forms and macro expansion functions), which led up to the break loop from the previous break loop (or from the top-level loop, if the current break loop is level 1).  The invocation sequence is maintained in a pushdown stack of events.  An event consists of an event function and an event environment.  An event function is:

 1. an interpreted (i.e., not compiled) function (global function, local function, lambda-expression, or closure),

 2. a special form within an interpreted function,

 3. a macro expansion function called from an interpreted function,

 4. a compiled function called from an interpreted function, or

 5. a compiled function called from another compiled function which was compiled while the safety optimize level is 3 or with a notinline declaration for the called function (see Chapter 7).

An event is pushed on the event stack when execution of its event function begins, and is popped away at the completion of the execution.  An event environment is the `environment' of the event function at the time the next event is pushed.  Actually, an event environment is a pointer to the main stack of ecl.  For each interpreted event function (i.e., event function in classes 1, 2, and 3), the pointer points to the first entry of the three contiguous main stack entries that hold the lexical environment of the event function.  For each compiled event function (i.e., event function in classes 4 and 5), the pointer is set to the first entry of the main stack area that is used locally by the compiled code.  In most cases, the first argument to the compiled function is saved in the first entry, the second argument in the second entry, and so on.  The local variables of the function are allocated in the entries following the arguments.  However, this is not always the case. Refer to Section 7.3 for variable allocations in compiled functions.

By break level commands, the user can choose one of the events as the current event.  If the current event function is an interpreted event function, then the break loop evaluates Lisp forms in the lexical environment retrieved from the event environment.  In particular, local variables may be referenced by the variable names, local functions and local macros may be invoked as usual, established blocks may be exited from, and tags may be used as the destination of go.  If the current function is a compiled function, Lisp forms are evaluated in the null environment.

Within the break loop, each event is represented by the event symbol. The backtrace command, for example, lists events in terms of their event symbols.  If the event function is a named function (global or local) or a macro expansion function, then the function or macro name is used as the event symbol.  If the event function is a special form, then the name of the special form is used.  If the event function is a lambda-expression (or a closure), then the symbol lambda (or lambda-closure) is used.

To suppress unnecessary information, the user can hide (or make invisible) some of the events.  Invisible events do not appear in the backtrace, for example. Initially, only those events are invisible whose event symbols belong to the system internal package system.  When the break loop is entered, the last visible event becomes the current event.

The break loop commands are described below.  Some of the commands allow abbreviation in the keywords that identify them.  For example, the user may abbreviate current as c.  The break loop commands return no values at all.

 -- Break Command: :current
 -- Break Command: :c
     Prints the event symbol of the current event.

 -- Break Command: :previous optional n
 -- Break Command: :p optional n
     Makes the N-th previous visible event the new current event.  Invisible events are not counted.  If there are less than N previous events, then the first visible event in the invocation sequence becomes the new current event. N must be a positive integer and the default is 1.

 -- Break Command: :next optional n
 -- Break Command: :n optional n
     Makes the N-th next visible event the new current event.  If there are less than N next events, then the last visible event in the invocation sequence becomes the new current event. N  must be a positive integer and the default is 1.

 -- Break Command: :backtrace
 -- Break Command: :b
     Prints the event symbols of all visible events in order.  The symbol of the current event is printed in upper-case letters and the event symbols of other events are in lower-case.

 -- Break Command: :help
 -- Break Command: :h
     Lists the break loop commands.

 -- Break Command: :quit optional n
 -- Break Command: :q optional n
     Returns control to the level N break loop.  If N is 0 or if N is omitted, then control will return to the top-level loop. N must be a non-negative integer smaller than the current break level.

 -- Break Command: :continue
 -- Break Command: :c
     Returns control to the caller of the break loop.  If the break loop has been entered from cerror, cerror returns nil as its value and control will resume at that point.  Otherwise, this command returns control to the previous break loop (or to the top-level loop, if the current break level is 1).

 -- Break Command: :variables
 -- Break Command: :v
     Prints the names of the bound variables in the current environment.  To see the value of a bound variable, just type the variable name.

 -- Break Command: :functions
     Prints the names of the local functions and local macros in the current environment.  To see the definition of a local function or macro, use the function special form in the usual way.  That is, (function NAME) will return the definition of the local function or macro whose name is NAME.  Local functions and local macros may be invoked as usual.

 -- Break Command: :blocks
     Prints the names of the blocks established in the current environment.  If a block BLOCK is established, then the return-from form (return-from BLOCK VALUE) works as usual.  That is, the block form that established BLOCK will return VALUE as its value and control will resume at that point.

 -- Break Command: :tags
     Prints the tags established in the current environment.  If a tag TAG is established, then the go form (go TAG) works as usual. That is, control will resume at the position of TAG in the surrounding tagbody.

 -- Break Command: :local optional n
 -- Break Command: :l optional n
     If N is 0 or if it is omitted, then this command prints the value stored in the main stack entry that is pointed to by the current event environment. N is an offset from that entry.  If N is positive, then the value of the n-th next (i.e., toward the top of the main stack) entry is printed.  If N is negative, then the value of the N-th previous (i.e., toward the bottom of the main stack) entry is printed. N must be an integer.  It is an error if the specified entry does not lie between the bottom and the top of the stack.

 -- Break Command: :hide symbol
     Hides all events whose event symbol is SYMBOL.  In particular, by :hide 'lambda and hide 'lambda-closure, all events become invisible whose event functions are lambda-expressions and closures, respectively.  If the event symbol of the current event happens to be SYMBOL, then the last previous visible event will become the new current event.  SYMBOL must be a symbol.

     Events of eval and evalhook may never become invisible and attempts to hide them are simply ignored.  It is always the case that the first event function is either eval or evalhook.  Keeping both of them visible is the simplest way to avoid the silly attempts of the user to hide all events.

 -- Break Command: :hide-package package
     Hides all events whose event symbol belongs to the package PACKAGE. PACKAGE may be any object that represents a package, i.e., a package object, a symbol, or a string.  If the event symbol of the current event happens to belong to the package PACKAGE, then the last previous visible event will become the new current event.  Even if lisp package was specified as PACKAGE, events of eval and evalhook do not become invisible.  See the description of hide above.

 -- Break Command: :unhide symbol
     unhide is the inverse command of hide.  If, however,  SYMBOL belongs to one of the hide-packaged packages, events of SYMBOL become visible only after the package is :unhide-package 'd. SYMBOL must be a symbol.

 -- Break Command: :unhide-package package
     unhide-package is the inverse command of hide-package.  However, an event whose event symbol belongs to PACKAGE becomes visible only after the symbol is unhide 'd, if the symbol was code 'd before. PACKAGE may be any object that represents a package, i.e., a package object, a symbol, or a string.

Example:

     > (defun fact (x) (if (= x 0) one (* x (fact (1- x)))))
     fact                    ;;;  Wrong definition for  fact, the factorial.

     > (fact 6)              ;;;  Tries to calculate factorial 6.

     Error: The variable ONE is unbound.
     Error signalled by IF.

     Broken at IF:           ;;;  Enters the break-loop.
     >> :h                   ;;;  Help.

     Break commands:
     :q(uit)         Return to some previous break level.
     :pop            Pop to previous break level.
     :c(ontinue)     Continue execution.
     :b(acktrace)    Print backtrace.
     :f(unction)     Show current function.
     :p(revious)     Go to previous function.
     :n(ext)         Go to next function.
     :g(o)           Go to next function.
     :fs             Search forward for function.
     :bs             Search backward for function.
     :v(ariables)    Show local variables, functions, blocks, and tags.
     :l(ocal)        Return the nth local value on the stack.
     :hide           Hide function.
     :unhide         Unhide function.
     :hp             Hide package.
     :unhp           Unhide package.
     :unhide-all     Unhide all variables and packages.
     :vs             Show value stack.
     :bds            Show binding stack.
     :m(essage)      Show error message.
     :hs             Help stack.

     Top level commands:
     :cf             Compile file.
     :exit or ^D     Exit Lisp.
     :ld             Load file.
     :step           Single step form.
     :tr(ace)        Trace function.
     :untr(ace)      Untrace function.

     Help commands:
     :apropos        Apropos.
     :doc(ument)     Document.
     :h(elp) or ?    Help.  Type ":help help" for more information.

     >> :b                   ;;;  Backtrace.
     Backtrace: eval > fact > if > fact > if > fact > if > fact >
     if > fact > if > fact > if > fact > IF

     >>: p                   ;;;  Moves to the previous event.
     Broken at FACT.

     >> :b                   ;;;  Now inside of  fact  but outside of  if.
     Backtrace: eval > fact > if > fact > if > fact > if > fact >
     if > fact > if > fact > if > FACT > if

     >> :v                   ;;;  Shows local variables.
     Local variables:
       X: 1
     Block names: FACT.

     >> x                    ;;;  The value of x is 1.
     1

     >> (return-from fact 1) ;;;  Returns from the  fact  block with value  1.
     720                     ;;;  Now the correct answer.

     >                      ;;;  Top-level.

Describe and Inspect
====================

 -- Function: describe object
     Prints the information about OBJECT to the stream that is the value of *standard-output*.  The description of an object consists of several fields, each of which is described in a recursive manner.  For example, a symbol may have fields such as home package, variable documentation, value, function documentation, function binding, type documentation, deftype definition, properties.

 -- Function: inspect object
     Prints the information about OBJECT in an interactive manner.  The output of inspect is similar to that of describe, but after printing the label and the value of a field (the value itself is not describe 'd), it prompts the user to input a one-character command.  The input to inspect is taken from the stream that is the value of *query-io*.  Normally, the inspection of OBJECT terminates after all of its fields have been inspected.  The following commands are supported:

     n
          Next. Goes to the next level; the field is inspected recursively.

     s
          Skip. Skips the inspection of the field. inspect proceeds to the next field.

     p
          Print. Pretty-prints the field and prompts again.

     u FORM
          Update. The FORM is evaluated and the field is replaced by the resulting value.  If the field cannot be updated, the message Not updated.  will be printed.

     a
          Abort. Aborts the inspection of the current object.  The field and the rest of the fields are not inspected.

     e FORM
          Eval. Evaluates the specified form in the null environment and prints the resulting values.  Then prompts again with the same field.

     q
          Quit. Aborts the entire inspection.

     ?
          Help. Lists the inspect commands.

The Profiler
============

The profiler tool is enabled by default in the basic ecl configuration.  It can be disabled with the configure option --disable-profiler.

 -- sys: profile GRAIN optional ADDRESS
     This function activates the profiling of subsequent executions.  GRAIN is a value between 1 and 16384 which indicates the granularity of code segments to consider. There is a counter for each such segment.  With each clock tick, the current segment is identified and its corresponding histogram count is incremented.  A value of 0 for GRAIN means stop profiling.  ADDRESS indicates the base address for the code being profiled.

 -- sys: display-profile
     Displays the histogram of accumulated tick counts.  The ticks are attributed to the compiled Lisp function whose base address is closest to the start of the segment.  This may not be totally accurate for system functions which invoke some auxiliary function to do the job.

 -- sys: clear-profile
     Clears the profile histogram.

 -- Variable: sys *profile-array*
     Contains the profile histogram: two short integer counters are packed in each value of this array of fixnums.

Online Help
===========

Online help is provided by the following functions.

 -- Function: help optional SYMBOL
     help with no arguments prints a greeting message to ecl beginners. help with a symbol argument prints the documentation associated with the symbol.

 -- Function: help* STRING optional PACKAGE
     Prints the documentation associated with those symbols in the specified PACKAGE whose print names contain STRING as substring. STRING may be a symbol, in which case the print name of that symbol is used. PACKAGE is optional and defaults to the LISP package. If PACKAGE is nil, then all packages are searched.

The Interpreter
***************

Former versions of ecl, as well as many other lisps, used linked lists to represent code. As of version 0.3 a bytecodes compiler and a bytecodes interpreter were developed to circumvent the limitations of linked lists.

When you enter code at the lisp prompt, or when you load a source file, ecl begins a process known as minimal compilation. Barely this process consists on parsing each form, macroexpanding it and translating it into an intermediate language made of bytecodes.

The bytecodes compiler is implemented in src/c/compiler.d. The main entry point is the lisp function SI::MAKE-LAMBDA, which takes a name for the function and the body of the lambda lists, and produces a lisp object that can be invoked. For instance,

     > (defvar fun (si::make-lambda 'f '((x) (1+ x))))
     *FUN*
     > (funcall fun 2)
     3

ecl can only execute bytecodes. When a list is passed to EVAL it must be first compiled to bytecodes and, if the process succeeds, then the resulting bytecodes are passed to the interpreter. Similarly, every time a function object is created, such as in DEFUN or DEFMACRO, the bytecodes compiler processes the lambda form to produce a suitable bytecodes object.

The fact that ecl performs this eager compilation means that changes on a macro are not immediately seen in code which was already compiled. This has subtle implications. Take the following code:

     > (defmacro f (a b) `(+ ,a ,b))
     F
     > (defun g (x y) (f x y))
     G
     > (g 1 2)
     3
     > (defmacro f (a b) `(- ,a ,b))
     F
     > (g 1 2)
     3

The last statement always outputs 3 while in former implementations based on processing of lambda lists it would produce -1.

The Compiler
************

The ecl compiler translates a Lisp program stored in a source file into a C program, invokes the C compiler to compile the C program, and then generates an object file, called fasl file (or o-file because of the actual filetype).  The compiled program in a fasl file is loaded by the function load.

Ordinarily, the object program generated by the ecl compiler scarcely does runtime error-checking for runtime efficiency.  In addition, Lisp functions in the same source file are linked together and some system functions are open-coded in-line.  To control runtime error checking, supply appropriate optimize declarations (see Section 7.1).

The ecl compiler processes the eval-when special form exactly as specified in Steele:84 (see Section 5.3.3 of Steele:84).

The ecl compiler is invoked by the functions compile-file, compile, and disassemble described below.  In addition, the ecl compiler may be invoked directly by the Shell commands ecl. This command requires the file name of the source file as its argument. ecl simply adds .lsp to the file name argument to obtain the full name of the source file.

             $ ecl FILENAME

has the same effect as the compiler invocation (compile-file FILENAME) from within ecl, and

             $ ecl -C FILENAME

has the same effects as (compile-file FILENAME :c-file t :h-file t :data-file t).

 -- Function: compile-file PATHNAME keys :output-file :verbose :print :c-file :h-file :data-file
     compile-file compiles the Lisp program stored in the file specified by PATHNAME, and generates a binary file.  If verbose is true, a message indicating what file is being compiled is printed.  If print is true, information about top-level forms in the file being compiled is printed.  compile-file generates the following temporary files:

     Temporary File
     Contents
     C-FILE
     C version of the Lisp program
     H-FILE
     The include file referenced in the c-file
     DATA-FILE
     The Lisp data to be used at load time

     If files of these names already exist, the old files will be deleted first. Usually, these intermediate files are automatically deleted after execution of compile-file.

     The input-file is determined in the usual manner (see Section 2.9), except that, if the filetype is not specified, then the default filetype .lsp will be used.  The keyword parameter :output-file defines the default directory and the default name to be applied to the output files (i.e., the fasl file and the temporary files).  output-file itself defaults to INPUT-PATHNAME.  That is, if output-file is not supplied, then the directory and the name of the input file will be used as the default directory and the default name for the output files.  The file types of the output files are fixed as follows.

     Output File   Filetype
     fasl file   .o
     c-file   .c
     h-file   .h
     data-file   .data

     Each output file can be specified by the corresponding keyword parameter. If the value of the keyword parameter is nil, then the output file will be deleted after execution of compile-file.  If the value of the keyword parameter is true, then the output file will be left in the default directory under the default name.  Otherwise, the output file will be left in the directory under the name specified by the keyword parameter. The default value of output-file is true, and the default values of c-file, :h-file, and data-file are all nil.

     (compile-file 'foo)
          The source file is FOO.lsp and the fasl file is FOO.o both in the current directory.

     (compile-file 'foo.lish)
          The source file is FOO.LISH and the fasl file is FOO.o'.

     (compile-file "/usr/mas/foo" :output-file "/usr/tai/baa")
          The source file is foo.lsp in the directory /usr/mas, and the fasl file is baa.o in the directory /usr/tai.

 -- Function: compile NAME CODE optional DEFINITION
     If DEFINITION is not supplied, NAME should be the name of a not-yet-compiled function.  In this case, compile compiles the function, replaces the previous definition of NAME with the compiled function,and returns NAME.  If DEFINITION is supplied, it should be a lambda-expression to be compiled and NAME should be a symbol. If NAME is a non-nil symbol, then compile installs the compiled function as the function definition of NAME and returns NAME.  If NAME is nil, then compile simply returns the compiled function.

     The ecl compiler is essentially a file compiler, and forms to be compiled are supposed to be stored in a file.  Thus compile actually creates a source file which contains the form designated by the arguments.  Then compile calls compile-file to get a fasl file, which is then loaded into ecl.  The source file and the fasl file are given the names gazonk.lsp and gazonk.fasl, respectively.  These files are not deleted automatically after the execution of compile.

 -- Function: disassemble optional THING keys :h-file :data-file

     This function does not actually disassemble.  It always calls the ecl compiler and prints the contents of the c-file, i.e., the C-language code, generated by the ecl compiler.  If THING is not supplied, or if it is nil, then the previously compiled form by disassemble will be compiled again.  If THING is a symbol other than nil, then it must be the name of a not-yet-compiled function, whose definition is to be compiled.  In this case, it is an error if the name is associated with a special form or a macro. If THING is a lambda-expression (lambda LAMBDA-LIST . BODY), then disassemble first creates a function definition (defun gazonk LAMBDA-LIST .  BODY) and this definition is compiled.  (The function name gazonk has no special meanings.  Indeed, the displayed code is essentially independent of the function name.) Otherwise, THING itself will be compiled as a top-level form.  In any case, disassemble does not install the compiled function. disassemble returns no value.

     No intermediate h-file is created if the keyword parameter :h-file is nil or if h-file is not supplied.  Otherwise, an intermediate h-file is created under the name specified by h-file.  Similarly, the intermediate data-file is specified by the keyword parameter data-file.

Declarations
************

ecl supports all kinds of declarations described in the Steele:84.  Any valid declaration will affect the ecl environment in some way or another, although information obtained by declarations, other than special declarations, is mainly used by the ecl compiler.

As described in Steele:84, clisp declarations are divided into two classes: PROCLAMATIONS and others.  A proclamation is a global declaration given by the function proclaim, the top-level macro defvar, or the top-level macro defparameter.  Once given, a proclamation remains effective during the ecl session unless it is shadowed by a local declaration or is canceled by another proclamation.  Any other declaration is a local declaration and is given only by the special form declare.  A local declaration remains in effect only within the body of the construct that surrounds the declaration.

In the following nonsensical example borrowed from Chapter 9 of Steele:84,

     (defun nonsense (k x z)
        (foo z x)
        (let ((j (foo k x))
              (x (* k k)))
             (declare (inline foo) (special x z))
          (foo x j z)))

the inline and the special declarations both remain in effect within the surrounding let form.  In this case, we say that the let form is the surrounding construct of these declarations.

 -- Special Form: the VALUE-TYPE FORM

     The ecl interpreter does actually check whether the value of the form conforms to the data type specified by value-type and signals an error if the value does not.  The type checking is performed by the function typep.  For example,

     (the fixnum (foo))

is equivalent to

     (let ((values (multiple-value-list (foo))))
        (cond ((endp values) (error ``Too few return values."))
              ((not (endp (cdr values)))
               (error ``Too many return values."))
              ((typep (car values) 'fixnum) (car values))
              (t (error ``~s is not of type fixnum." (car values)))))

On the other hand, the ecl compiler uses the special form to obtain type information for compiled code optimization. No code for runtime type-checking is embedded in the compiled code.

Declaration Specifiers
======================

ecl recognizes all declaration specifiers defined in Steele:84. The syntax of each such declaration specifier is exactly the same as defined in Steele:84.  In addition, ecl recognizes the object declaration specifier which is specific to ecl.

 -- Declaration: special {VARIABLE-NAME}*
     The interpreter and the compiler of ecl both treat special declarations exactly as described in Steele:84.

 -- Declaration: type TYPE {VARIABLE-NAME}*
     A type proclamation (type type var1 var2 ...)  specifies that the dynamic values of the named variables are of the type type.  A local type declaration specifies that the variables mentioned are bound by the surrounding construct and have values of the type type during execution of the surrounding construct.  The compiler issues a warning if one of the named variables is not bound by the surrounding construct.  The information given by type declarations is used by the compiler to optimize the compiled code.  The behavior of the compiled code is unpredictable if a wrong type declaration is supplied.  The compiler detects certain wrong type declarations at compile time.

For example,

     >(defun foo (x y)
        (declare (fixnum x) (character y))
        (setq x y)
       ...))
     foo

     >(compile 'foo)

     ; (defun foo ...) is being compiled.
     ;; Warning: Type mismatches between x and y.

See Section 7.3 for further information on type declarations.

 -- Declaration: type {VARIABLE-NAME}*
     (TYPE VAR1 VAR2 ...) is equivalent to (type TYPE VAR1 VAR2 ...), provided that TYPE is one of the symbols in Table 4-1 of Steele:84, other than function.  Declaration specifications that begin with function are regarded as function declarations (see below).

 -- Declaration: function FUNCTION-NAME ARGUMENT-TYPES . RETURN-TYPES
     A function declaration is used to obtain type information for function call forms.  That is, a function declaration specifies the argument and the return types of each form that calls the named function.

     (defun foo ()
       (declare (function bar (character) fixnum))
       (+ (bar (atcholi1)) (bar (atcholi2))))

In this example, the function declaration specifies that the two functions atcholi1 and atcholi2 both return character objects when called within the body of foo, and that the function bar returns fixnum objects when called within the body of foo.  The type information given by function declarations is used by the compiler to optimize the compiled code.  The behavior of the compiled code is unpredictable if a wrong function declaration is supplied.  The compiler detects certain wrong function declarations at compile time.

For example,

     >(defun foo (x)
        (declare (fixnum x)
                 (function bar (character) fixnum))
        (bar x))
     foo

     >(compile 'foo)

     ; (defun foo ...) is being compiled.
     ;; Warning: The type of the form x is not character.

However, the compiler does not check the number of arguments, and thus, the following function definition will be compiled successfully without any warnings.

     (defun foo ()
       (declare (function bar (character character) fixnum))
       (+ (bar (atcholi1)) (bar (atcholi2) (atcholi3) (atcholi4))))

For this definition, the compiler assumes that the three functions atcholi1, atcholi2, and atcholi3 will return fixnum objects.  The return type of atcholi4 is unknown at compile time.

The complete syntax of a function declaration is:

     (function  function-name
       ({type}* [{optional | rest | keys} {thing}*])
       {(values {type}* ) | {type}*}
     )

Although optional, rest, and keys markers may appear in the list of argument types, only those TYPES are recognized that appear before any such markers and the rest of the list is simply ignored.  Note that functions with optional, rest, or keys parameters may still be declared by function declarations because of the use of function declarations mentioned above.

The values construct in the specification of return types is almost useless: (function FUNCTION-NAME ARGUMENT-TYPES (VALUES TYPE1 TYPE2 ...)) is equivalent to (function FUNCTION-NAME ARGMENT-TYPES TYPE1 TYPE2 ...).

See Section 7.3 for further information on function declarations.

 -- Declaration: ftype FUNCTION-TYPE {FUNCTION-NAME}*
     FUNCTION-TYPE must be a list whose first element is the symbol function.  (ftype (function . REST) FUNCTION-NAME-1 ...  FUNCTION-NAME-N) is equivalent to N consecutive function declarations (function FUNCTION-NAME-1 . REST) ... (function FUNCTION-NAME-N . REST).

 -- Declaration: notinline {function-name}*
     (notinline FUNCTION1 FUNCTION2 ...)  specifies that the compiler should not compile the named functions in-line.  Calls to the named functions can be traced and an event (see Section 5.4) is pushed on the event stack when any one of the named functions is invoked.

 -- Declaration: inline {function-name}*
     An inline proclamation cancels currently effective notinline proclamations, and a local inline declaration locally shadows currently effective notinline declarations.

     >(defun foo (x)
        (cons (car x)
              (locally (declare (inline car)) (car x))))
     foo
     >(defun bar (x)
        (cons (car x)
              (locally (declare (inline car)) (car x))))
     foo
     >(proclaim '(notinline car))
     nil
     >(compile 'foo)
     ...
     >(proclaim '(inline car))
     nil
     >(compile 'bar)
     ...

Usually, primitive functions such as car are compiled in-line. Therefore, in this example, only the first call to car within foo is compiled not in-line.

In general, the ecl compiler compiles functions in-line whenever possible. Thus an inline declaration (inline FUNCTION1 FUNCTION2 ...) is worthless if none of the named functions have previously been declared to be notinline.

 -- Declaration: ignore {variable-name}*
     Usually, the compiler issues a warning if a lexical variable is never referred to.  (ignore VAR1 ...  VARN) causes the compiler not to issue a warning even if the named variables are never referred to.  The compiler issues a warning if one of the named variables is not bound by the surrounding construct, or if a named variable is actually referred to.  ignore proclamations are simply ignored.

 -- Declaration: optimize {(quality value) | quality}*
     ecl supports the four optimize qualities listed in the Steele:84.

     speed and compilation-speed are used to set up the optimization switch of the C language compiler which is invoked to compile the C-language code generated by the ecl compiler (see Chapter 6).  (optimize (speed N)) and (optimize (compilation-speed M)) are equivalent, where N and M are integers between 0 and 3, and M is equal to 3-N.  When a ecl session is started, the speed quality is set to 3.  That is, by default, the compiler generates the fastest code in the longest compilation time.  The space quality specifies whether the code size is important or not: The compiled code is a little bit larger and faster when compiled with the space quality 0, than when compiled with the space quality 1, 2, or 3.  When a ecl session is started, the space quality is set to 0.  The safety quality determines how much runtime error checking code should be embedded in the compiled code.  If the safety quality is 0, the compiled code scarcely does runtime error checking.  If the safety quality is 1, then the compiled code for a function will check the number of arguments to the function at runtime.  If the safety quality is 2 or 3, then the compiled code does full runtime error checking.  In addition, the highest quality value 3 causes the compiler to treat all functions as if they were declared to be notinline.  When a ecl session is started, the safety quality is set to 0.

 -- Declaration: declaration {name}*
     A declaration declaration is used exactly as specified in the Steele:84.

 -- Declaration: object {variable-name}*
     This is the only declaration specifier that is specific to ecl. (object VAR1 ...  VARN) affects only variable bindings and specifies that the named variables can be allocated in the C stack (see Section 7.3).  The compiler issues a warning if one of the named variables is not bound by the surrounding construct. object proclamations are simply ignored.

Significant Type Specifiers
===========================

Whenever a declaration is encountered, each type specifier (if any) in the declaration is converted to one of the following type specifiers, which are collectively called the significant type specifiers.
          |------------   fixnum
          |------------   character
          |------------   short-float
          |------------   long-float
      t --|----   (array t)  --------------  (vector t)
          |----   (array fixnum)  ---------  (vector fixnum)
          |----   (array string-char)   ---  string
          |----   (array short-float)   ---  (vector short-float)
          |----   (array long-float)    ---  (vector long-float)
          |----   (array bit)   -----------   bit-vector

Here, the lines indicate subtype relations; the right type is a subtype of the left type.  For instance, (vector t) is a subtype of (array t) and true, and (array t) itself is a subtype of true.  However, (array t) and (array string-char) are disjoint types.

The function subtypep is used for the conversion to significant type specifiers: If the first value of (subtypep RAW-TYPE TYPE) is true for one of the significant type specifiers TYPE, then the type specifier RAW-TYPE in the declaration is converted to TYPE.  If there are more than one such significant type specifiers, then the type specifier that is a subtype of other specifiers is selected.  For example, type specifiers fixnum, (mod 3), and (member 0 1) are all converted to fixnum, though they are also subtypes of true.

Because of this type specifier conversion, ecl may sometimes regard two seemingly distinct declarations as the same.  For example, the following type declarations are completely equivalent, internally in ecl.

     (declare (type fixnum x)))

     (declare (type (mod 3) x))

     (declare (type (member 0 1) x))

Type specifiers in declaration specifications passed to the ecl specific function proclamation are also converted to significant type specifiers. Thus, for example,

     >(proclaim '(function foo (fixnum) fixnum))
     nil
     >(proclamation '(function foo ((mod 3)) (member 0 1)))
     t
     >(proclamation '(function foo (number) character))
     nil

The first call to proclamation returns true because both (mod 3) and (member 0 1) are converted to fixnum before the function type of foo is checked.

Treatment of Type Declarations
==============================

ecl uses several runtime stacks.

Arguments to functions, lexical and temporary variables are allocated on the C stack. Temporary values saved on the C stack may sometimes be represented as RAW DATA instead of pointers to heap-allocated cells.  Accessing such raw data on the C stack results in faster compiled code, partly because no pointer dereferencing operation is necessary, and partly because no cell is newly allocated on the heap when a new object is created. This is particularly helpful for numeric code which computes with floating point numbers.

ecl uses a conservative garbage collector to scan the C stack and find references to live object.

Variable Allocations
====================

If a lexical variable is declared to be of fixnum, character, short-float, long-float, or their subtypes, then it is allocated on the C stack rather than on the value stack.  In addition, the variable always has a raw datum as its value: 32 bit signed integer for fixnums, 8 bit character code with 24 bit padding for characters (remember that the font and bit fields of ecl characters are always 0), 32 bit floating point representation for short-floats, and 64 bit floating point representation for long-floats.  Similarly, if a lexical variable is named in an object declaration (see Section 7.1), then it is allocated on the C stack but, in this case, the variable always has a cell pointer as its value.  The user is strongly recommended to make sure that objects stored in such an object variable may never be garbage collected unexpectedly.  For example,

     (do ((x (foo) (cdr x)))
         ((endp x))
         (let ((y (car x)))
              (declare (object y))
           (bar y)))

this object declaration is completely safe because the value of the variable Y is always a substructure of the value of X, which in turn is protected against garbage collection.  Incidentally, loop variables of dolist may always be declared as object variables, since the dolist form has essentially the same control structure as the do form above.  On the other hand, the result of evaluation of the following form is unpredictable, because the cons cell pointed to from the object variable Z may be garbage collected before bar is called.

     (let ((z (cons x y)))
          (declare (object z))
       (foo (cons x y))
       (bar z))

Lexical variables that are not declared to be of fixnum, character, short-float, long-float, or their subtypes, and that are not named in object declarations are usually allocated on the value stack, but may possibly be allocated on the C stack automatically by the compiler.

Built-in Functions that Operate on Raw Data Directly
====================================================

Some built-in clisp functions can directly operate on raw data, if appropriate declarations are supplied.  The addition function + is among such functions.

     (let ((x 1))
          (declare (fixnum x))
       ...
       (setq x (+ x 2))
       ...
       )

In the compiled code for this let form, the raw fixnum datum (i.e., the 32 bit signed integer) stored in X is simply incremented by 2 and the resulting 32 bit signed integer is stored back into X.  The compiler is sure that the addition for 32 bit signed integers will be performed on the call to +, because the arguments are both fixnums and the return value must be also a fixnum since the value is to be assigned to the fixnum variable.  The knowledge of both the argument types and the return type is necessary for this decision: Addition of two fixnums may possibly produce a bignum and addition of two bignums may happen to produce a fixnum value.  If either the argument type or the return type were not known to the compiler, the general addition function would be called to handle the general case.  In the following form, for example, the compiler cannot be sure that the return value of the multiplication is a fixnum or that the arguments of the addition are fixnums.

     (setq x (+ (* x 3) 2))

In order to obtain the optimal code, a the special form should surround the multiplication.

     (setq x (+ (the fixnum (* x 3)) 2))

Built-in clisp functions that can directly operate on raw data are:

 1. arithmetic functions such as +,  -, 1+, 1-,  *, floor,  mod, /, and expt.

 2. predicates such as eq, eql, equal, zerop, plusp, minusp, =, /=, <, <=, >, >=, char=, char/=, char<, char<=, char>, and char>=.

 3. sequence processing functions that receive or return one or more fixnum values, such as nth, nthcdr, length, and elt.

 4. array access functions such as svref, char, schar, and aref (see below).

 5. system-internal functions for array update (see below).

 6. type-specific functions such as char-code, code-char, and float.

As mentioned in Section 2.5.1, array elements are represented in one of six ways depending on the type of the array.  By supplying appropriate array type declarations, array access and update operations can handle raw data stored in arrays.  For example,

     (let ((a (make-array n :element-type 'fixnum))
           (sum 0))
          (declare (type (array fixnum) a)
                   (fixnum sum))
       (dotimes (i n)             ;;; Array initialization.
                (declare (fixnum i))
          (setf (aref a i) i))
       ....
       (dotimes (i n)             ;;; Summing up the elements.
                (declare (fixnum i))
          (setq sum (+ (aref a i) sum)))
       ....
       )

The setf form replaces the i-th element of the array a by the raw fixnum value of i.  The aref form retrieves the raw fixnum datum stored in a.  This raw datum is then added to the raw fixnum value of the fixnum variable sum, producing the raw fixnum datum to be stored in sum.  Similar raw data handling is possible for arrays of types (array fixnum), (vector fixnum), (array string-char),  string, (array short-float),  (vector short-float), (array long-float), and (vector long-float).

Arguments/Values Passing
========================

Function proclamations (function FUNCTION-NAME (ARG-TYPE1 ARG-TYPE2 ...) RETURN-TYPE) or its equivalents give the compiler the chance to generate compiled code so that arguments to the named functions and resulting values of the named functions will be passed via the C stack, thus increasing the efficiency of calls to these functions.  Such arguments/values passing via the C stack is possible only if the called function is also defined in the same source file.  This is because the code for the called function must have two entries: One entry for C arguments/values passing and another for ordinary Lisp arguments/values passing.  (An ordinary function has only the latter entry.)  When the latter entry is used, the arguments are unboxed and passed to the former entry.  On return from the function, the resulting value is cast into a Lisp data type.

A good example of this follows.

     (eval-when (compile)
       (proclaim '(function tak (fixnum fixnum fixnum) fixnum)))

     (defun tak (x y z)
       (declare (fixnum x y z))
       (if (not (< y x))
           z
           (tak (tak (1- x) y z)
                (tak (1- y) z x)
                (tak (1- z) x y))))

     ;;; Call (tak 18 12 6).

When tak is called with the arguments 18, 12, and 6, the raw fixnum data of the arguments are set to the parameters x, y, z.  After that, only raw C data are used to perform the execution: No cell pointers are newly allocated nor even referenced.  The built-in functions < and 1- directly operate on the raw data.  Only at the return from the top-level call of tak, the resulting raw data value (which happens to be 7) is reallocated on the heap.  Note that both the function proclamation and the local fixnum declaration are necessary to obtain the optimal code.  The function proclamation is necessary for arguments/values passing via the C stack and the fixnum declaration is necessary to unbox the parameters into C variables.

Operating System Interface
**************************

ecl provides the following facilities that are not defined in Steele:84.

 -- Function: system string
     Executes a Shell command as if STRING is an input to the Shell.  On return from the Shell command, system returns the exit code of the command as an integer.

 -- Function: open-pipe string
     Executes a Shell command as if STRING is an input to the Shell.  It returns a stream corresponding to the output stream of the Shell command, from which one can read its output.

 -- Function: quit optional exit-code
     Terminates ecl and returns the EXIT-CODE to the parent process. EXIT-CODE must be an integer and its default value is 0.

Macros
******

A defmacro lambda-list is a lambda-list-like construct that is used as the third element in the defmacro form,

     (defmacro NAME EFMACRO-LAMBDA-LIST [DECLARATION | DOC-STRING] {FORM}*)

The description of defmacro lambda-lists in Steele:84 is quite ambiguous.  ecl employs the following syntax.

The complete syntax of a defmacro lambda-list is:

     ( [&whole VAR]
       [&environment VAR]
       [PSEUDO-VAR]
       [optional {var | ( pseudo-var [initform [pseudo-var]] )}]
       {[{rest | &body} pseudo-var]
        [keys {var
               | ({var | (keyword pseudo-var)} [initform [pseudo-var]])}*
         [allow]]
        [aux {var | (pseudo-var [initform])}*]
        | . var }
     )

where PSEUDO-VAR is either a symbol or a list of the following form:

     ( {pseudo-var}*
       [optional {var | (pseudo-var [initform [pseudo-var]])}*]
       {[{rest | &body} pseudo-var]
        [keys {var | ({var | (keyword pseudo-var)}
                       [initform [pseudo-var]])}*
         [allow]]
        [aux {var | (pseudo-var [initform])}]
       | . var }
     )

The defmacro lambda-list keyword &whole may appear only at the top-level, first in the defmacro lambda-list.  It is not allowed within PSEUDO-VAR.  Use of the &whole keyword does not affect the processing of the rest of the defmacro lambda-list:

     (defmacro foo (&whole w x y) ...)

and

     (defmacro foo (x y) ...)

both bind the variables x and y to the second and the third elements, respectively, of macro forms of foo.

The defmacro lambda-list keyword &environment may appear only at the top-level, first in the defmacro lambda-list if &whole is not supplied, or immediately after the variable that follows &whole, if &whole is supplied.  &environment is not allowed within PSEUDO-VAR.  Like &whole, use of &environment does not affect the processing of the rest of the defmacro lambda-list.  If an &environment parameter is supplied and if this parameter is not used at all, then the ecl compiler will issue a warning.  To suppress the warning, just remove the parameter from the defmacro lambda-list, or add an ignore declaration.

The defmacro lambda-list keyword &body is completely equivalent to the rest keyword.  ecl takes no special action for &body parameters.

Although useless, ecl allows supplied-p parameters to be destructured. This is useless because supplied-p parameters can never be bound to a non-empty list.  Our intention is to stick to the specification in the Steele:84 as far as possible, even if it is silly to do so.

Like for ordinary lambda-lists, the interpreter detects invalid arguments to macro expansion functions.  When a parameter is destructured, the structure of the corresponding argument is also checked.  Such runtime argument checking may or may not be embedded in compiled code, depending on the environment when the code was generated.  If the code was generated while the safety optimize level is zero (that is, while the value of (proclamation '(optimize (safety 0))) is true), then the generated code does not perform argument checking at all.  Otherwise, the compiled code does check the validity of arguments.

CLOS
****

 -- Generic: add-method generic-function method
 -- Method: add-method (generic-function standard-generic-function) (method method)

 -- Macro: call-method method next-method-list

 -- Macro: call-next-method rest args

 -- Generic: change-class instance new-class
 -- Method: change-class (instance standard-object) (new-class standard-class)
 -- Method: change-class (instance t) (new-class symbol)

 -- Generic: class-name class
 -- Method: class-name (class class)

 -- Generic: (setf class-name) new-value class
 -- Method: (setf class-name) new-value (class class)

 -- Function: class-of object
     The function class-of returns the class of which the given object is an instance.  The argument to class-of may be any clisp object.

 -- Function: compute-applicable-methods generic-function function-arguments

 -- Macro: defclass class-name ({superclass-name}*) ({slot-specifier}*) [class-option]

          CLASS-NAME ::= SYMBOL
          SUPERCLASS-NAME ::= SYMBOL
          SLOT-SPECIFIER ::= SLOT-NAME | (SLOT-NAME [SLOT-OPTION])
          SLOT-NAME ::= SYMBOL
          SLOT-OPTION ::= {:reader READER-FUNCTION-NAME}*
                  | {:writer WRITER-FUNCTION-NAME}*
                  | {:accessor READER-FUNCTION-NAME}*
                  | {:allocation ALLOCATION-TYPE}
                  | {:initarg INITARG-NAME}*
                  | {:initform FORM}
                  | {:type TYPE-SPECIFIER}
                  | {:documentation STRING}
          READER-FUNCTION-NAME ::= SYMBOL
          WRITER-FUNCTION-NAME ::= FUNCTION-NAME
          FUNCTION-NAME ::= SYMBOL |(setf SYMBOL)
          INITARG-NAME ::= SYMBOL
          ALLOCATION-TYPE ::= :instance | :class
          CLASS-OPTION ::= (:default-initargs INITARG-LIST)
                  | (:documentation STRING)
                  | (:metaclass CLASS-NAME)
          INITARG-LIST ::= {INITARG-NAME DEFAULT-INITIAL-VALUE-FORM}*

 -- Macro: defgeneric function-name lambda-list [option | {method-description}*]

          FUNCTION-NAME ::= SYMBOL | (setf SYMBOL)
          LAMBDA-LIST ::= ({VAR}*
                  [optional {VAR | (VAR)}*]
                  [rest VAR]
                  [keys {KEYWORD-PARAMETER}* [allow]])
          KEYWORD-PARAMETER ::= VAR | ( {VAR | (KEYWORDVAR )})
          OPTION ::= (:argument-precedence-order {PARAMETER-NAME}+)
                  | (declare {DECLARATION}+)
                  | (:documentation STRING)
                  | (:method-combination symbol {ARG}*)
                  | (:generic-function-class CLASS-NAME)
                  | (:method-class CLASS-NAME)
          METHOD-DESCRIPTION ::=
                  (:method {METHOD-QUALIFIER}* SPECIALIZED-LAMBDA-LIST
                   [{DECLARATION}* | DOCUMENTATION]
                   {FORM}*)
          METHOD-QUALIFIER ::= NON-NIL-ATOM
          SPECIALIZED-LAMBDA-LIST ::= ({VAR | (VAR PARAMETER-SPECIALIZER-NAME)}*
                  [optional {VAR | (VAR [INITFORM [SUPPLIED-P-PARAMETER]])}*]
                  [rest VAR]
                  [keys {SPECIALIZED-KEYWORD-PARAMETER}* [allow]])
                  [aux {VAR | (VAR [INITFORM])}*] )
          SPECIALIZED-KEYWORD-PARAMETER ::= VAR
                  | {({VAR | (KEYWORDVAR)} [INITFORM [SUPPLIED-P-PARAMETER]])}*
          PARAMETER-SPECIALIZER-NAME ::= SYMBOL | (eql EQL-SPECIALIZER-FORM)

 -- Macro: define-method-combination name [short-form-option]
 -- Macro: define-method-combination name lambda-list ({method-group-specifier}*) [(:arguments . lambda-list)] [(:generic-function generic-fn-symbol)] [{declaration}* | doc-string] {form}*

          SHORT-FORM-OPTION ::= :documentation STRING
                                  | :identity-with-one-argument BOOLEAN
                                  | :operator OPERATOR
          METHOD-GROUP-SPECIFIER ::= (VARIABLE  {QUALIFIER-PATTERN}+ | PREDICATE
                                  [LONG-FORM-OPTION])
          LONG-FORM-OPTION ::= :description FORMAT-STRING
                                  | :order ORDER
                                  | :required BOOLEAN

 -- Macro: defmethod function-name {method-qualifier}+ specialized-lambda-list [{declaration}* | doc-string] {form}*

          FUNCTION-NAME ::= SYMBOL | (setf SYMBOL)
          METHOD-QUALIFIER ::= NON-NIL-ATOM
          PARAMETER-SPECIALIZER-NAME ::= SYMBOL | (eql EQL-SPECIALIZER-FORM )

 -- Generic: documentation x optional doc-type
 -- Method: documentation (method standard-method) optional doc-type
 -- Method: documentation (generic-function standard-generic-function) optional doc-type
 -- Method: documentation (class standard-class) optional doc-type
 -- Method: doumentation (method-combination method-combination) optional doc-type
 -- Method: documentation (slot-description standard-slot-description) optional doc-type
 -- Method: documentation (symbol symbol) optional doc-type
 -- Method: documentation (list list) optional doc-type

 -- Generic: (setf documentation) new-value x optional doc-type
 -- Method: (setf documentation) new-value (method standard-method) optional doc-type
 -- Method: (setf documentation) new-value (class standard-class) optional doc-type
 -- Method: (setf documentation) new-value (method-combination method-combination)
 -- Method: (setf documentation) new-value (slot-description standard-slot-description) optional doc-type
 -- Method: (setf documentation) new-value (symbol symbol) optional doc-type
 -- Method: (setf documentation) new-value (list list) optional doc-type

 -- Function: ensure-generic-function {function-name keys lambda-list:argument-precedence-order :declare :documentation :generic-function-class|ekeys:method-combination :method-class :environment}

          function-name ::= symbol | (setf symbol)

 -- Function: find-class symbol optional errorp environment

     The function find-class returns the class object named by the given symbol in the given environment. The first argument to find-class is a symbol.

 -- Generic: find-method generic-function method-qualifiers specializers optional errorp
 -- Method: find-method (generic-function standard-generic-function)
     method-qualifiers specializers  optional errorp

 -- Generic: function-keywords method
 -- Method: function-keywords (method standard-method)

The generic function function-keywords is used to return the keyword parameter specifiers for a given method.

 -- Macro: generic-function {lambda-list \mchoiceoption | {method-description}*}

          option ::= (:argument-precedence-order {parameter-name}+)
                  | (declare {declaration}+)
                  | (:documentation string)
                  | (:method-combination symbol {arg}*)
                  | (:generic-function-class class-name)
                  | (:method-class class-name)
          method-description ::= (:method {method-qualifier}*
                                          specialized-lambda-list
                                          {declaration | DOCUMENTATION}*
                                          {form}*)

     The generic-function macro creates an anonymous generic function. The generic function is created with the set of methods specified by its method descriptions.  The OPTION, METHOD-QUALIFIER, and SPECIALIZED-LAMBDA-LIST arguments are the same as for defgeneric. The generic function object is returned as the result.  If no method descriptions are specified, an anonymous generic function with no methods is created.  See defgeneric, generic-flet, generic-labels, defmethod.

 -- Generic: initialize-instance instance rest initargs
 -- Method: initialize-instance (instance standard-object) rest initargs

     The generic function initialize-instance is called by make-instance to initialize a newly created instance.  The generic function initialize-instance is called with the new instance and the defaulted initialization arguments.

 -- Function: invalid-method-error method format-string rest args

     The function invalid-method-error is used to signal an error when there is an applicable method whose qualifiers are not valid for the method combination type.  The error message is constructed by using a format string and any arguments to it.  Because an implementation may need to add additional contextual information to the error message, invalid-method-error should be called only within the dynamic extent of a method combination function.  The function invalid-method-error is called automatically when a method fails to satisfy every qualifier pattern and predicate in a define-method-combination form.  A method combination function that imposes additional restrictions should call invalid-method-error explicitly if it encounters a method it cannot accept.

 -- Generic: make-instance class rest INITARGS
 -- Method: make-instance (class standard-class) rest initargs
 -- Method: make-instance (class symbol) rest initargs

     The generic function make-instance creates and returns a new instance of the given class.  The generic function make-instance may be used as described in section 1.9.  The class argument is a class object or a symbol that names a class.  The remaining arguments form a list of alternating initialization argument names and values.  If the second of the above methods is selected, that method invokes make-instance on the arguments (find-class class) and initargs.  The initialization arguments are checked within make-instance (see section 1.9).  The new instance is returned.

 -- Generic: make-instances-obsolete class
 -- Method: make-instances-obsolete (class standard-class)
 -- Method: make-instances-obsolete (class symbol)

 -- Function: method-combination-error format-string rest args

     The function method-combination-error is used to signal an error in method combination.  The error message is constructed by using a format string and any arguments to it.  Because an implementation may need to add additional contextual information to the error message, method-combination-error should be called only within the dynamic extent of a method combination function.  The format-string argument is a control string that can be given to format, and args are any arguments required by that string.

 -- Generic: method-qualifiers method
 -- Method: method-qualifiers (method standard-method)

     The generic function method-qualifiers returns a list of the qualifiers of the given method.

 -- Function: next-method-p

     The locally defined function next-method-p can be used within the body of a method defined by a method-defining form to determine whether a next method exists.

 -- Generic: no-applicable-method generic-function rest function-arguments
 -- Method: no-applicable-method (generic-function t) rest function-arguments

     The generic function no-applicable-method is called when a generic function of the class standard-generic-function is invoked and no method on that generic function is applicable. The default method signals an error.

 -- Generic: no-next-method generic-function method rest args
 -- Method: no-next-method (generic-function standard-generic-function) (method standard-method) rest args

 -- Generic: print-object object stream
 -- Method: print-object (object standard-object) stream

     The generic function print-object writes the printed representation of an object to a stream.  The function print-object is called by the print system; it should not be called by the user.

 -- Generic: reinitialize-instance instance rest initargs
 -- Method: reinitialize-instance (instance standard-object) rest initargs

     The generic function reinitialize-instance can be used to change the values of local slots according to initialization arguments.  This generic function is called by the Meta-Object Protocol.  It can also be called by users.

 -- Generic: remove-method generic-function method
 -- Method: remove-method (generic-function standard-generic-function) method

     The generic function remove-method removes a method from a generic function. It destructively modifies the specified generic function and returns the modified generic function as its result.

 -- Generic: shared-initialize INSTANCE SLOT-NAMES REST INITARGS
 -- Method: shared-initialize (instance standard-object) slot-names rest initargs

     The generic function shared-initialize is used to fill the slots of an instance using initialization arguments and :initform forms.  It is called when an instance is created, when an instance is re-initialized, when an instance is updated to conform to a redefined class, and when an instance is updated to conform to a different class.  The generic function shared-initialize is called by the system-supplied primary method for initialize-instance, reinitialize-instance, update-instance-for-redefined-class, and update-instance-for-different-class.

 -- Function: slot-boundp instance slot-name

     The function slot-boundp tests whether a specific slot in an instance is bound. The arguments are the instance and the name of the slot.

 -- Function: slot-exists-p object slot-name

     The function slot-exists-p tests whether the specified object has a slot of the given name.  The object argument is any object.  The slot-name argument is a symbol.

 -- Function: slot-makunbound instance slot-name

     The function slot-makunbound restores a slot in an instance to the unbound state.  The arguments to slot-makunbound are the instance and the name of the slot.

 -- Generic: slot-missing class object slot-name operation optional new-value
 -- Method: slot-missing (class t) object slot-name operation optional new-value

     The generic function slot-missing is invoked when an attempt is made to access a slot in an object whose metaclass is standard-class and the name of the slot provided is not a name of a slot in that class.  The default method signals an error.

 -- Generic: slot-unbound class instance slot-name
 -- Method: slot-unbound (class t) instance slot-name

     The generic function slot-unbound is called when an unbound slot is read in an instance whose metaclass is standard-class. The default method signals an error.

 -- Function: slot-value object slot-name

     The function slot-value returns the value contained in the slot slot-name of the given object.  If there is no slot with that name, slot-missing is called. If the slot is unbound, slot-unbound is called.  The macro setf can be used with slot-value to change the value of a slot.

 -- Generic: update-instance-for-different-class previous current rest initargs
 -- Method: update-instance-for-different-class (previous standard-object) (currentstandard-object) rest initargs

 -- Generic: update-instance-for-redefined-class instance added-slots discarded-slots property-list rest initargs
 -- Method: update-instance-for-redefined-class (instance standard-object) added-slots discarded-slots property-list rest initargs

 -- Macro: with-accessors ({slot-entry}*) instance-form {declaration}* {form}*

     The macro with-accessors creates a lexical environment in which specified slots are lexically available through their accessors as if they were variables.  The macro with-accessors invokes the appropriate accessors to access the specified slots.  Both setf and setq can be used to set the value of the slot.  The result returned is that obtained by executing the forms specified by the body argument.

 -- Macro: with-slots ({slot-entry}*) instance-form {declaration}* {form}*

          SLOT-ENTRY ::= SLOT-NAME | (VARIABLE-NAME SLOT-NAME)

     The macro with-slots creates a lexical context for referring to specified slots as though they were variables.  Within such a context the value of the slot can be specified by using its slot name, as if it were a lexically bound variable.  Both setf and setq can be used to set the value of the slot.

Multithread
***********

[To come once the interface is fixed]

Bibliography
************

ANSI
     ANSI clisp Specification, 1986.

Steele:84
     Guy L. Steele Jr. et al. ``Common Lisp: the Language'', Digital Press, 1984.

Steele:90
     Guy L. Steele Jr. at al. ``Common Lisp: the Language II'', second edition, Digital Press, 1990.

Yasa:85
     Taiichi Yuasa and Masami Hagiya ``Kyoto clisp Report'', Research Institute for Mathematical Sciences, Kyoto University, 1988.

Smith:84
     B.C. Smith and J. des Rivieres  ``The Implementation of Procedurally Reflective Languages'', Proc. of the 1984 ACM Symposium on LISP and Functional Programming, 1984.