This is ecl.info, produced by makeinfo version 4.8 from
/work/a/ports/lang/ecl/work/ecl-0.9g/src/doc/user.txi.

INFO-DIR-SECTION Lisp Programming
START-INFO-DIR-ENTRY
* ecl: (ecl).           Embeddable Common Lisp (ECL) User's Manual
END-INFO-DIR-ENTRY

   ECL is an implementation of Common-Lisp designed for being
_embeddable_ into C based applications.

Copyright (C) 2000, Juan Jose Garcia-Ripoll Copyright (C) 1990,
Giuseppe Attardi


File: ecl.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)

Top
***

   ECL is an implementation of Common-Lisp originally designed for being
_embeddable_ into C based applications.  This document describes the
ECL implementation and how it differs from [ANSI, *note Bibliography::]
and [Steele:84, *note Bibliography::].  See *note (ecldev)Top:: for
details about the implementation and how to interface with other
languages.

* Menu:

* Introduction::                What ECL is and how to install it.
* Standards::                   Deviations from standards.
* Input and output::            Accessing files with ECL.
* Memory management::           Bits and bytes of every object.
* Program development::         Tracing, steppping, error handling, etc.
* The interpreter::             The guts behind ECL.
* The compiler::                When you need speed...
* Declarations::                Helping the compiler
* OS interface::                Operating system interface.
* Macros::                      Implementation dependent features of macros.
* CLOS::                        Common-Lisp's Object System.
* Multithread::                 Lisp lightweight processes or threads.
* Bibliography::                Some interesting books.


File: ecl.info,  Node: Introduction,  Next: Standards,  Prev: Top,  Up: Top

1 Introduction
**************

ECL is an implementation of the Common-Lisp language that was developed
by Giuseppe Attardi's up from the Kyoto Common-Lisp. See *Note 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, *note
Bibliography::], the aim of ECL is now to achieve maximum compliance
with ANSI Common-Lisp, the most up to date standard for Common-Lisp.

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

* Menu:

* Credits::
* Copyright::
* Installation::                Installing a binary distribution.
* Rebuilding ECL::              Building ECL from sources.
* Invoking ECL::                Basic skills.


File: ecl.info,  Node: Credits,  Next: Copyright,  Prev: Introduction,  Up: Introduction

1.1 Credits
===========

The ECL project is an implementation of the Common-Lisp language that
aims to comply with the ANSI Common-Lisp 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
Common-Lisp, 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
Common-Lisp 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, *note Bibliography::]

   The following people or organizations must be credited for support
