What is OOP?
OOP stands for Object-Oriented Programming.
OK, what is Object-Oriented Programming?
Who knows? Not me. There are lots of theories. Here are some:
- Some programmers think that OOP means Smalltalk, i.e. Our Only Programming-language.
- Some programmers think that OOP means Hypercard or its successful sibling, Visual Basic.
- Some programmers think that OOP means that constructors must be stored in tree structures.
- Some programmers think that OOP means that systems should be built using only unary operators.
- Some programmers think that OOP is a fancy word for 'subroutine'.
- Some salesmen think that OOP is shorthand for 'our company employees programmers'.
:-) For my part, all I can say is OOP usually involves an object system.
What is an object system?
An object system is a database which stores closures. Each closure in the database has a key which consists of a signature and zero or more objects. The object system has operations which support the adding new closures to the database, recovering closures given a key, and removing closures from the database.
What is a closure?
A closure is a function with no free variables. More often than not, closures in object-oriented programming systems are called 'methods'. I have purposely avoid using the term method to avoid conjuring up any pre-conceived notions about issues such as method lookup.
What is a function?
Let's not get in to that. I don't mean anything mathematically precise by this. In particular, I do not wish to imply anything about the presence or absence of side-effects or even determinism. I could just have easily said procedure or subroutine. I will take the notion of function as self-evident.
What is a signature?
All functions accept parameters of certain data types and return values of certain types. They also have certain set of semantics. Collectively, the types and semantics are called the 'signature' of a function. It is an unsolved problem in computer science to find a way to express the semantics of a function in some concise way. As a result, most programming systems are content to summarize the semantics of a function by giving it a name. Thus, the signature of a function is reduced to its name and data types.
What is a free variable in a function?
A free variable in a function is a reference to an object that is not defined in the function, e.g. the function
int getNextValue()
{
x = x + 1;
return x;
}
has references the variable x, whose definition is elsewhere. Note that, in this context, any parameters to the function are not considered to be 'free variables' since the function cannot be invoked without specifying values for those parameters.
But programmers often write functions with free variables - how do they become closures?
It is the task of the object system to convert functions to closures. This is done by supplying values for each of the functions free variables. There are a many ways to do this. For example, here are some programming languages and their strategies:
Language | In... | Free variables can be bound to... |
---|---|---|
C | all functions | global variables |
Java | all methods | other class members |
Pascal | all functions | global variables |
nested functions | variables in enclosing blocks | |
C++ | all functions | global variables |
all member functions | other class members | |
Smalltalk | all methods | object or class variables, global/pool variables |
blocks | variables in enclosing blocks or methods | |
LISP | all functions | global variables, or "special" variables in the call stack |
nested functions | variables in enclosing blocks | |
generic functions | object or class slots |
It is in this way that you can view an object system as a storage system which, when given a reference to an object and the signature of a function, returns an appropriate closure. In languages such as C, there is only one object -- the implicit 'global' object. Languages with an object system allow (or demand that) the programmer supply an explicit object. Some object systems (e.g. the Common Lisp Object System, CLOS), even allow the programmer to specify more than one object when looking up closures. However, CLOS and similar systems cannot be properly called object-oriented, but rather something like closure-oriented or method-oriented. In passing, I will note that my view is that OOP is an intermediate stage on the way to the more general closure-oriented programming.
The interesting part of an object system is its closure look-up mechanism. The fun begins when a closure key is sought in the database and is not found. In the procedural languages (e.g. C, FORTRAN), a compile-time, link-time, or run-time error is signalled. Other languages have more recovery mechanisms, for example:
Language | Other places to look for closures (methods) |
---|---|
Simula | an object's class and superclasses |
Beta | a pattern's subpatterns (i.e an object's class and subclasses) |
C++ | functions generated from templates |
Lisp | lots of places, including user-defined ones |
What is a data type?
A data type is an arbitrary collection of function signatures. If you detect a certain circularity between the definitions of signature and data type, then you have put your finger on another unsolved problem in computer science. Fortunately, the circularity does not appear to cause difficulties in practice. The difficulty is usually resolved by having certain built-in data types that have special properties and That Is Just The Way It Is.
Note that if an object is viewed as an arbitrary collection of closures then an object is of a given data type if for every signature in the data type the object has a closure with a matching signature.
Some programming languages, the strongly-typed ones, check the data types of objects as early as possible (e.g. compile-time). To do this, they typically constrain the 'arbitrary collection of signatures' somewhat. For example, in Java the signatures must all belong to a single class (or its superclasses or superinterfaces). Other languages, the weakly-typed ones, place no such restrictions and defer type checking to a very late stage (e.g. run-time). For example, in Smalltalk a data type is called a 'protocol'. There is no formal language support for protocols but any object can potentially support any protocol. This yields significant flexibility in exchange for more onerous testing requirements.
What is an object?
An object is an arbitrary identifier used as part of a closure-key in an object system. Therefore, one can roughly view an object a collection of closures. I say 'roughly', because some object systems permit zero objects or more than one object to be used in a key.
If one looks 'under the hood' of an object system, one might find that the term 'object' has a much more concrete meaning. For example, in C++ an object is a block of storage allocated specifically for holding the variables associated with a set of closures and a pointer to a jump table for the code blocks for those closures.
How do objects get created?
By far, the most common techniques employed by object systems are to delegate object creation to a class or prototype.
What is a class?
A 'class' is a kind of object which creates other objects. Usually, a class object is handled specially by the object system in question. User-defined classes often leverage the built-in class functionality of an object system, but sometimes they are designed from scratch and then called 'factories' to distinguish them from the built-in variety of class. In general, a class is an object with three closures: one which creates an object, one which locates a closure for an object given a signature, and one that destroys an object which was created by the first closure.
Most of the details of a class are private to the object system's implementation. For example, the class will arrange for any necessary storage to be allocated for the object and for that storage to be released when the object's life is over. Beyond, creation and destruction, there are not many more operations that are common to all object systems. Some object systems allow classes to be grouped into hierarchies and to automatically delegate certain functions to classes which appear higher in the hierarchy. Other object systems delegate functions to classes which appear lower in the hierarchy. Still other object systems dispense with the concept of hierarchy and permit arbitrary delegation.
What is a prototype?
A 'prototype' is an object which can clone itself. Some object systems, such as those in the languages Self and Javascript, rely on cloning as the normal way to create objects. A single object is created and then has its structure modified procedurally. Then that object is duplicated as many times as needed.