Chapter 1


Language Overview

Dylan is written in a very regular syntax. In addition to making the language easier to read and write, the layered composition of the syntax supports a macro system that is language-aware. The macro system does not simply perform text substitution, but rather performs syntax fragment substitution. This allows the extension of the language within bounds that are safe, semantically well-defined, and in accord with the syntactic flavor of the language.

Bindings (Dylan's analog to variables) are lexically scoped and fully resolved at compile time. Binding names are not retained in running programs. The module system allows bindings to be private or shared. Names can be changed upon import to a module, so the possibility of irreconcilable name conflicts among separately developed modules is eliminated. Modules can provide multiple interfaces to the same code base, decreasing the chance of exposing a client to inappropriate interfaces.

Flow of control is supported through polymorphic function calls, a variety of conditional and iteration constructs, and a nonlocal transfer mechanism with protected regions.

All objects are first class, including numbers, classes and functions. This means that all objects can be used as arguments to functions, returned as values, and stored in data structures, and all are subject to introspection. All objects are typed, and type-safety is guaranteed, either through compile-time or runtime type checking. There are no facilities for deallocating objects. Objects are deallocated automatically when they can no longer be reached by a program.

Types are used to categorize and specify the behavior of objects. An object may be an instance of any number of types. Classes are a particular kind of type used to define the structure and inheritance of instances. Every Dylan object is a direct instance of exactly one class, and a general instance of that class and each of its superclasses. The root of the class hierarchy (and of the type hierarchy) is a class called <object>.

Values associated with an instance are stored in slots of the instance.

Classes do not define scopes for names. Names are scoped by modules and local binding declarations.

Functions are the active portions of Dylan programs. Functions accept zero or more arguments and return zero or more values. Functions are specialized to accept arguments of particular types, and will signal an error if they are called with arguments that are not instances of those types. The return values of functions are similarly type-checked.

A method is a basic unit of callable code. When a method is called, it creates local bindings for its arguments and executes a body in the resulting environment. A method can be called directly by a program or indirectly through a generic function that contains it.

A generic function contains a number of methods. When a generic function is called, it finds the methods that are applicable to the arguments, and passes control to the most specific of those methods.

Slots are accessed through functions. This ensures that instances present an abstract interface to their clients, which assists both in polymorphism and in program redesign.

Sealing declarations allow the programmer to declare portions of the class hierarchy and set of functions to be invariant. This supports the enforcement of protocols, compile-time resolution of polymorphic behavior, and efficient inline slot access. Portions of a program that are not sealed can be extended at run time or by additional libraries.

Dylan includes a number of predefined libraries, including an exception system, collections, arithmetic, higher-order functions, and introspection.

The exception system is object-based. It uses calling semantics (thereby allowing recovery) but also provides exiting handlers.

The collection system includes a number of predefined collection classes and operations built on a simple iteration protocol. Additional classes defined in terms of this protocol have access to the full suite of collection operations.

Arithmetic is fully object-based and extensible.

A library of higher-order operations on functions supports function composition.

A library of introspective functions supports the run time examination of objects, including classes and functions.