in the development of Kyoto Common-Lisp: 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 Common-Lisp (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.


File: ecl.info,  Node: Copyright,  Next: Installation,  Prev: Credits,  Up: Introduction

1.2 Copyright
=============

Copyright (C) 2000 Juan Jose Garcia Ripoll

Copyright (C) 1990, 1991, 1993 Giuseppe Attardi

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


File: ecl.info,  Node: Installation,  Next: Rebuilding ECL,  Prev: Copyright,  Up: Introduction

1.3 Installation
================

*** *** Building of binary distributions has been discontinued. The ***
following paragraphs do not apply ***

   Usually I build current binaries for the platforms I have access to,
and these are placed in
Linux
     `http://www.arrakis.es/~worm/ecl-linux.tgz'

FreeBSD (>= 4.0)
     `http://www.arrakis.es/~worm/ecl-freebsd.tgz'

   To install them you need only unpack them on the root directory, and
the program will install itself under
     /usr/local/bin		ecl program
     /usr/local/lib/ecl	libraries and headers
     /usr/local/man/man1     ecl.1 manual page
     /usr/local/info         ecl.info user guide

   The flags which I used to build the program are summarized in
`/usr/local/lib/ecl/BUILD-STAMP'. You should check that they correspond
to your needs before using ECL -i.e., it could be a too old version,
garbage collector might not be the right one or TCP/IP support could
have been removed.


File: ecl.info,  Node: Rebuilding ECL,  Next: Invoking ECL,  Prev: Installation,  Up: Introduction

1.4 Rebuilding 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. Make sure everything went OK with the configuration.  The
     configuration script figures out the machine where it is running
     and creates a directory `machine' where to perform the
     installation.  If the program fails to recognize the machine, you
     will have to check whether it is one of the supported machines
     present in `src/h/machine.h'.

  7. 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:
         /usr/local/bin/ecl               the ECL interpreter and compiler

     Help documents:
         /usr/local/lib/ecl/help.doc      data for the online help
         /usr/local/man/man1/ecl.1        manual page for ECL
         /usr/local/info/ecl.info         this manual you are reading

     Library files and headers:
         /usr/local/lib/ecl/libecl.a      the core library in C
         /usr/local/lib/ecl/libgmp.a      GNU library for bignums
         /usr/local/lib/ecl/libgc.a       Boehm-Weiser garbage collector
         /usr/local/lib/ecl/*.a           Other lisp compiled code
         /usr/local/lib/ecl/h/            Header files

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


File: ecl.info,  Node: Invoking ECL,  Prev: Rebuilding ECL,  Up: Introduction

1.5 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 itunder 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 ().

   The top-level loop of ECL is almost the same as that defined in
Section 20.2 of [Steele:84, *note Bibliography::].  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.
     >>


File: ecl.info,  Node: Standards,  Next: Input and output,  Prev: Introduction,  Up: Top

2 Standards
***********

ECL supports all Common-Lisp data types exactly as defined in the
[Steele:84, *note Bibliography::].  This chapter simply complements
Chapter 2 of [Steele:84, *note Bibliography::], by describing
implementation dependent features of Common-Lisp data types.  Each
section in this chapter corresponds to the section in Chapter 2 of
[Steele:84, *note Bibliography::], with the same section title.

* Menu:

* Numbers::
* Characters::
* Symbols::
* List and conses::
* Arrays::
* Hash tables::
* Readtables::
* Packages::
* Pathnames::
* Streams::
* Random-states::
* Structures::
* Functions::
* Unreadable data objects::
* Overlap of types::
* ANSI-CL compliance::


File: ecl.info,  Node: Numbers,  Next: Characters,  Prev: Standards,  Up: Standards

2.1 Numbers
===========

* Menu:

* Integers::
* Ratios::
* Floating-point numbers::
* Complex numbers::


File: ecl.info,  Node: Integers,  Next: Ratios,  Prev: Numbers,  Up: Numbers

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

   Common-Lisp 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, *note Bibliography::] for their
meanings.


File: ecl.info,  Node: Ratios,  Next: Floating-point numbers,  Prev: Integers,  Up: Numbers

2.1.2 Ratios
------------

There are no implementation-dependent features for ratios.


File: ecl.info,  Node: Floating-point numbers,  Next: Complex numbers,  Prev: Ratios,  Up: Numbers

2.1.3 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       53 bits   11 bits

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

   Common-Lisp constants related to floating-point numbers have the
following values in ECL.
     most-positive-short-float
       = most-positive-single-float
       = - most-negative-short-float
       = - most-negative-single-float
       = 3.402823s38

     least-positive-short-float
       = least-positive-single-float
       = - least-negative-short-float
       = - least-negative-single-float
       = 1.401298s-45

     most-positive-long-float
       = most-positive-double-float
       = - most-negative-long-float
       = - most-negative-double-float
       = 1.797693134862315f308

     least-positive-long-float
       = least-positive-double-float
       = - least-negative-long-float
       = - least-negative-double-float
       = 4.940656458412469f-324

     short-float-epsilon
       = 2.980232s-8

     short-float-negative-epsilon
       = 2.980232s-8

     long-float-epsilon
       = double-float-epsilon
       = single-float-epsilon
       = 5.5511151231257827f-17

     long-float-negative-epsilon
       = double-float-negative-epsilon
       = single-float-negative-epsilon
       = 5.5511151231257827f-17

     pi = 3.141592653589793

   See Chapter 12 of [Steele:84, *note Bibliography::] for their
meanings.


File: ecl.info,  Node: Complex numbers,  Prev: Floating-point numbers,  Up: Numbers

2.1.4 Complex Numbers
---------------------

There are no implementation-dependent features for complex numbers.


File: ecl.info,  Node: Characters,  Next: Symbols,  Prev: Numbers,  Up: Standards

2.2 Characters
==============

ECL is fully ANSI Common-Lisp compliant in all aspects of the character
data type, with the following peculiarities.

* Menu:

* Character types::
* Standard characters::
* Line divisions::
* Non-standard characters::
* Character attributes::


File: ecl.info,  Node: Character types,  Next: Standard characters,  Prev: Characters,  Up: Characters

2.2.1 Character types
---------------------

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


File: ecl.info,  Node: Standard characters,  Next: Line divisions,  Prev: Character types,  Up: Characters

2.2.2 Standard Characters
-------------------------

ECL supports all standard and semi-standard characters listed in Section
2.2.1 of [Steele:84, *note Bibliography::].  Non-printing characters
have the following character codes.
     Character        Code  (in octal)
     --------------------------------
     #\Null                  000
     #\Space                 040
     #\Newline               012
     #\Backspace             010
     #\Tab                   011
     #\Linefeed              012
     #\Page                  014
     #\Return                015
     #\Rubout                177

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


File: ecl.info,  Node: Line divisions,  Next: Non-standard characters,  Prev: Standard characters,  Up: Characters

2.2.3 Line Divisions
--------------------

Since ECL represents the `#\Newline' character by a single code 12,
problems with line divisions discussed in Section 2.2.2 of the
[Steele:84, *note Bibliography::] are absent in ECL.


File: ecl.info,  Node: Non-standard characters,  Next: Character attributes,  Prev: Line divisions,  Up: Characters

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

ECL supports no additional non-standard characters.


File: ecl.info,  Node: Character attributes,  Prev: Non-standard characters,  Up: Characters

2.2.5 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, *note Bibliography::].


