- Message-Sending
- Turtles All the Way Down
- No Source Code
- Classes and Objects
- Smalltalk Descendants
Classes and Objects
Some people refer to the "Simula school of object orientation," but this expression is quite misleading. Simula is not an object-oriented language, but it's a class-based language. By contrast, Smalltalk is both an object-oriented and a class-based language. Self, a direct descendent of Smalltalk, is object-oriented, but isn't class-based.
In Smalltalk, everything is an object, and objects are instances of classes. When you send a message to an object, its class decides how that message is handled. Because everything is an object, classes are objects, too. Just as an object is an instance of a class, a class is an instance of a metaclass.
In Self, classes didn't enjoy any special status. Every object decided on its own how it handled messages. You could add methods to a single instance of an object. Rather than delegating method lookup to a class (which delegated to its superclass), objects could delegate lookup to any other object, known as its prototype.
Neither of these models is more expressive than the other—it's possible to translate automatically between the two, although running Smalltalk code in a Self virtual machine is easier than the other way around. Effectively, a Smalltalk object is a Self object that doesn't have any methods of its own, and has its class as its prototype.
The Self model is probably quite familiar to a lot of readers, as it has been adopted by one of the most successful languages that you'll see used at the moment: JavaScript. The JavaScript object model is almost directly equivalent to that of Self. Like Self, JavaScript has objects and closures, but no classes. Objects behave like dictionaries, and you define a method by attaching a closure to an object.
The Self VM was very fast, and a lot of papers were published by the Self team about optimizing dynamic languages. Some of the techniques that they developed are now common in JavaScript implementations. For example, Google's V8 engine (found in the Chrome browser) performs a hidden class transform. This technique was originally developed to run Self programs in Smalltalk virtual machines, by mapping the Self object model back to the Smalltalk one.
It works by first observing that, although you can have a different set of methods for every object in Self, people never actually do that. Few objects add methods that aren't present in their prototype. Conceptually, you could implement Self in Smalltalk by making every object an instance of its own class, which inherited from its prototype's class. This technique wouldn't be very efficient, but fortunately it turns out that a lot of these classes will be identical, so you can reuse them. The hidden class transform helps with optimization as well, because you can cache method lookups per class, rather than per object, which gives a much greater change of a cache hit.