CLOS
Encyclopedia
The Common Lisp Object System (CLOS) is the facility for object-oriented programming
which is part of ANSI Common Lisp
. CLOS is a powerful dynamic
object system which differs radically from the OOP facilities found in more static languages such as C++
or Java
. CLOS was inspired by earlier Lisp object systems such as MIT Flavors and CommonLOOPS
, although it is more general than either. Originally proposed as an add-on, CLOS was adopted as part of the ANSI standard for Common Lisp and has been adapted into other Lisp dialects like EuLisp
or Emacs Lisp
.
s and their methods. CLOS provides macros to define those:
Classes can have multiple superclasses, a list of slots (member variables in C++/Java parlance) and a special meta class. Slots can be allocated by class (all instances of a class are sharing the slot) or by instance. Each slot has a name and the value of a slot can be accessed by that name using the function
CLOS is a multiple dispatch
system. This means that method
s can be specialized upon any or all of their required arguments. Most OO languages are single-dispatch, meaning that methods are only specialized on the first argument. Another unusual feature is that methods do not "belong" to classes; classes do not provide a namespace for generic functions or methods. Methods are defined separately from classes, and they have no special access (e.g. this, self, or protected) to class slots.
Methods in CLOS are grouped into generic function
s. A generic function is an object which is callable like a function and which associates a collection of methods with a shared name and argument structure, each specialized for different arguments. Since Common Lisp provides non-CLOS classes for structures and built-in data types (numbers, strings, characters, symbols, ...), CLOS dispatch works also with these non-CLOS classes. CLOS also supports dispatch over individual objects (eql specializers). CLOS does not by default support dispatch over all Common Lisp data types (for example dispatch does not work for fully specialized array types or for types introduced by
Dispatch in CLOS is also different from most OO languages:
This dispatch mechanism works at runtime. Adding or removing methods thus may lead to changed effective methods (even when the generic function is called with the same arguments) at runtime. Changing the method combination also may lead to different effective methods.
For example,
Like the OO systems in most dynamic languages
, CLOS does not enforce encapsulation. Any slot can be accessed using the
facility to declare which functions or data structures are intended for export.
Apart from normal ("primary") methods, there also are
The Standard Method-Combination provides above primary, before, after and around methods. There are other Method-Combinations with other method types. New (both simple and complex) Method-Combinations and method types can be defined.
CLOS allows multiple inheritance
. When the default order in which methods are executed in multiple inheritance is not correct, the programmer may resolve the diamond inheritance problems
by specifying the order of method combinations.
CLOS is dynamic, meaning that not only the contents, but also the structure of its objects can be modified at runtime. CLOS supports changing class definitions on-the-fly (even when instances of the class in question already exist) as well as changing the class membership of a given instance through the
is readily solved in CLOS, and most OOP design patterns
either disappear or are qualitatively simpler.
CLOS is not a prototype language: Classes must be defined before objects can be instantiated as members of that class.
Protocol (MOP). The MOP defines a standard interface to the underpinnings of the CLOS implementation, treating classes, slot-descriptions, generic-functions and methods themselves as instances of metaclass
es, and allows the definition of new metaclasses and the modification of all CLOS behavior. The flexibility of the CLOS MOP prefigures aspect-oriented programming
, which was later developed by some of the same engineers, such as Gregor Kiczales
. The MOP defines the behavior of the whole object system by a set of protocols. These are defined in terms of CLOS. Thus it is possible to create new object-systems by extending or changing the provided CLOS functionality. The Book The Art of the Metaobject Protocol
describes the use and implementation of the CLOS MOP.
The various Common Lisp implementations have slightly different support for the Meta-Object Protocol. The Closer project aims to provide the missing features.
. Large parts of the Lisp Machine operating systems and many applications for it use Flavors or New Flavors. Flavors introduced multiple inheritance
and mixins, amongst other features. Flavors is mostly obsolete, though implementations for Common Lisp do exist. Flavors was using the message passing paradigm. New Flavors introduced generic functions.
CommonLoops
was the successor of LOOPS (from Xerox Interlisp
-D). CommonLoops was implemented for Common Lisp. A portable implementation called Portable CommonLoops (PCL) was the first implementation of CLOS. PCL is widely ported and still provides the base for the CLOS implementation of several Common Lisp
implementations. PCL is implemented mostly in portable Common Lisp with only a few system dependent parts.
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,...
which is part of ANSI 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...
. CLOS is a powerful 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...
object system which differs radically from the OOP facilities found in more static languages such as 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...
or 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...
. CLOS was inspired by earlier Lisp object systems such as MIT Flavors and CommonLOOPS
CommonLoops
CommonLoops is an early programming language which extended Common Lisp to include Object-oriented programming functionality and is a dynamic object system which differs from the OOP facilities found in static...
, although it is more general than either. Originally proposed as an add-on, CLOS was adopted as part of the ANSI standard for Common Lisp and has been adapted into other Lisp dialects like EuLisp
EuLisp
EuLisp is a statically and dynamically scoped Lisp dialect developed by a loose formation of industrial and academic Lisp users and developers from around Europe. The standardizers intended to create a new Lisp "less encumbered by the past" , and not so minimalistic as Scheme...
or Emacs Lisp
Emacs Lisp
Emacs Lisp is a dialect of the Lisp programming language used by the GNU Emacs and XEmacs text editors . It is used for implementing most of the editing functionality built into Emacs, the remainder being written in C...
.
Features
The basic building blocks of CLOS are classes, instances of classes, generic functionGeneric function
In certain systems for object-oriented programming such as the Common Lisp Object System and Dylan, a generic function is an entity made up of all methods having the same name. Typically a generic function itself is an instance of a class that inherits both from function and standard-object...
s and their methods. CLOS provides macros to define those:
defclass
, defgeneric
and defmethod
. Instances are created with the function make-instance
.Classes can have multiple superclasses, a list of slots (member variables in C++/Java parlance) and a special meta class. Slots can be allocated by class (all instances of a class are sharing the slot) or by instance. Each slot has a name and the value of a slot can be accessed by that name using the function
slot-value
. Additionally special generic functions can be defined to write or read values of slots. Each slot in a CLOS class must have a unique name.CLOS is a multiple dispatch
Multiple dispatch
Multiple dispatch or multimethods or function overloading is the feature of some object-oriented programming languages in which a function or method can be dynamically dispatched based on the run time type of more than one of its arguments...
system. This means that method
Method (computer science)
In object-oriented programming, a method is a subroutine associated with a class. Methods define the behavior to be exhibited by instances of the associated class at program run time...
s can be specialized upon any or all of their required arguments. Most OO languages are single-dispatch, meaning that methods are only specialized on the first argument. Another unusual feature is that methods do not "belong" to classes; classes do not provide a namespace for generic functions or methods. Methods are defined separately from classes, and they have no special access (e.g. this, self, or protected) to class slots.
Methods in CLOS are grouped into generic function
Generic function
In certain systems for object-oriented programming such as the Common Lisp Object System and Dylan, a generic function is an entity made up of all methods having the same name. Typically a generic function itself is an instance of a class that inherits both from function and standard-object...
s. A generic function is an object which is callable like a function and which associates a collection of methods with a shared name and argument structure, each specialized for different arguments. Since Common Lisp provides non-CLOS classes for structures and built-in data types (numbers, strings, characters, symbols, ...), CLOS dispatch works also with these non-CLOS classes. CLOS also supports dispatch over individual objects (eql specializers). CLOS does not by default support dispatch over all Common Lisp data types (for example dispatch does not work for fully specialized array types or for types introduced by
deftype
). However, most Common Lisp implementations provide a metaobject protocol which allows generic functions to provide application specific specialization and dispatch rules.Dispatch in CLOS is also different from most OO languages:
- Given a list of arguments, a list of applicable methods is determined.
- This list is sorted according to the specificity of their parameter specializers.
- Selected methods from this list are then combined into an effective method using the method combination used by the generic function.
- The effective method is then called with the original arguments.
This dispatch mechanism works at runtime. Adding or removing methods thus may lead to changed effective methods (even when the generic function is called with the same arguments) at runtime. Changing the method combination also may lead to different effective methods.
For example,
Like the OO systems in most dynamic languages
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...
, CLOS does not enforce encapsulation. Any slot can be accessed using the
slot-value
function or via (optionally auto-generated) accessor methods. To access it via slot-value
you have to know the name of the slot. CL programmers use the language's packageNamespace (computer science)
A namespace is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols . An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces...
facility to declare which functions or data structures are intended for export.
Apart from normal ("primary") methods, there also are
:before
, :after
, and :around
"auxiliary" methods. The former two are invoked prior to, or after the primary method, in a particular order based on the class hierarchy. An :around
method can control whether the primary method is executed at all. Additionally, the programmer can specify whether all possible primary methods along the class hierarchy should be called or just the one providing the closest match.The Standard Method-Combination provides above primary, before, after and around methods. There are other Method-Combinations with other method types. New (both simple and complex) Method-Combinations and method types can be defined.
CLOS allows 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....
. When the default order in which methods are executed in multiple inheritance is not correct, the programmer may resolve the diamond inheritance problems
Diamond problem
In object-oriented programming languages with multiple inheritance and knowledge organization, the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C...
by specifying the order of method combinations.
CLOS is dynamic, meaning that not only the contents, but also the structure of its objects can be modified at runtime. CLOS supports changing class definitions on-the-fly (even when instances of the class in question already exist) as well as changing the class membership of a given instance through the
change-class
operator. CLOS also allows one to add, redefine and remove methods at runtime. The Circle-Ellipse ProblemCircle-ellipse problem
The circle-ellipse problem in software development illustrates a number of pitfalls which can arise when using subtype polymorphism in object modelling...
is readily solved in CLOS, and most OOP design patterns
Design pattern (computer science)
In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that...
either disappear or are qualitatively simpler.
CLOS is not a prototype language: Classes must be defined before objects can be instantiated as members of that class.
Metaobject Protocol
Outside of the ANSI Common Lisp standard, there is a widely implemented extension to CLOS called the MetaobjectMetaobject
In computer science, a metaobject or meta-object is any entity that manipulates, creates, describes, or implements other objects. The object that the metaobject is about is called the base object...
Protocol (MOP). The MOP defines a standard interface to the underpinnings of the CLOS implementation, treating classes, slot-descriptions, generic-functions and methods themselves as instances of metaclass
Metaclass
In object-oriented programming, a metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances. Not all object-oriented programming languages support metaclasses...
es, and allows the definition of new metaclasses and the modification of all CLOS behavior. The flexibility of the CLOS MOP prefigures aspect-oriented programming
Aspect-oriented programming
In computing, aspect-oriented programming is a programming paradigm which aims to increase modularity by allowing the separation of cross-cutting concerns...
, which was later developed by some of the same engineers, such as Gregor Kiczales
Gregor Kiczales
Gregor Kiczales is a professor of computer science at the University of British Columbia in Canada. His best known work is on Aspect-oriented programming and the AspectJ extension for Java at Xerox PARC. He has also contributed to the design of the Common Lisp Object System, and is the author of...
. The MOP defines the behavior of the whole object system by a set of protocols. These are defined in terms of CLOS. Thus it is possible to create new object-systems by extending or changing the provided CLOS functionality. The Book The Art of the Metaobject Protocol
The Art of the Metaobject Protocol
The Art of the Metaobject Protocol is a 1991 book by Gregor Kiczales, Jim des Rivieres, and Daniel G. Bobrow on metaobject protocol...
describes the use and implementation of the CLOS MOP.
The various Common Lisp implementations have slightly different support for the Meta-Object Protocol. The Closer project aims to provide the missing features.
Influences from older Lisp-based object systems
Flavors (and its successor New Flavors) was the object system on the MIT Lisp MachineLisp machine
Lisp machines were general-purpose computers designed to efficiently run Lisp as their main software language. In a sense, they were the first commercial single-user workstations...
. Large parts of the Lisp Machine operating systems and many applications for it use Flavors or New Flavors. Flavors introduced 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....
and mixins, amongst other features. Flavors is mostly obsolete, though implementations for Common Lisp do exist. Flavors was using the message passing paradigm. New Flavors introduced generic functions.
CommonLoops
CommonLoops
CommonLoops is an early programming language which extended Common Lisp to include Object-oriented programming functionality and is a dynamic object system which differs from the OOP facilities found in static...
was the successor of LOOPS (from Xerox Interlisp
Interlisp
Interlisp was a programming environment built around a version of the Lisp programming language. Interlisp development began in 1967 at Bolt, Beranek and Newman in Cambridge, Massachusetts as BBN LISP, which ran on PDP-10 machines running the TENEX operating system...
-D). CommonLoops was implemented for Common Lisp. A portable implementation called Portable CommonLoops (PCL) was the first implementation of CLOS. PCL is widely ported and still provides the base for the CLOS implementation of several 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...
implementations. PCL is implemented mostly in portable Common Lisp with only a few system dependent parts.
Literature
- Gregor KiczalesGregor KiczalesGregor Kiczales is a professor of computer science at the University of British Columbia in Canada. His best known work is on Aspect-oriented programming and the AspectJ extension for Java at Xerox PARC. He has also contributed to the design of the Common Lisp Object System, and is the author of...
, Jim des Rivieres, and Daniel G. BobrowDaniel G. BobrowDaniel Gureasko Bobrow is a Research Fellow in the Intelligent Systems Laboratory of the Palo Alto Research Center, and is amongst other things known for creating an oft-cited artificial intelligence program STUDENT, with which he earned his PhD....
, The Art of the Metaobject ProtocolThe Art of the Metaobject ProtocolThe Art of the Metaobject Protocol is a 1991 book by Gregor Kiczales, Jim des Rivieres, and Daniel G. Bobrow on metaobject protocol...
, 1991, MIT Press. ISBN 0-262-61074-4 - The Common Lisp Object System: An Overview by Richard P. Gabriel and Linda DeMichiel provides a good introduction to the motivation for defining classes by means of generic functions.
- Fundamentals of CLOS by Nick Levine provides a step-by-step exposure to the implementation of OO concepts in CLOS, and how to utilize them. It is intended for anybody with a basic knowledge of Lisp or Scheme.
- Sonya Keene, Object-Oriented Programming in Common Lisp: A Programmer's Guide to CLOSObject-Oriented Programming in Common Lisp: A Programmer's Guide to CLOSObject-Oriented Programming in Common Lisp: A Programmer's Guide to CLOS is a book by Sonya Keene on the Common Lisp Object System...
, 1988, Addison-Wesley. ISBN 0-201-17589-4 - Common Lisp HyperSpecCommon Lisp HyperSpecThe Common Lisp HyperSpec is a hypertext html document which is not the ANSI Common Lisp standard, but is based on it with permission from ANSI and X3. It is copyrighted by LispWorks Ltd...
, Chapter 7: Objects