File: ecl.info,  Node: Symbols,  Next: List and conses,  Prev: Characters,  Up: Standards

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


File: ecl.info,  Node: List and conses,  Next: Arrays,  Prev: Symbols,  Up: Standards

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

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


File: ecl.info,  Node: Arrays,  Next: Hash tables,  Prev: List and conses,  Up: Standards

2.5 Arrays
==========

ECL arrays can have up to 64 ranks.

   When the value of the Common-Lisp variable `*print-array*' (see
Section 22.1.6 of [Steele:84, *note Bibliography::]) is (), 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 ().

   Common-Lisp constants related to arrays have the following values in
ECL.

         array-dimension-limit = 16777216
         array-rank-limit = 64
         array-total-size-limit = 16777216

   See Section 17.1 of [Steele:84, *note Bibliography::] for their
meanings.

* Menu:

* Vectors::
* Strings::
* Bit-Vectors::


File: ecl.info,  Node: Vectors,  Next: Strings,  Prev: Arrays,  Up: Arrays

2.5.1 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


File: ecl.info,  Node: Strings,  Next: Bit-Vectors,  Prev: Vectors,  Up: Arrays

2.5.2 Strings
-------------

The ECL implementation of strings is ANSI Common-Lisp 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.


File: ecl.info,  Node: Bit-Vectors,  Prev: Strings,  Up: Arrays

2.5.3 Bit-Vectors
-----------------

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


File: ecl.info,  Node: Hash tables,  Next: Readtables,  Prev: Arrays,  Up: Standards

2.6 Hash Tables
===============

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


File: ecl.info,  Node: Readtables,  Next: Packages,  Prev: Hash tables,  Up: Standards

2.7 Readtables
==============

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


File: ecl.info,  Node: Packages,  Next: Pathnames,  Prev: Readtables,  Up: Standards

2.8 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 xlib

   The `compiler' package contains symbols used by the ECL compiler.
Other packages are described in Section 11.6 of [Steele:84, *note
Bibliography::].  The `clos' package is used for the internal symbols
of the Common-Lisp Object System, which is described in Chapter 14.
The `xlib' package is used for the internal symbols of CLX, the
Common-Lisp Language X Interface to the X Window System, which is
described in a separate manual.

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


