Introduction
EuLisp is a dialect of Lisp and as such owes much to the great body of work
that has been done on language design in the name of Lisp over the last thirty
years. The distinguishing features of EuLisp are (i) the integration of the
classical Lisp type system and the object system into a single class hierarchy
(ii) the complementary abstraction facilities provided by the class and the
module mechanism (iii) support for concurrent execution.
Here is a brief summary of the main features of the language.
- Classes are first-class objects. The class structure integrates the
primitive classes describing fundamental datatypes, the predefined
classes and user-defined classes.
- Modules together with classes are the building blocks of both the EuLisp
language and of applications written in EuLisp. The module system
exists to limit access to objects by name. That is, modules allow for
hidden definitions. Each module defines a fresh, empty, lexical
environment.
- Multiple control threads can be created in EuLisp and the concurrency
model has been designed to allow consistency across a wide range of
architectures. Access to shared data can be controlled via locks
(semaphores). Event-based programming is supported through a generic
waiting function.
- Both functions and continuations are first-class in EuLisp, but the latter
are not as general as in Scheme because they can only be used in the
dynamic extent of their creation. That implies they can only be used
once.
- A condition mechanism which is fully integrated with both classes and
threads, allows for the definition of generic handlers and supports both
propagation of conditions and continuable handling.
- Dynamically scoped bindings can be created in EuLisp, but their use is
restricted, as in Scheme. EuLisp enforces a strong distinction between
lexical bindings and dynamic bindings by requiring the manipulation of
the latter via special forms.
EuLisp does not claim any particular Lisp dialect as its closest relative,
although parts of it were influenced by features found in Common Lisp,
InterLisp, LeLisp, Lisp/VM, Scheme, and T. EuLisp both introduces new
ideas and takes from these Lisps. It also extends or simplifies their ideas as
seen fit. But this is not the place for a detailed language comparison. That
can be drawn from the rest of this text.
EuLisp breaks with Lisp tradition in describing all its types (in fact, classes) in
terms of an object system. This is called The EuLisp Object System, or Telos.
Telos incorporates elements of the Common Lisp Object System (CLOS) [?],
ObjVLisp [?], Oaklisp [?], MicroCeyx [?], and MCS [?].
Language Structure
The EuLisp definition comprises the following items:
- Level-0
- comprises all the level-0 classes,
functions, macros and special forms, which is this text minus Annex ?? .
The object system can be extended by user-defined structure classes, and
generic functions.
- Level-1
- extends level-0 with the classes,
functions, macros and special forms defined in Annex ?? . The object
system can be extended by user-defined classes and metaclasses. The
implementation of level-1 is not necessarily written or writable as a
conforming level-0 program.
A level-0 function is a (generic) function defined in this text to be
part of a conforming processor for level-0. A function defined in terms of
level-0 operations is an example of a level-0 application.
Much of the functionality of EuLisp is defined in terms of modules. These
modules might be available (and used) at any level, but certain modules are
required at a given level. Whenever a module depends on the operations
available at a given level, that dependency will be specified.
EuLisp level-0 is provided by the module eulisp0
. This
module imports and re-exports the modules specified in Table ?? .
Modules comprising eulisp0
_________________________________________________________________
|__Module________________________________________Section(s)__|___
| character
?? |
| collection
?? |
| compare
?? |
| condition
?? |
| convert
?? |
| copy
?? |
| double
?? |
| mathlib
?? |
| fpi
?? |
| formatted-io
?? |
| function
?? |
| list
?? |
| lock
?? |
| number
?? |
| telos0
?? |
| stream
?? |
| string
?? |
| symbol
?? |
| table
?? |
| thread
?? |
|__vector
___________________________??______________|
This definition is organized in three parts:
- Sections ?? {??
- describes the core of
level-0 of EuLisp, covering modules, simple classes, objects and generic
functions, threads, conditions, control forms and events. These sections
contain the information about EuLisp that characterizes the language.
- Annex A
- describes the additional classes
required at level-0 and the operations defined on instances of those
classes. The annex is organized by module in alphabetical order. These
sections contain information about the predefined classes in EuLisp that
are necessary to make the language usable, but is not central to an
appreciation of the language.
- Annex B
- describes the reflective aspects
of the object system and how to program the metaobject protocol and
some additional control forms.
Prior to these, sections ?? {?? define the scope of the text, cite
normative references, conformance definitions, error definitions, typographical
and layout conventions and terminology definitions used in this text.
Scope
This text specifies the syntax and semantics of the computer programming
language EuLisp by defining the requirements for a conforming EuLisp
processor and a conforming EuLisp program (the textual representation of
data and algorithms).
This text does not specify:
- The size or complexity of a EuLisp program that will exceed the
capacity of any specific configuration or processor, nor the actions to be
taken when those limits are exceeded.
- The minimal requirements of a configuration that is capable of
supporting an implementation of a EuLisp processor.
- The method of preparation of a EuLisp program for execution or the
method of activation of this EuLisp program once prepared.
- The method of reporting errors, warnings or exceptions to the client of a
EuLisp processor.
- The typographical representation of a EuLisp program for human
reading.
- The means to map module names to the filing system or other object
storage system attached to the processor.
To clarify certain instances of the use of English in this text the
following definitions are provided:
- must
- a verbal form used to introduce a
required property. All conforming processors must satisfy the
property.
- should
- A verbal form used to introduce a
strongly recommended property. Implementors of processors
are urged (but not required) to satisfy the property.
Normative References
The following standards contain provisions, which through references in this
text constitute provisions of this definition. At the time of writing, the
editions indicated were valid. All standards are subject to revision and parties
making use of this definition are encouraged to apply the most recent edition
of the standard listed below.
- ISO 646
- Information processing; ISO 7-bit coded character set for
information interchange, 1983. Note: this standard is currently under revision
and the interested reader should see the 1990 Draft International Standard
version of ISO/IEC 646.
- ISO 2382
- Data processing; vocabulary.
- ISO TR 10034 : 1990
- Information technology; Guidelines for the
preparation of conformity clauses in programming language standards.
- ISO TR 10176 : 1991
- Information technology; Guidelines for the
preparation of programming language standards. Note: this is currently a draft
technical report.
- BS 6154
- Method of defining; Syntactic metalanguage, 1981.
- ISO/IEC 9899 : 1990
- Programming Languages; C.
- ISO/IEC 9945-1 : 1990
- Information technology; Portable Operating
System Interface (POSIX) Part 1: System Application Program Interface
(API) [C language].
Conformance Definitions
The following terms are general in that they could be applied to the definition
of any programming language. They are derived from ISO/IEC TR 10034:
1990.
configuration: Host and target computers, any operating systems(s)
and software (run-time system) used to operate a language
processor.
conformity clause: Statement that is not part of the language
definition but that specifies requirements for compliance with the language
standard.
conforming program: Program which is written in the language
defined by the language standard and which obeys all the
conformity clauses for programs in the language
standard.
conforming processor: Processor which processes
conforming programs and program units and which
obeys all the conformity clauses for
processors in the language standard.
error: Incorrect program construct or incorrect functioning of a
program as defined by the language standard.
extension: Facility in the processor that is not specified
in the language standard but that does not cause any ambiguity or
contradiction when added to the language standard.
implementation-defined: Specific to the processor, but
required by the language standard to be defined and documented by the
implementer.
processor: Compiler, translator or interpreter working in
combination with a configuration.
Error Definitions
Errors in the language described in this definition fall into one of the following
three classes:
dynamic error: An error which is detected during the execution of a
EuLisp program or which is a violation of the defined dynamic behaviour of
EuLisp. Dynamic errors have two classifications:
- Where a conforming processor is required to
detect the erroneous situation or behaviour and report it. This is
signified by the phrase an error is signalled. The condition
class to be signalled is specified. Signalling an error consists of
identifying the condition class related to the error and allocating an
instance of it. This instance is initialized with information dependent on
the condition class. A conforming EuLisp program can rely on the fact
that this condition will be signalled.
- Where a conforming processor might or might
not detect and report upon the error. This is signified by the phrase ...is
an error. A processor should provide a mode where such errors are
detected and reported where possible.
environmental error: An error which is detected by the
configuration supporting the EuLisp processor. The processor must signal the
corresponding dynamic error which is identified and handled as described
above.
static error: An error which is detected during the preparation of a
EuLisp program for execution, such as a violation of the syntax or static
semantics of EuLisp by the program under preparation.
The violation of the syntactic or static semantic requirements is
not an error, but an error might be signalled by the program performing the
analysis of the EuLisp program.
All errors specified in this definition are dynamic unless explicitly stated
otherwise.
Compliance
An EuLisp processor can conform at either of the two levels defined under
Language Structure in the Introduction. Thus a level-0 conforming processor
must support all the basic expressions, classes and class operations defined at
level-0. A level-1 conforming processor must support all the basic expressions,
classes, class operations and modules defined at level-1 and at level-0.
The following two statements govern the conformance of a processor at a given
level.
- A conforming processor must correctly process all programs
conforming both to the standard at the specified level and the
implementation-defined features of the processor.
- A conforming processor should offer a facility to report the
use of an extension which is statically determinable solely
from inspection of a program, without execution. (It is also considered
desirable that a facility to report the use of an extension which is only
determinable dynamically be offered.)
A level-0 conforming program is one which observes the syntax and
semantics defined for level-0. A level-0 conforming program might not conform
at level-1. A strictly-conforming level-0 program is one that also conforms at
level-1. A level-1 conforming program observes the syntax and semantics
defined for level-1.
In addition, a conforming program at any level must not use any
extensions implemented by a language processor, but
it can rely on implementation-defined features.
The documentation of a conforming processor must include:
- A list of all the implementation-defined definitions or values.
- A list of all the features of the language standard which are dependent
on the processor and not implemented by this processor due
to non-support of a particular facility, where such non-support is
permitted by the standard.
- A list of all the features of the language implemented by this processor
which are extensions to the standard language.
- A statement of conformity, giving the complete reference of the language
standard with which conformity is claimed, and, if appropriate, the level
of the language supported by this processor.
Conventions
This section defines the conventions employed in this text, how definitions will
be laid out, the typeface to be used, the meta-language used in descriptions
and the naming conventions. A later section (?? ) contains definitions of the
terms used in this text.
A standard function denotes an immutable top-lexical binding of the defined
name. All the definitions in this text are bindings in some module except for
the special form operators, which have no definition anywhere. All bindings
and all the special form operators can be renamed.
A description making mention of an x where x is
the name of a class usually means an instance of <x>.
Frequently, a class-descriptive name will be used in the argument list of a
function description to indicate a restriction on the domain to which that
argument belongs. In the case of a function, it is an error to call it with a
value outside the specified domain. A generic function can be defined with a
particular domain and/or range. In this case, any new methods must respect
the domain and/or range of the generic function to which they are to be
attached. The use of a class-descriptive name in the context of a generic
function definition defines the intention of the definition, and is not necessarily
a policed restriction.
The result-class of an operation, except in one case, refers to a
primitive or a defined class described in this definition. The exception is for
predicates. Predicates are defined to return either the empty list|written
()
|representing the boolean value false, or any value other
than ()
, representing true. Although the class containing
exactly this set of values is not defined in the language, notation is abused for
convenience and boolean is defined, for the purposes of this report,
to mean that set of values. If the true value is a useful value, it is specified
precisely in the description of the function.
Layout and Typography
Both layout and fonts are used to help in the description of EuLisp. A
language element is defined as an entry with its name as the heading of a
clause, coupled with its classification. Examples of several kinds of entry are
now given. Some subsections of entries are optional and are only given where
it is felt necessary.
a-special-form
:
special form
Syntax
a special form
= '(', a-special-form, {form}, ')';
Arguments
- form-1
- description of structure and r^ole of
form-1.
...
- form-n
- description of structure and r^ole of
form-n.
Result
A description of the result.
Remarks
Any additional information defining the behaviour of
a-special-form
.
Examples
Some examples of use of the special form and the
behaviour that should result.
See also:
Cross references to related entries.
a-function
:
function
Arguments
- argument-a
- information about the class or classes of
argument-a.
...
- [argument-n]
- information about the class or classes of
the optional argument argument-n.
Result
A description of the result and, possibly, its class.
Remarks
Any additional information about the actions of
a-function
.
Examples
Some examples of calling the function with certain
arguments and the result that should be returned.
See also:
Cross references to related entries.
a-generic
:
generic-function
Generic arguments
- (argument-a <class-a>)
-
means that argument-a of
a-generic
must
be an instance of <class-a> and that
argument-a is one of the arguments on which
a-generic
specializes. Furthermore, each method
defined on a-generic
may specialize only on a subclass
of <class-a> for argument-a.
...
- argument-n
- means that (i) argument-n is
an instance of <object>, i.e. it is
unconstrained, (ii)
a-generic
does not specialize on
argument-n, (iii) no method on a-generic
can specialize on argument-n.
Result
A description of the result and, possibly, its class.
Remarks
Any additional information about the actions of
a-generic
. This can take two forms depending on the
function. This will probably be in general terms, since the actual behaviour
will be determined by the methods.
See also:
Cross references to related entries.
a-generic
:
method
(A method on a-generic
with the following specialized
arguments.)
Specialized arguments
- (argument-a <class-a>)
-
means that argument-a of the method must be an instance of
<class-a>. Of course, this argument must be one which
was defined in
a-generic
as being open to specialization
and <class-a> must be a subclass of the class.
...
- argument-n
- means that (i) argument-n is
an instance of <object>, i.e. it is
unconstrained, because
a-generic
does not specialize on
argument-n.
Result
A description of the result and, possibly, its class.
Remarks
Any additional information about the actions of this
method attached to a-generic
.
See also:
Cross references to related entries.
<a-
condition>
:
<a-condition-superclass>
Initialization options
- initarg-a : value-a
- means that an instance
of <a-condition> has a slot called
initarg-a
which should be initialized to
value-a, where value-a is often the name of a
class, indicating that value-a should be an instance of that
class and a description of the information that value-a is supposed to
provide about the exceptional situation that has arisen.
...
- initarg-n : value-n
- As for
initarg-a
.
Remarks
Any additional information about the circumstances in
which the condition will be signalled.
<class-
name>
:
class
Initialization options
- initarg-a : value-a
- means that
<class-name> has an initarg whose name is
initarg-a
and the description will usually say of what
class (or classes) value-a should be an instance. This initarg
is required.
...
[
initarg-n : value-n]
-
The enclosing square brackets denote that this initarg is optional.
Otherwise the interpretation of the definition is as for
initarg-a
.
Remarks
A description of the r^ole of <class-name>.
Naming
Naming conventions are applied in the descriptions of primitive and defined
classes as well as in the choice of other function names. Here is a list of the
conventions and some examples of their use.
<name> wrapping: By convention, classes have
names which begin with <
and end with
>
.
binary
prefix: The two argument version of a
n-ary argument function. For example binary+
is the two
argument (generic) function corresponding to the n-ary argument
+
function.
-class
suffix: The name of a metaclass of a set of
related classes. For example, <function-class>, which is the
class of <simple-function>,
<generic-function> and any of their subclasses and
<condition-class> is the class of all condition classes. The
exception is <class> itself which is the default metaclass. The
prefix should describe the general domain of the classes in question, but not
necessarily any particular class in the set.
generic-
prefix: The generic version of the
function named by the stem.
hyphenation: Function and class names made up of more than one
word are hyphenated, for example:
compute-specialized-slot-description-class
.
p
suffix: A predicate function is named by a
p
suffix if the function or class name (after removing the
enclosing <
and >
) is not
hyphenated, for instance, consp
, and is named by a
-p
suffix if it is, for instance double-float-p
.