Influential Programming Languages, Part 3: Smalltalk
To understand modern programming languages and patterns, it's important that you know about the languages that originated them. In the first two parts of this series, we looked at ALGOL and Simula, which are intimately tied to the structured programming and class-based models. In this article, we'll look at a slightly more modern model: object orientation.
It's hard to talk about object orientation without talking about Smalltalk. The term object orientation was coined by Alan Kay, while he was at the University of Utah, to describe his style of programming. The Smalltalk language was created a few years later, after Kay had moved to Xerox PARC, to embody this style. The relationship between Smalltalk and object orientation is very similar to the relationship between ALGOL and structured programming.
Smalltalk, like Xen, was created on a bet. In this case, the bet was whether it was possible to specify a complete programming language on a single piece of paper.
Most programming languages have a variety of flow-control constructs; for example, conditionals (such as if/switch statements), loops (for, while, and so on), and function calls. Smalltalk has only one: a message-send.
The object-oriented programming model was created in response to the growing complexity of computer programs. When attempting to design a complex system, Alan Kay reasoned that you should split it into simple components. The simplest possible model for a component of a computer program is itself a computer. Objects in this system are simple models of computers, and they communicate by exchanging messages.
At the lowest level, flow control is implemented in terms of conditional branches. Conditional statements in most programming languages are a higher-level version of conditional jump instructions. Smalltalk has no direct equivalent. Every other flow-control construct is built on top of message-sending. For example, consider this statement in C:
if (someCondition) doSomething();
If someCondition is true, the doSomething() function executes. In Smalltalk, the equivalent would be as follows:
someCondition ifTrue: [ self doSomething ].
Here, someCondition is a Boolean object, an instance of either the True or False class. Both of these classes implement an ifTrue: method; in the False class it does nothing, and in the True class it will look something like this:
ifTrue: aBlock [ ^aBlock value. ]
The argument is a block (closure). Sending a value message to a block executes it. When you send an ifTrue: message to an instance of the True class, it simply executes the argument. This design allows you to implement something equivalent to C's if statement, purely in terms of message-sending. In fact, it's more powerful, because the receiver doesn't have to be a Boolean object. You can implement a new class that responds to these messages. For example, you could implement some form of trinary logic by providing a Maybe class that did nothing when sent ifTrue: or ifFalse: message.
Dan Ingalls, one of the designers of Smalltalk, proposed a test for whether a language is object-oriented. In an object-oriented language, a user should be able to create a new type of integer and use it to specify the coordinates for drawing in a system-provided window class. Very few languages satisfy this condition. Those that do are typically considered "pure" object-oriented languages; those that don't, but come close (such as Java), are called object-oriented, without the "pure."
The Ingalls test seems a contrived example, but it has some interesting uses. For example, suppose you want to create a window in which everything is clipped or wrapped into a rectangle. A trivial way of doing this would be to use coordinates that used modulo or saturating arithmetic. Without this capability, you need to perform the wrapping or clamping on every single arithmetic operation in your window.