File: ecl.info,  Node: Pathnames,  Next: Streams,  Prev: Packages,  Up: Standards

2.9 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 Common-Lisp variable
*DEFAULT-PATHNAME-DEFAULTS* is `#P""' (or, equivalently, `(pathname
"")').

   A pathname in the file system of Common-Lisp 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 ().
          ".lsp"
               name:          nil
               type:          "lsp"

   If a namestring contains no period, the filetype is ().
         "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 ().
          "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 :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 (), 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


File: ecl.info,  Node: Streams,  Next: Random-states,  Prev: Pathnames,  Up: Standards

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


File: ecl.info,  Node: Random-states,  Next: Structures,  Prev: Streams,  Up: Standards

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


File: ecl.info,  Node: Structures,  Next: Functions,  Prev: Random-states,  Up: Standards

2.12 Structures
===============

There are no implementation-dependent features for structures.


File: ecl.info,  Node: Functions,  Next: Unreadable data objects,  Prev: Structures,  Up: Standards

2.13 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 NAME>
     #<interpreted-function `address'>
   Compiled functions (including compiled macro-expansion functions)
are printed in the following formats.
     #<compiled-function 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.

   Common-Lisp constants related to functions have the following values
in ECL.

     call-arguments-limit = 64
     lambda-list-keywords = (&optional &rest &key &allow-other-keys
                             &aux &whole &environment &body)
     lambda-parameters-limit = 64
     multiple-values-limit = 32

   Refer to [Steele:84, *note Bibliography::] for their meanings.


File: ecl.info,  Node: Unreadable data objects,  Next: Overlap of types,  Prev: Functions,  Up: Standards

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

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


File: ecl.info,  Node: Overlap of types,  Next: ANSI-CL compliance,  Prev: Unreadable data objects,  Up: Standards

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


File: ecl.info,  Node: ANSI-CL compliance,  Prev: Overlap of types,  Up: Standards

2.16 ANSI-CL compliance
=======================

In this section we have documented the how much ECL implements of each
section in [ANSI, *note Bibliography::], and which are the most
important implementation-dependent features.

   5. Data and control flow

   * nth-value

   10. Symbols:

   * make-symbol: string becomes part of symbol

   * symbol-name, copy-symbol

   * gensym, fails for numeric argument >= MOST-POSITIVE-FIXNUM

   * *gensym-counter*

   11. Packages:

   * package-name

   * intern accepts any string designator, not only strings.

   12. Numbers:

   * floor, ceiling, truncate, round

   * float, complex, realpart, imagpart, numerator, denominator

   * zerop, plusp, minusp, evenp, oddp

   * =, /=, <=, >=, <, >, +, -, *, /, 1+, 1- but they do not fail for
     single       non numeric argument

   * max, min, but they do not contagiate floating-point nature.

   * minusp, plusp, zerop

   * sin, cos, tan

   * pi

   * existence and behavior of -0.0 is not assured, with all failures
        of compliance that it implies.

   * since we do not have conditions, mathematical errors are simple
       errors.

   13. Characters: complete

   * character = base-char > standard-char

   * empty-char is an empty type

   14. Conses:

   * last

   16. Strings: complete

   * string-char = base-char

   * simple-string-char = simple-base-char

   * When :start1 or :start2 parameters are NIL they are taken as 0.

   19. Filenames: complete, but simplistic

   * :wild-inferiors is not supported

   * of the possible wildcard combinations, only `:wild' works as
     expected.

   * in `#'pathname-match-p' a `nil' directory is not regarded as
     `:wild'.

   * enough-namestring does not return optimal namestring

   20. Files:

   * truename

   * rename-file

   * directory


File: ecl.info,  Node: Input and output,  Next: Memory management,  Prev: Standards,  Up: Top

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

* Menu:

* Read macros::
* Input/Output functions::
* Network streams::
* CLOS streams::


File: ecl.info,  Node: Read macros,  Next: Input/Output functions,  Prev: Input and output,  Up: Input and output

3.1 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, *note
Bibliography::], 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 '`#.''.


