Dylan is intended to be a general-purpose high-level language as suitable for systems programming as it is for commercial application programming. The target audience is developers who have become disillusioned with the complexities and insecurities of C++.
Dylan differs from C++ in several major ways. It's a pure object-oriented language in which everything is an object, like Smalltalk but unlike C++. It is a dynamic language that retains information about the types of objects at run time rather than compiling it out. Dylan also features automatic memory management and garbage collection. It's incrementally compiled and hence facilitates a rapid development cycle. And it's a modular language, with type-checked module interfaces, to help in building
large, extensible applications.
Dylan uses an object model closer to that of Common Lisp Object System (CLOS) than to that of Smalltalk, so rather than sending messages to objects, Dylan implements polymorphism via generic functions with many alternative implementations called methods. The type of the arguments passed at run time determines which method to execute. Though Dylan is inspired by CLOS, it doesn't use a Lisp-like syntax, is a smaller and simpler language than CLOS, and can run on much smaller computers. Dylan is fully compiled, and it provides that clean distinction between the development environment and the run-time deliverable that's expected of commercial applications.
Dylan programs contain just two basic entities: objects and functions. Objects are bundles of data contained in named
slots
, while functions are code that performs action on objects. Objects are related in a class hierarchy with multiple inheritance.
The listing below shows
a typical Dylan declaration, of a class called
<employee>
. The angle brackets are a Dylan naming convention that indicates a class or type name. The class
<employee>
inherits from class
<object>
, the parent of all objects. The
<employee>
class contains two slots (like data members in C++) called
name
and
salary
, which hold data of type
<string>
and
<number>
, respectively. The Dylan language supports automatic initialization, so the salary slot of an employee will get initialized to 50000 if no other value is supplied during instance creation.
Dylan also supports
keywords
, similar to those in Smalltalk, that label function parameters and make the code much more readable. At the end of the
"Dylan Class Declaration"
listing, I create an instance of
<employee>
, called
Jim
, using the
make()
function. I can initialize these slots by nam
e, using the keywords
name:
and
salary:
in any order, but the
name:
initialization is compulsory (
required-init-keyword
) and will raise a compiler error if omitted. Omitting a slot from the
make
call altogether causes it to take its default value. This mechanism hugely improves the readability and writeability of Dylan code when functions have many arguments.
Dylan is a strongly typed language, but type declarations for variables are optional since the system knows the type of every object. A variable is just a way of attaching a name to an object, and it's the object rather than the variable that possesses a type. Omitting a type definition will force Dylan to perform run-time checks, and so supplying a type (as in slot
name :: <string>
) will usually enable the compiler to generate faster code.
It is impossible to change the data in a Dylan slot by direct assignment; you must use functions to change or read slots. However, Dylan helps
you by creating such access functions automatically; in the case of my
salary
slot, these will by default be called
salary-setter
and
salary-getter
. I could change Jim's salary by
salary-setter(56000, Jim)
or using the familiar dot syntax
Jim.salary := 56000
, or I could use a hybrid:
salary(Jim) := 56000
.
Methods and Polymorphism
Dylan functions are of two kinds: methods and generic functions. A method is the smallest executable unit of code, and a collection of methods with the same name but with differently typed argument lists constitutes a generic function (see generic function
double
in the listing
). The argument list of a method is called its
specializer
, and when a generic function is called, the method whose specializer most nearly matches the type of the actual supplied arguments is the one that gets dispatched for execution. So, in
double(12)
the second method would fire.
If several specializers related by inheritance would all match an argument, then the most specialized subclass is chosen. In fact, Dylan is multiply polymorphic (unlike Smalltalk or C++) since functions can have arbitrarily many required parameters, each of which can be specialized independently.
Unlike Smalltalk or C++, Dylan's methods are not encapsulated in a class definition, and you can call them directly like ordinary functions. This looser association of methods with classes confers an important advantage. In Dylan, you never need to create artificial glue classes just to inherit virtual methods from, as you so often do in C++. This makes for shallower class hierarchies in Dylan programs and so reduces the overhead of method dispatch.
All Dylan functions return a value, which is the value of the last statement executed in their code body; no return statement is needed. The first version of
double
has no specialization at all and simply returns two pointers to its argument, of wh
atever type. The last specialization of
double
illustrates two more features:
singletons
and
symbols
. The
==
operator constrains that argument to be equal to just a single object rather than belonging to a class of objects. In this case, that singleton object is the symbol
nickel:
, an immutable string that behaves like an enumerated type in Pascal.
Modules and Libraries
Dylan provides large-scale program structuring by modules and libraries, which control the visibility of variable names. Since all Dylan classes and functions are stored in variables, modules can effectively import and export them, as in this example:
define module company
use dylan, ;
export <employee>, workgroup;
end module;
Company is a module that imports dylan (the system module containing language primitives) and exports just the class
employee
and the function
workgroup
to any other module that uses it. Libraries are ev
en larger structuring units that contain, import, and export a number of modules. Dylan libraries will also be responsible for maintaining links between source-code and executable-code modules, in an implementation-dependent way that is intimately linked to a particular development environment.
Modules are enormously helpful in the building of large programs. They prevent name clashes (since each module constitutes a separate namespace); but in object-oriented programming, they have a special, even more important role to play as the unit of application extension. Thanks to late binding (e.g., virtual methods in C++), you should be able to extend an object-oriented application by adding new compiled code without needing to recompile the application itself or even needing its source code. To make this work effectively requires a compilation unit that's larger than a single class, and that supports well- defined and type-checked interfaces. Surprisingly, many OOP languages lack such a facility, but Dylan'
s libraries fit the bill.
Once Upon a Time You Dressed So Fine . . .
Dylan collects together many of the best ideas in modern programming-language design, combining highly expressive primitives with a clean attractive syntax. However, several question marks hang over its future. Dylan's very late, having taken almost a decade to realize. In that time, C++ has achieved an almost unshakeable grip on the programming world. Performance remains in question, too, and since the experimental Dylans have all been interpreters, they offer little guidance as to how fast a commercial compiler would be.
A team at Carnegie Mellon University continues work on a Unix Dylan. The software firm Harlequin is close to releasing commercial Windows and Unix implementations, including a prototype producer for the Architecture Neutral Distribution Format system, which produces portable binaries.
Apple recently closed the lab where all Dylan work took place and disbanded the team. The company
issued E-mail to developers indicating that the prototype "technology release" of Dylan will be distributed but will be the last to be funded or supported by Apple. The latest verdict from Apple says: "The investment required to deliver a Dylan product that satisfies the customer needs in a timely manner and create the infrastructure to ensure Dylan's success in the market at this time is prohibitive."
WHERE TO FIND
Dylan home page:
http://www.cambridge.apple.com/dylan/dylan.html