Problems with the term 'object-oriented'

'Object-oriented' means different things to different people. A programmer who came from a Java background may consider 'object-oriented' to mean a style of programming where the code and data are bound together in objects, whose structure is based on class hierarchies with hiding of internal data that relate to such properties as encapsulation & protection. Meanwhile, a Lisp programmer might say that Lisp is object-oriented because it provides polymorphism (both ad hoc polymorphism and parametric polymorphism) and the ability to specify that one type is as good as another (specification inheritance).

Without a unified meaning of the term 'object-oriented,' it is meaningless to discuss object-oriented programming, let alone how it pertains to Scheme. Of course, many of the paradigms explained below are useful, and hence they are implemented for Scheme. Despite the concerns of this page, due to popular demand, they call themselves object-systems.

In December of 2001, Jonathan Rees wrote to the LL1 mailing list an article discussing the whole situation with the meaning of the term 'object-oriented.' In the beginning of the article, he presented a brief list, not necessarily exhaustive or most accurate, containing aspects of what he has heard many people mean when they say 'object-oriented.' With a set of explicitly named concepts that many may think of when they say 'object-oriented,' it is much easier and less error-prone to discuss those concepts.

What aspects has the term 'object-oriented' been assigned to?

This was not meant to be a complete list of all the properties of what has been considered 'object-oriented'; however, it does provide a firm ground on which to discuss the questions that the reader of this page likely had in mind when first coming across the page.


Syntactically hiding the specific implementation of a given interface. For instance, the implementation of a queue structure is not apparent from the interface if the definition of the queue data type is encapsulated.


The hiding of implementation details from the client. For instance, in Smalltalk? all of the data-members of an object are hidden. In Java, you can select the level of protection (private, public, protected) on both data and behavioural members of an object.

Ad-Hoc Polymorphism

A method behaves differently based on the types of its arguments and sometimes the return type.

Parametric Polymorphism

A method is defined over a data structure of values of any type. For example, a list appending method could be defined over lists of any type. For example, Java tries to have this using a single root class of the class hierarchy, Object, but doesn't due to the primitive types. The common root class model also does escape from the static type checking. Java 1.5/5.0 might solve this problem.

Everything is an object

This has a troublesome definition, since object itself means different things to different people. This is intended to mean that every value that the language supports is also an object in whatever sense the language uses that name, without allowing any exceptions such as the primitive types in Java.

All You Can Do Is Send A Message

Also known as message passing. There is no direct manipulation of objects, all you can do is send the object a message (or call a method). The Actors Model builds on this and allows for concurrent objects who recieve messages asynchronously. Scheme was created to investigate actors, as closures can be seen as objects which receive messages (arguments).

Specification Inheritance

Sub-Typing. This is different from sub-classing (see below). Specification inheritance is where one object is as good as another for the purposes of type. For instance, a complex number is as good as a real number for an addition operation.

Implementation Inheritance

Sub-Classing. Behaviour (code) from one unit can be accessed from another unit without the need to copy-and-paste code.

Sum-of-product-of-function pattern

Objects are essentially functions that in-effect take as their first argument the name of the method to invoke from a finite list. For example, in Java when you are calling method foo on object bar, foo has to be defined for bar - if not, you get a compile error. In other systems, you can blindly send messages to any object and just see what happens.

Object Orientation

So, given this list, we can now ask what the famed "Object Orientation" is that some existing languages are said to support.

Beware that not all of these things can be considered features (e.g. the sum-of-product-of-function pattern or Protection), others can be mutually exclusive or dependant (e.g. the Actors Model depends on Protection), while still others don't make sense for all languages (Parametric Polymorphism is only useful if your language does static type checking, other languages get this for free).

Encapsulation is not part of a language or system, but an attribute of the abstract data type you define.

In this table, X means yes, - means no, while * means that this doesn't make sense for this language.

CLOS Closures Java Python
Protection - X X -
Ad-Hoc Polymorphism X - X -
Parametric Polymorphism * * X (1.5) *
Everything is an object X - - X
All you can do is send a message - X - -
Specification Inheritance X * X *
Implementation Inheritance X X X (limited) X
Sum-of-product-of-function pattern - - X X

Alan Kay speaks up

Alan Kay is the guy who invented the term "Object-Oriented Programming". His definition would be:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them.

That is (taken also from the website):

How does it work in Scheme?

So now that you have a better idea of the multi-faceted and confusing nature of "Object Oriented Programming", we can lead you in a general direction on where you want to go, and how to get there with scheme.

The first thing to be aware of is that Scheme already provides most of the items on the menu. The simple-object page will show you message-passing, encapsulation and by extension (limited) protection. Parametric polymorphism is also supported by the Schemes type system.

Now, if you want to do things like define classes and/or play around with a meta-object-protocol, visit the object-systems page and find a system that works for you, and does what you need. Conversely you can roll-your-own-object-system, which is considered a badge of pride amongst some schemers.


Other sources

A very interesting article by Oleg K. on subtyping problems:

Course notes on the implementation of objects: