Chapter 2 - About Smalltalk

This chapter gives a brief overview of the Smalltalk programming language. There are some excellent tutorials on the World Wide Web for those interested in learning Smalltalk (links given at the end of this page). This chapter is mainly to help you determine whether Smalltalk is the right language for you. Experienced Smalltalk users can skip this chapter.

If you are new to computer programming, don't be intimidated by the somewhat rushed summary given below. Just read it once or twice to get a general feel for things, and don't worry if you don't understand everything you read.

Synopsis

Smalltalk is a simple and powerful object-oriented programming language. Unlike "hybrid" object-oriented languages like Java and C++, Smalltalk is considered to be a "pure" object-oriented language. Smalltalk is said to be "pure" for one main reason: Everything in Smalltalk is an object, whereas in hybrid systems there are things which are not objects (for example, integers in C and Java).

The benefits of the "everything is an object" philosophy are great, and pure languages such as Smalltalk are considered to be more productive and (more importantly) more fun to program in.

Smalltalk is fundamentally tied to automatic dynamic memory management, and as such must be supported by an underlying automatic memory management system. In practical terms this means that a Smalltalk programmer no longer needs to worry about when to free allocated memory. When finished with a dynamically allocated object, the program can simply "walk away" from the object. The object is automatically freed, and its storage space recycled, when there is nothing else referencing it.

Message Sending

All computations in Smalltalk are performed by objects sending messages to one another. A message is a name for a routine to execute, possibly together with some arguments to the routine. The power in this approach is that different objects can respond to the same message in different ways (that is, by executing different routines). Moreover, the sender of a message does not need to know in advance how the receiver will interpret the message. This is the power of object oriented programming.

Smalltalk has a uniquely simple and elegant syntax for expressing message sending. There are three possible forms:

receiver doSomething
This is a "unary" message send. Write the receiver on the left and the message name ('doSomething', in this case) on the right. There are no arguments.

receiver + argument
This is a "binary" message send. As before, the receiver goes on the left, followed by the message name ('+'), followed by exactly one argument. This form of message sending is always used for messages with "funny" names like +. Any message name that is composed of symbols instead of letters and numbers uses this syntax, and all such messages take exactly one argument.

receiver take: 3 of: 'candy'
This is a "keyword" message send. Keywords ending in : (colon) alternate with arguments. The whole thing is considered a single message send. The message name is the concatenation of all the keywords (in this case, 'take:of:'). There are as many arguments as there are keywords, and there can be as many keywords as you want.

Blocks

One of the most useful features of Smalltalk is the ability to define "local functions" in the form of blocks. Blocks have many of the properties of lexical closures and can be used to implement a wide variety of control structures. In fact, Smalltalk has no built-in control structures, but instead implements them in terms of blocks. Blocks are written as one or more Smalltalk statements between square brackets ([ and ]). Arguments to block functions can be specified by putting the argument names, prefixed by colons, before a vertical bar (|) at the beginning of the block. Here are some examples:

5 timesRepeat: [self print: 'Hello world!'].

primes := (1 to: 100) select: [:number | number isPrime].

#('mary' 'had' 'a' 'little' 'lamb')
   do: [:string | self print: string]
   separatedBy: [self space].

[self shouldContinue]
    whileTrue: [self performAction].

The important thing to note here is that all control flow constructs are implemented as messages interpreted by various kinds of objects. For example, 'timesRepeat:' is a message understood by integers.

Classes and Inheritance

How do objects know how to respond to messages? The answer reveals another general unifying feature of Smalltalk: every object belongs to a class. A class defines which messages can be understood by members (also called instances) of that class, and it defines how objects respond to those messages.

Since everything in Smalltalk is an object, everything has a class. For example, the number 5 has a class named Integer. The string 'hello' has a class named String, and so forth. You can define your own classes and create instances of them. You can find out what class any object belongs to by sending it the message 'class'.

Classes themselves are instances of other classes called metaclasses. Metaclass programming is a relatively advanced part of Smalltalk programming, but it can be used to achieve some important effects. The Smalltalk class browser makes both "ordinary class" and metaclass programming quite easy.

When you program in Smalltalk, you spend most of your time creating and modifying class definitions. In the Smalltalk class browser window, you can associate message names (also called selectors) with Smalltalk program code fragments (also called methods). A class, therefore, is a mapping between selectors and methods. When an instance of a class receives a message, it consults its class to see which method it should invoke in response to the message.

A very important ability of Smalltalk classes is that they can inherit from other classes. This reflects the observation that most objects can be viewed as specializations of more general objects. For example a character string like 'hello' can be viewed a a collection of letters (characters). Therefore, the String class inherits many of its abilities from another more general class called Collection. Every class inherits from exactly one other class (this is known as single inheritance, in contrast to the multiple inheritance of C++, Self, and to a lesser extent Java). Every class therefore inherits abilities from another class, called its superclass. There is one exception to this rule: the class called Object has no superclass. Therefore, every other class ultimately inherits from Object. Inherited abilities are themselves inherited, so superclasses can be "nested" to any depth. For example the Integer class inherits from Number, which in turn inherits from Object.

Summary and Links

This has been a very brief introduction to the Smalltalk language. If you are interested in pursuing further, see the links below for some online Smalltalk tutorials:


Andrew Brault (ajb@tiac.net)