File: ecl.info,  Node: Input/Output functions,  Next: Network streams,  Prev: Read macros,  Up: Input and output

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

The input and output functions of ECL almost follow the definitions in
Chapter 22 of [Steele:84, *note Bibliography::].  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,
*note Bibliography::] are listed below.

 -- Function: load PATHNAME &key :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*'


File: ecl.info,  Node: Network streams,  Next: CLOS streams,  Prev: Input/Output functions,  Up: Input and output

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


File: ecl.info,  Node: CLOS streams,  Prev: Network streams,  Up: Input and output

3.4 CLOS Streams
================

When the optional CLOS subsystem is available, an interface is provided
by ECL for using CLOS objects as Common-Lisp 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 Common-Lisp I/O functions such as `read', `listen',
`prin1', etc.  The fundamental interface to `clos-stream' objects
consists of (generic) functions which implement the basic Common-Lisp
character stream operations (see Common-Lisp, 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.

* Menu:

* CLOS Stream Input::
* CLOS Stream Output::
* CLOS Stream common::


File: ecl.info,  Node: CLOS Stream Input,  Next: CLOS Stream Output,  Prev: CLOS streams,  Up: CLOS streams

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


File: ecl.info,  Node: CLOS Stream Output,  Next: CLOS Stream common,  Prev: CLOS Stream Input,  Up: CLOS streams

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

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


File: ecl.info,  Node: CLOS Stream common,  Prev: CLOS Stream Output,  Up: CLOS streams

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


File: ecl.info,  Node: Memory management,  Next: Program development,  Prev: Input and output,  Up: Top

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

* Menu:

* Implementation types::
* Heap and relocatable areas::
* The garbage collector::
* Allocation functions::
* Storage information::


File: ecl.info,  Node: Implementation types,  Next: Heap and relocatable areas,  Prev: Memory management,  Up: Memory management

4.1 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
Common-Lisp 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
`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    `contiguous'
         table'   
`symbol' `symbol  `relocatable'
         name'    
`package'`hash    `contiguous'
         table'   
`array'  `array   `relocatable
         body'    or
                  contiguous'
`hash-table'`hash    `relocatable'
         table'   
`vector' `vector  `relocatable
         body'    or
                  contiguous'
`bit-vector'`bit-vector`relocatable
         body'    or
                  contiguous'
`stream' `I/O     `contiguous'
         buffer'  
`cclosure'`code'   `contiguous'
`string' `string  `relocatable
         body'    or
                  contiguous'
`cfun'   `code'   `contiguous'
`structure'`structure`relocatable'
         body'    
`instance'`instance`relocatable'
         slots'   
`thread' `thread  `contiguous'
         data'    

   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-() value, then the body of the array is allocated
as a contiguous block.


File: ecl.info,  Node: Heap and relocatable areas,  Next: The garbage collector,  Prev: Implementation types,  Up: Memory management

4.2 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   |
     +--------------+-------------------+---------------+


File: ecl.info,  Node: The garbage collector,  Next: Allocation functions,  Prev: Heap and relocatable areas,  Up: Memory management

4.3 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 (), the garbage collector is invoked for level 1 garbage
     collection.  If X is T, it is invoked for level 3 garbage
     collection.  Otherwise, it is invoked for level 2 garbage
     collection.  If `sys:*gc-verbose*' is non-(), then it print
     messages at the start and end of each garbage collection.

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


File: ecl.info,  Node: Allocation functions,  Next: Storage information,  Prev: The garbage collector,  Up: Memory management

4.4 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 (), 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-(), then ECL
automatically increments the maximum number of pages for the class by
50 percent.  The initial value of `(si::ignore-maximum-pages)' is T.


File: ecl.info,  Node: Storage information,  Prev: Allocation functions,  Up: Memory management

4.5 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


File: ecl.info,  Node: Program development,  Next: The interpreter,  Prev: Memory management,  Up: Top

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

* Menu:

* The tracer::
* The stepper::
* Errors::
* The break loop::
* Describe and inspect::
* The profiler::
* Online help::


File: ecl.info,  Node: The tracer,  Next: The stepper,  Prev: Program development,  Up: Program development

5.1 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 {&key 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.



File: ecl.info,  Node: The stepper,  Next: Errors,  Prev: The tracer,  Up: Program development

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


File: ecl.info,  Node: Errors,  Next: The break loop,  Prev: The stepper,  Up: Program development

5.3 Errors
==========

 -- Variable: *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 T, and
     thus an error will invoke the break loop.  If the value is (),
     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 (), no backtrace appears on the
     screen.

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



File: ecl.info,  Node: The break loop,  Next: Describe and inspect,  Prev: Errors,  Up: Program development

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


File: ecl.info,  Node: Describe and inspect,  Next: The profiler,  Prev: The break loop,  Up: Program development

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


File: ecl.info,  Node: The profiler,  Next: Online help,  Prev: Describe and inspect,  Up: Program development

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


File: ecl.info,  Node: Online help,  Prev: The profiler,  Up: Program development

5.7 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 (), then all packages are searched.


File: ecl.info,  Node: The interpreter,  Next: The compiler,  Prev: Program development,  Up: Top

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


File: ecl.info,  Node: The compiler,  Next: Declarations,  Prev: The interpreter,  Up: Top

7 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, *note Bibliography::] (see Section 5.3.3 of
[Steele:84, *note Bibliography::]).

   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 &key :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 (), then the
     output file will be deleted after execution of `compile-file'.  If
     the value of the keyword parameter is T, 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 T, and the default values of :C-FILE, ::H-FILE,
     and :DATA-FILE are all ().

    `(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-() symbol, then compile installs the
     compiled function as the function definition of NAME and returns
     NAME.  If NAME is (), 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 &key :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 (), then the previously compiled form by
     disassemble will be compiled again.  If THING is a symbol other
     than (), 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 () 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.



File: ecl.info,  Node: Declarations,  Next: OS interface,  Prev: The compiler,  Up: Top

8 Declarations
**************

ECL supports all kinds of declarations described in the [Steele:84,
*note Bibliography::].  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, *note Bibliography::], Common-Lisp
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, *note Bibliography::],
     (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.

* Menu:

* Declaration specifiers::
* Type specifiers::
* Type declarations::
* Variable allocations::
* Raw data functions::
* Arguments/Values passing::


File: ecl.info,  Node: Declaration specifiers,  Next: Type specifiers,  Prev: Declarations,  Up: Declarations

8.1 Declaration Specifiers
==========================

ECL recognizes all declaration specifiers defined in [Steele:84, *note
Bibliography::].  The syntax of each such declaration specifier is
exactly the same as defined in [Steele:84, *note Bibliography::].  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, *note
     Bibliography::].

 -- 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, *note Bibliography::], 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 | &key} {thing}*])
       {(values {type}* ) | {type}*}
     )

   Although &optional, &rest, and &key 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 &key 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, *note Bibliography::].

     `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, *note Bibliography::].

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


