The language Dylan was defined by a group at Apple Computer's Cambridge Research Laboratories. A book describing an early version of the Dylan language (Andrew Shalit, Dylan: an object oriented dynamic language, Apple Computer, Inc. 1992) put forth the reasons Apple embarked upon development of a new Object-Oriented Dynamic Language.
According to Larry Tesler [Dylan, 1992], Dylan was intended to meet the following requirements:
A Dylan program consists of one or more libraries, which are the units of compilation and optimization in a Dylan program. Libraries contain modules, which are Dylan's unit of global name scoping. A binding is an association of a name to a value within a module. Both variable and constant bindings can be defined.
A Dylan class describes the structure of the objects that belong to the class by enumerating the slots (conceptual instance variables) that comprise the objects and by specifying their getters and setters. Consider the playing card class.
define constant :: = one-of (#"hearts", #"clubs", #"diamonds", #"spades"); define constant :: = one-of (#"red", #"black"); define class (
The program fragment presented here contains three constituents:
<suit>
.
<rank>
.
<card>
.
Dylan distinguishes between the notion of a class and a type. A class describes a set of objects with common structure created by class definitions. Type is a more general notion encompassing classes, unions of classes, sets of values, and other constructs.
By convention, type names in Dylan are written within angle
brackets (like <suit>
).
The syntactic construct #"
name"
is used to introduce a unique symbolic name, and the function
one-of
creates a type containing exactly the values
presented as arguments to it. Thus <suit>
is a type
containing just the values #"hearts", #"clubs", #"diamonds",
and
#"spades"
and no others.
The class definition of <card>
specifies that an object
belonging to that class has unique superclass <object>
,
and constains three slots, namely:
suit
, which is specialized to class
<suit>
.
rank
, which is specialized to class
<integer>
.
color
, which is virtual and is specialized
to class <color>
.
suit
and rank
slots identify the data
members belonging to every instance object of the class
<card>
. They can be accessed through the use of
getter and setter methods. The slot
color
is virtual, thus there is no actual data member to
hold this value in instances of <card>
. However, by
identifying the virtual slot, the programmer is documenting the fact
that color
getter or setter methods will be provided by
the program, thus giving the appearance that there is a real
color
slot.
The definition of the color
getter method uses the
suit
getter method to satisfy its requirements.
define method color (c :: ) => ; if (c.suit == #"diamonds" | c.suit == #"hearts") #"red" else #"black" end if; end method color;
Note the way in which the color method is defined and note the
syntax for accessing the suit
slot. The syntax
object.name is the conventional way in which a
getter is invoked. It is functionally identical to a call
of the the form name(object). Thus to define
the color
getter method, we describe how to implement
the generic function color
when it is applied
to an object belonging to class
The fundamental difference between the Dylan view of object behavior and that espoused by Smalltalk hinges on how one elicits behavior. In the Smalltalk view, classes contain an enumeration of the data members each instance will contain and also contain the methods used by the class to implement messages it will receive. The Dylan view, removes the methods from the classes, and groups them together in what are termed generic functions. A generic function is associated with the methods which implement it, rather than associating methods with the objects.
Dylan's view, though characterized by some as non-OO, supports a valid and reasonable view of how to achieve computation in an OO framework. In particular, Dylan's view solves problems associated with more traditional message-passing implementations. (See the double-dispatch work-around cited by Budd in Chapter 8 as an example of something that can be avoided easily in Dylan.) Dylan's view also supports multiple-inheritance in a straighforward and principled way.