Dylan programming language
Encyclopedia
Dylan is a multi-paradigm programming language
that includes support for functional
and object-oriented
programming, and is dynamic
and reflective
while providing a programming model designed to support efficient machine code generation, including fine-grained control over dynamic and static behaviors. It was created in the early 1990s by a group led by Apple Computer
.
Dylan derives from Scheme and Common Lisp
and adds an integrated object system derived from the Common Lisp Object System (CLOS). In Dylan, all values (including numbers, characters, functions, and classes) are first-class objects
. Dylan supports multiple inheritance, polymorphism, multiple dispatch, keyword arguments, object introspection, pattern-based syntax extension macros, and many other advanced features. Programs can express fine-grained control over dynamism, admitting programs that occupy a continuum between dynamic and static programming and supporting evolutionary development (allowing for rapid prototyping followed by incremental refinement and optimization).
Dylan's main design goal is to be a dynamic language well-suited for developing commercial software. Dylan attempts to address potential performance issues by introducing "natural" limits to the full flexibility of Lisp systems, allowing the compiler to clearly understand compilable units (i.e., libraries).
Although deriving much of its semantics from Scheme and other Lisps—some implementations were in fact initially built within existing Lisp systems—Dylan has an ALGOL
-like syntax rather than a Scheme-like prefix syntax.
. At one point in its development it was intended for use with Apple's Newton
computer, but the Dylan implementation did not reach sufficient maturity in time, and Newton instead used a combination of C and the NewtonScript developed by Walter Smith. Apple ended their Dylan development effort in 1995, though they made a "technology release" version available ("Apple Dylan TR1") that included an advanced IDE
.
Two other groups contributed to the design of the language and developed implementations: Harlequin
released a commercial IDE for Microsoft Windows
and Carnegie Mellon University
released an open source
compiler for Unix
systems. Both of these implementations are now open source and maintained by a group of volunteers, the Gwydion Maintainers.
The Dylan language was code-named Ralph. James Joaquin chose the name Dylan for "DYnamic LANguage."
By the time the language design was completed, it was changed to an Algol-like syntax, designed by Michael Kahl, with the expectation that it would be more familiar to a wider audience of programmers:
Similar to other functional programming languages, the result of a function is the value of the last expression evaluated—there is no explicit “return” statement. The following function returns the value of the “if” statement (statements, too, produce results), which evaluates to the value of either “1” or “n * factorial(n - 1)”:
Some languages also include a separate, explicit namespace or module system that performs encapsulation in a more general way. Dylan is such a language.
In Dylan, the concepts of compile-unit and import-unit are separated, and classes have nothing specifically to do with either. A library defines items that should be compiled and handled together, while a module defines the namespace. Classes can be placed together in modules, or cut across them, as the programmer wishes. Often the complete definition for a class does not exist in a single module, but is spread across several that are optionally collected together. Different programs can have different definitions of the same class, including only what they need.
For example, consider an add-on library for regex support on String. In some languages, in order for the functionality to be included in strings, the functionality has to be added to the String namespace itself. As soon as you do this, the String class becomes larger, and people who don't need to use regex still have to "pay" for it in increased library size. For this reason these sorts of add-ons are typically placed in their own namespaces and objects. The downside to this approach is that the new functionality is no longer a part of string; instead, it is isolated in its own set of functions that have to be called separately. Instead of
In addition, under Dylan many interfaces can be defined for the same code, for instance the String concatenation method could be placed in both the String interface, and the "concat" interface which collects together all of the different concatenation functions from various classes. This is more commonly used in math libraries, where functions tend to be applicable to widely differing object types.
A more practical use of the interface construct is to build public and private versions of a module, something that other languages include as a "bolt on" feature that invariably causes problems and adds syntax. Under Dylan the programmer can simply place every function call in the "Private" or "Development" interface, and collect up publicly accessible functions in "Public". Under Java
or C++
the visibility of an object is defined in the code itself, meaning that to support a similar change the programmer would be forced to re-write the definitions completely, and could not have two versions at the same time.
. Default getter and setter methods are automatically generated based on the slot names. In contrast with most other OO languages, other methods applicable to the class are often defined outside of the class, and thus class definitions in Dylan typically include the definition of the storage only. For instance:
In this example the class "
In languages such as C++ or Java, the class would also define its interface. In this case the definition above has no explicit instructions, so in both languages access to the slots and methods is considered
In Dylan these sorts of visibility rules are not considered part of the code itself, but of the module/interface system. This adds considerable flexibility. For instance, one interface used during early development could declare everything public, whereas one used in testing and deployment could limit this. With C++ or Java these changes would require changes to the source code itself, so people won't do it, whereas in Dylan this is a completely unrelated concept.
Although this example does not use it, Dylan also supports multiple inheritance
.
Under Java the same methods would be isolated in a particular class. In order to use that functionality the programmer is forced to import that class and refer to it explicitly in order to call the method. If that class is not available, or unknown at compile time, the application simply won't compile.
In Dylan, code is isolated from storage in functions. Many classes have methods that call their own functions, thereby looking and feeling like most other OO languages. However code may also be located in generic functions, meaning they are not attached to a particular class, and can be called natively by anyone. Linking a particular generic function to a method in a class is accomplished this way:
This definition is similar to those in other languages, and would likely be encapsulated within the
for
The utility of generic methods comes into its own when you consider more "generic" examples. For instance, one common function in most languages is the
form for the object. For instance, a window might return its title and its position in parens, while a string would return itself. In Dylan these methods could all be collected into a single module called "
The implication here is that a programmer can add functionality to existing classes by defining functions in a separate file. For instance, you might wish to add spell checking to all
This still might not sound all that obvious, but in fact it is a common problem faced by almost all OO languages; not everything fits into a class construct, many problems apply to all objects in the system and there's no natural way to handle this.
. It was originally developed for the Apple Newton
product.
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....
that includes support for functional
Functional programming
In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state...
and object-oriented
Object-oriented programming
Object-oriented programming is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction,...
programming, and is dynamic
Dynamic programming language
Dynamic programming language is a term used broadly in computer science to describe a class of high-level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all...
and reflective
Reflection (computer science)
In computer science, reflection is the process by which a computer program can observe and modify its own structure and behavior at runtime....
while providing a programming model designed to support efficient machine code generation, including fine-grained control over dynamic and static behaviors. It was created in the early 1990s by a group led by Apple Computer
Apple Computer
Apple Inc. is an American multinational corporation that designs and markets consumer electronics, computer software, and personal computers. The company's best-known hardware products include the Macintosh line of computers, the iPod, the iPhone and the iPad...
.
Dylan derives from Scheme and Common Lisp
Common Lisp
Common Lisp, commonly abbreviated CL, is a dialect of the Lisp programming language, published in ANSI standard document ANSI INCITS 226-1994 , . From the ANSI Common Lisp standard the Common Lisp HyperSpec has been derived for use with web browsers...
and adds an integrated object system derived from the Common Lisp Object System (CLOS). In Dylan, all values (including numbers, characters, functions, and classes) are first-class objects
First-class object
In programming language design, a first-class citizen , in the context of a particular programming language, is an entity that can be constructed at run-time, passed as a parameter, returned from a subroutine, or assigned into a variable...
. Dylan supports multiple inheritance, polymorphism, multiple dispatch, keyword arguments, object introspection, pattern-based syntax extension macros, and many other advanced features. Programs can express fine-grained control over dynamism, admitting programs that occupy a continuum between dynamic and static programming and supporting evolutionary development (allowing for rapid prototyping followed by incremental refinement and optimization).
Dylan's main design goal is to be a dynamic language well-suited for developing commercial software. Dylan attempts to address potential performance issues by introducing "natural" limits to the full flexibility of Lisp systems, allowing the compiler to clearly understand compilable units (i.e., libraries).
Although deriving much of its semantics from Scheme and other Lisps—some implementations were in fact initially built within existing Lisp systems—Dylan has an ALGOL
ALGOL
ALGOL is a family of imperative computer programming languages originally developed in the mid 1950s which greatly influenced many other languages and became the de facto way algorithms were described in textbooks and academic works for almost the next 30 years...
-like syntax rather than a Scheme-like prefix syntax.
History
Dylan was created in the early 1990s by a group led by Apple ComputerApple Computer
Apple Inc. is an American multinational corporation that designs and markets consumer electronics, computer software, and personal computers. The company's best-known hardware products include the Macintosh line of computers, the iPod, the iPhone and the iPad...
. At one point in its development it was intended for use with Apple's Newton
Apple Newton
The MessagePad was the first series of personal digital assistant devices developed by Apple for the Newton platform in 1993. Some electronic engineering and the manufacture of Apple's MessagePad devices was done in Japan by the Sharp Corporation...
computer, but the Dylan implementation did not reach sufficient maturity in time, and Newton instead used a combination of C and the NewtonScript developed by Walter Smith. Apple ended their Dylan development effort in 1995, though they made a "technology release" version available ("Apple Dylan TR1") that included an advanced IDE
Integrated development environment
An integrated development environment is a software application that provides comprehensive facilities to computer programmers for software development...
.
Two other groups contributed to the design of the language and developed implementations: Harlequin
Harlequin (software company)
Harlequin was formerly a technology company based in Cambridge, UK and Cambridge, Massachusetts. They specialized in printing applications, graphical applications, law enforcement applications, and programming language implementations...
released a commercial IDE for Microsoft Windows
Microsoft Windows
Microsoft Windows is a series of operating systems produced by Microsoft.Microsoft introduced an operating environment named Windows on November 20, 1985 as an add-on to MS-DOS in response to the growing interest in graphical user interfaces . Microsoft Windows came to dominate the world's personal...
and Carnegie Mellon University
Carnegie Mellon University
Carnegie Mellon University is a private research university in Pittsburgh, Pennsylvania, United States....
released an open source
Open source
The term open source describes practices in production and development that promote access to the end product's source materials. Some consider open source a philosophy, others consider it a pragmatic methodology...
compiler for Unix
Unix
Unix is a multitasking, multi-user computer operating system originally developed in 1969 by a group of AT&T employees at Bell Labs, including Ken Thompson, Dennis Ritchie, Brian Kernighan, Douglas McIlroy, and Joe Ossanna...
systems. Both of these implementations are now open source and maintained by a group of volunteers, the Gwydion Maintainers.
The Dylan language was code-named Ralph. James Joaquin chose the name Dylan for "DYnamic LANguage."
Syntax
Initially, Dylan used a Scheme-like prefix syntax, which is based on s-expressions:
(bind ((radius 5)
(circumference (* 2 $pi radius)))
(if (> circumference 42)
(format-out "Hello big circle! c is %=" circumference)
(format-out "Hello circle! c is %=" circumference)))
By the time the language design was completed, it was changed to an Algol-like syntax, designed by Michael Kahl, with the expectation that it would be more familiar to a wider audience of programmers:
let radius = 5;
let circumference = 2 * $pi * radius;
if (circumference > 42)
format-out("Hello, big circle! c is %=", circumference);
else
format-out("Hello, circle! c is %=", circumference);
end if
Similar to other functional programming languages, the result of a function is the value of the last expression evaluated—there is no explicit “return” statement. The following function returns the value of the “if” statement (statements, too, produce results), which evaluates to the value of either “1” or “n * factorial(n - 1)”:
define method factorial(n :: )
if (n = 0)
1
else
n * factorial(n - 1)
end
end method;
Modules vs. namespace
In many object-oriented languages, classes are the primary means of encapsulation and modularization; each class defines a namespace and controls how and which definitions are externally visible. In addition, classes in many languages define an indivisible unit that must be used as a whole—if you want to use a String concatenation function, you must import and compile against all of String.Some languages also include a separate, explicit namespace or module system that performs encapsulation in a more general way. Dylan is such a language.
In Dylan, the concepts of compile-unit and import-unit are separated, and classes have nothing specifically to do with either. A library defines items that should be compiled and handled together, while a module defines the namespace. Classes can be placed together in modules, or cut across them, as the programmer wishes. Often the complete definition for a class does not exist in a single module, but is spread across several that are optionally collected together. Different programs can have different definitions of the same class, including only what they need.
For example, consider an add-on library for regex support on String. In some languages, in order for the functionality to be included in strings, the functionality has to be added to the String namespace itself. As soon as you do this, the String class becomes larger, and people who don't need to use regex still have to "pay" for it in increased library size. For this reason these sorts of add-ons are typically placed in their own namespaces and objects. The downside to this approach is that the new functionality is no longer a part of string; instead, it is isolated in its own set of functions that have to be called separately. Instead of
myString.parseWith(myPattern)
, which would be the natural organization from an OO point of view, you use something like myPattern.parseString(myString)
, which effectively reverses the ordering.In addition, under Dylan many interfaces can be defined for the same code, for instance the String concatenation method could be placed in both the String interface, and the "concat" interface which collects together all of the different concatenation functions from various classes. This is more commonly used in math libraries, where functions tend to be applicable to widely differing object types.
A more practical use of the interface construct is to build public and private versions of a module, something that other languages include as a "bolt on" feature that invariably causes problems and adds syntax. Under Dylan the programmer can simply place every function call in the "Private" or "Development" interface, and collect up publicly accessible functions in "Public". Under Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
or C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
the visibility of an object is defined in the code itself, meaning that to support a similar change the programmer would be forced to re-write the definitions completely, and could not have two versions at the same time.
Classes
Classes in Dylan describe "slots" (data members, fields, ivars, etc.) of objects in a fashion similar to most OO languages. All access to slots are via methods, as in CLOS and SmalltalkSmalltalk
Smalltalk is an object-oriented, dynamically typed, reflective programming language. Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis." It was designed and created in part for educational use, more so for constructionist...
. Default getter and setter methods are automatically generated based on the slot names. In contrast with most other OO languages, other methods applicable to the class are often defined outside of the class, and thus class definitions in Dylan typically include the definition of the storage only. For instance:
define class ()
slot title :: = "untitled", init-keyword: title:;
slot position :: , required-init-keyword: position:;
end class;
In this example the class "
<window>
" is defined. The <class name> syntax is convention only, to make the class names stand out—the angle brackets are merely part of the class name. In comparison, in some languages the convention is to capitalize the first letter of the class name or to prefix the name with a "C" or "T" (for example). <window>
inherits from a single class, <view>
, and contains two slots, title
holding a string for the window title, and position
holding an X-Y point for a corner of the window. In this particular example the title has been given a default value, while the position has not. The optional "init-keyword" syntax allows the programmer to specify the initial value of the slot when instantiating an object of the class.In languages such as C++ or Java, the class would also define its interface. In this case the definition above has no explicit instructions, so in both languages access to the slots and methods is considered
protected
, meaning they can be used only by subclasses. In order to allow unrelated code to use the window instances, they would have to be declared public
.In Dylan these sorts of visibility rules are not considered part of the code itself, but of the module/interface system. This adds considerable flexibility. For instance, one interface used during early development could declare everything public, whereas one used in testing and deployment could limit this. With C++ or Java these changes would require changes to the source code itself, so people won't do it, whereas in Dylan this is a completely unrelated concept.
Although this example does not use it, Dylan also supports multiple inheritance
Multiple inheritance
Multiple inheritance is a feature of some object-oriented computer programming languages in which a class can inherit behaviors and features from more than one superclass....
.
Methods and generic functions
In Dylan, methods are not intrinsically associated with any particular class; methods can be thought of as existing outside of classes. Like CLOS, Dylan is based on multimethods, where the specific method to be called is chosen based upon the types of all its arguments. The method does not have to be known at compile time, the understanding being that the required functionality may be available or may not, based on the user's preferences.Under Java the same methods would be isolated in a particular class. In order to use that functionality the programmer is forced to import that class and refer to it explicitly in order to call the method. If that class is not available, or unknown at compile time, the application simply won't compile.
In Dylan, code is isolated from storage in functions. Many classes have methods that call their own functions, thereby looking and feeling like most other OO languages. However code may also be located in generic functions, meaning they are not attached to a particular class, and can be called natively by anyone. Linking a particular generic function to a method in a class is accomplished this way:
define method turn-blue (w :: )
w.color := $blue;
end method;
This definition is similar to those in other languages, and would likely be encapsulated within the
<window>
class. Note the := setter call, which is syntactic sugarSyntactic sugar
Syntactic sugar is a computer science term that refers to syntax within a programming language that is designed to make things easier to read or to express....
for
color-setter($blue, w)
.The utility of generic methods comes into its own when you consider more "generic" examples. For instance, one common function in most languages is the
to-string
, which returns some human-readableHuman-readable
A human-readable medium or human-readable format is a representation of data or information that can be naturally read by humans.In computing, human-readable data is often encoded as ASCII or Unicode text, rather than presented in a binary representation...
form for the object. For instance, a window might return its title and its position in parens, while a string would return itself. In Dylan these methods could all be collected into a single module called "
to-string
", thereby removing this code from the definition of the class itself. If a particular object did not support a to-string
, it could be easily added in the to-string
module.Extensibility
This whole concept might strike some readers as very odd. The code to handleto-string
for a window isn't defined in <window>
? This might not make any sense until you consider how Dylan handles the call of the to-string
. In most languages when the program is compiled the to-string
for <window>
is looked up and replaced with a pointer (more or less) to the method. In Dylan this occurs when the program is first run; the runtime builds a table of method-name/parameters details and looks up methods dynamically via this table. That means that a function for a particular method can be located anywhere, not just in the compile-time unit. In the end the programmer is given considerable flexibility in terms of where to place their code, collecting it along class lines where appropriate, and functional lines where it's not.The implication here is that a programmer can add functionality to existing classes by defining functions in a separate file. For instance, you might wish to add spell checking to all
<string>
s, which in most languages would require access to the source code of the string class—and such basic classes are rarely given out in source form. In Dylan (and other "extensible languages") the spell checking method could be added in the spell-check
module, defining all of the classes on which it can be applied via the define method
construct. In this case the actual functionality might be defined in a single generic function, which takes a string and returns the errors. When the spell-check
module is compiled into your program, all strings (and other objects) will get the added functionality.This still might not sound all that obvious, but in fact it is a common problem faced by almost all OO languages; not everything fits into a class construct, many problems apply to all objects in the system and there's no natural way to handle this.
Apple Dylan
Apple Dylan is the implementation of Dylan produced by Apple ComputerApple Computer
Apple Inc. is an American multinational corporation that designs and markets consumer electronics, computer software, and personal computers. The company's best-known hardware products include the Macintosh line of computers, the iPod, the iPhone and the iPad...
. It was originally developed for the Apple Newton
Apple Newton
The MessagePad was the first series of personal digital assistant devices developed by Apple for the Newton platform in 1993. Some electronic engineering and the manufacture of Apple's MessagePad devices was done in Japan by the Sharp Corporation...
product.
External links
- The Dylan Reference Manual - The core language and library definition
- Getting Started with Dylan
- Gwydion Dylan - Host of two open source, optimizing Dylan compilers targeting Unix/Linux, Mac OS X, and Microsoft Windows
- The Marlais Dylan Interpreter - An implementation of a subset of Dylan, suitable for bootstrapping a compiler
- Dylan Programming Language - A general information website
- Dylan Language Wiki
- A Dylan Primer for Scheme Programmers