File: ecl.info,  Node: Type specifiers,  Next: Type declarations,  Prev: Declaration specifiers,  Up: Declarations

8.2 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 T, and `(array t)' itself is a subtype of T.  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 T
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 T.

   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 T because both `(mod 3)'
and `(member 0 1)' are converted to fixnum before the function type of
`foo' is checked.


File: ecl.info,  Node: Type declarations,  Next: Variable allocations,  Prev: Type specifiers,  Up: Declarations

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


File: ecl.info,  Node: Variable allocations,  Next: Raw data functions,  Prev: Type declarations,  Up: Declarations

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


File: ecl.info,  Node: Raw data functions,  Next: Arguments/Values passing,  Prev: Variable allocations,  Up: Declarations

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

Some built-in Common-Lisp 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 Common-Lisp 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)'.


File: ecl.info,  Node: Arguments/Values passing,  Prev: Raw data functions,  Up: Declarations

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


File: ecl.info,  Node: OS interface,  Next: Macros,  Prev: Declarations,  Up: Top

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

ECL provides the following facilities that are not defined in
[Steele:84, *note Bibliography::].

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


File: ecl.info,  Node: Macros,  Next: CLOS,  Prev: OS interface,  Up: Top

10 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, *note
Bibliography::] 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]
        [&key {var
               | ({var | (keyword pseudo-var)} [initform [pseudo-var]])}*
         [&allow-other-keys]]
        [&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]
        [&key {var | ({var | (keyword pseudo-var)}
                       [initform [pseudo-var]])}*
         [&allow-other-keys]]
        [&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, *note Bibliography::] 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 T), then the generated code does not perform argument checking
at all.  Otherwise, the compiled code does check the validity of
arguments.


File: ecl.info,  Node: CLOS,  Next: Multithread,  Prev: Macros,  Up: Top

11 CLOS
*******

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

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

 -- Macro: call-next-method &rest args

 -- Generic: change-class instance new-class
 -- Method: change-class (
 -- Method: change-class (

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

 -- 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
     Common-Lisp 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]
                  [&key {KEYWORD-PARAMETER}* [&allow-other-keys]])
          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]
                  [&key {SPECIALIZED-KEYWORD-PARAMETER}* [&allow-other-keys]])
                  [&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: documentation (
 -- Method: documentation (
 -- Method: doumentation (
 -- Method: documentation (
 -- Method: documentation (
 -- Method: documentation (

 -- 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 &key lambda-list
          &key :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 (
     method-qualifiers specializers  &optional errorp

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

   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 (
     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 (
 -- Method: make-instance (
     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 (
 -- Method: make-instances-obsolete (

 -- 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 (
     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 (
     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: print-object object stream
 -- Method: print-object (
     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 (
     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 (
     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 (
     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 (
     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 (
     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 (

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

 -- Macro: with-accessors (
     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 ::= 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.


File: ecl.info,  Node: Multithread,  Next: Bibliography,  Prev: CLOS,  Up: Top

12 Multithread
**************

[To come once the interface is fixed]


File: ecl.info,  Node: Bibliography,  Prev: Multithread,  Up: Top

13 Bibliography
***************

ANSI
     ANSI Common-Lisp 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 Common-Lisp 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.



Tag Table:
Node: Top439
Node: Introduction1701
Node: Credits3830
Node: Copyright6514
Node: Installation8945
Node: Rebuilding ECL9992
Node: Invoking ECL12549
Node: Standards16046
Node: Numbers16827
Node: Integers17020
Node: Ratios17995
Node: Floating-point numbers18177
Node: Complex numbers20716
Node: Characters20917
Node: Character types21277
Node: Standard characters21525
Node: Line divisions22408
Node: Non-standard characters22754
Node: Character attributes22987
Node: Symbols23337
Node: List and conses23822
Node: Arrays24022
Node: Vectors24837
Node: Strings25589
Node: Bit-Vectors26202
Node: Hash tables26371
Node: Readtables26551
Node: Packages26729
Node: Pathnames27781
Node: Streams32593
Node: Random-states33612
Node: Structures33920
Node: Functions34110
Node: Unreadable data objects35605
Node: Overlap of types35850
Node: ANSI-CL compliance36144
Node: Input and output38049
Node: Read macros38275
Node: Input/Output functions39098
Node: Network streams41360
Node: CLOS streams42143
Node: CLOS Stream Input43174
Node: CLOS Stream Output44092
Node: CLOS Stream common44786
Node: Memory management45153
Node: Implementation types45744
Node: Heap and relocatable areas50224
Node: The garbage collector52575
Node: Allocation functions55692
Node: Storage information58547
Node: Program development60935
Node: The tracer61237
Node: The stepper64462
Node: Errors66225
Node: The break loop67299
Node: Describe and inspect80641
Node: The profiler82716
Node: Online help84048
Node: The interpreter84804
Node: The compiler86655
Node: Declarations93492
Node: Declaration specifiers96038
Node: Type specifiers105158
Node: Type declarations107740
Node: Variable allocations108592
Node: Raw data functions110703
Node: Arguments/Values passing114326
Node: OS interface116457
Node: Macros117301
Node: CLOS120690
Node: Multithread136005
Node: Bibliography136157

End Tag Table
