Smalltalk, Objects,
and Design

Chamond Liu

San Jose

toExcel

New York

Shanghai
“My good friend, every profession requires effort and devotion and practice.”

— advice to the young Perceval [de Troyes 1190]
# Contents

Acknowledgments xi

Preface xiii

1 Objects 1

1.1 Objects 1

1.2 Examples of Smalltalk messages (telegrams) 5

1.3 Pitfall: the effect versus the return 6

1.4 Why objects matter 7

1.5 Recap: objects 8

1.6 Exercise: warmup (the image) 9

1.7 Commentary: perspectives on objects 9

2 Classes and inheritance 11

2.1 Classes 11

2.2 The word "class" 13

2.3 Inheritance 13

2.4 Terminology 18

2.5 Exercise: hierarchies 21

2.6 Solution and discussion: Aggregation hierarchies 21

2.7 Example: aggregation plus inheritance 22

2.8 Syntaxes for inheritance 23

2.9 Example: inheritance in Smalltalk 24

2.10 Exercise: building a class hierarchy 26

2.11 Commentary: what is object-oriented programming? 27

2.12 Commentary: other languages 29

2.13 Commentary: history 30
3 Smalltalk introduction 32

3.1 Elementary objects 32

3.2 Messages and their precedences 33

3.3 Pitfalls: basic Smalltalk gotchas 34

3.4 Examples 36

3.5 Exercise: a hypothetical method 37

3.6 Solution and discussion 38

3.7 Kinds of variables 39

3.8 Pitfall: variables ≠ objects 40

3.9 Classes are objects 40

3.10 Control flow 42

3.11 Commentary: metaclasses 43

4 Exercises—Foundations 44

4.1 Precautions 44

4.2 Finding things in Smalltalk 46

4.3 Elements of Smalltalk 48

4.4 Smalltalk's debugger 57

4.5 Provocations 59

5 Abstract classes 61

5.1 Exercise in object-oriented design 62

5.2 Solution and discussion 62

5.3 Pure virtual (subclassResponsibility) methods 64

5.4 Exercise: discovering pure virtuals 65

5.5 Solution and discussion 65

5.6 Ensuring no instances 65

5.7 Concrete behavior in abstract classes 67

5.8 Summary: methods in abstract classes 68

6 Containers and other indispensable ideas 69

6.1 Heterogeneity and homogeneity 70

6.2 Exercise: heterogeneity and homogeneity 71

6.3 Exercise: dictionaries 72

6.4 Preparatory exercise: identity versus equality 73

6.5 Identity dictionaries 74

6.6 Exercise: identity dictionaries 75

6.7 Overriding equality 75

6.8 Exercise: anomaly of the disappearing element 76

6.9 Exercise: excursion into Streams 77

6.10 Containers versus aggregations 78

6.11 Shallow and deep copying 79
6.12 Commentary: value and reference semantics 80

6.13 Commentary: containers in C++ 81

7 *CRC cards* 82

7.1 Design exercise 83

7.2 Solution and discussion 84

7.3 Common questions and answers 87

7.4 Commentary: analysis, design, and implementation 88

8 *Exercises—Implementing a design* 91

8.1 Create the classes 91

8.2 A test case 91

8.3 Write "new" methods 92

8.4 Write instance methods 92

8.5 Test your solution 93

8.6 Engineering discipline 94

8.7 A minor variation 94

8.8 "Private" methods 94

8.9 Commentary: getters and setters 95

8.10 Summary 96

9 *When (not) to inherit* 97

9.1 Historical background 97

9.2 Inverting hierarchies 98

9.3 Buy or inherit? 99

9.4 Exercise 100

9.5 Solution and discussion 100

9.6 Conclusions 102

9.7 Commentary: multiple inheritance 103

10 *Use cases and dynamic relationships* 105

10.1 Interaction diagrams 105

10.2 Exercise 108

10.3 Solution and discussion 109

10.4 Use cases and interaction diagrams in analysis and design 110

10.5 Limitations 112

10.6 Summary 113

10.7 Commentary: historical note 114

11 *The venerable model-view-controller* 115

11.1 Model-view-controller example 115

11.2 Exercise 118

11.3 How MVC works 119
<table><tr><td>11.4</td><td>Exercise: the original dependency mechanism</td><td>121</td></tr><tr><td>11.5</td><td>MVC: benefits and difficulties</td><td>122</td></tr><tr><td>11.6</td><td>What's become of MVC?</td><td>124</td></tr></table>

## 12 Building windows 127

<table><tr><td>12.1</td><td>What you need to know about Motif</td><td>128</td></tr><tr><td>12.2</td><td>Widget resources</td><td>130</td></tr><tr><td>12.3</td><td>Excursion: pool dictionaries</td><td>131</td></tr><tr><td>12.4</td><td>Exercise: a first window</td><td>133</td></tr><tr><td>12.5</td><td>Exercise: a window for the account balance</td><td>134</td></tr><tr><td>12.6</td><td>Exercise: a window for the transaction log</td><td>135</td></tr><tr><td>12.7</td><td>Exercise: a window containing both widgets</td><td>136</td></tr><tr><td>12.8</td><td>Assessment: building windows</td><td>136</td></tr><tr><td>12.9</td><td>Callbacks and events</td><td>137</td></tr><tr><td>12.10</td><td>Preparation</td><td>138</td></tr><tr><td>12.11</td><td>Exercise: mouse event handling</td><td>138</td></tr><tr><td>12.12</td><td>Challenging exercise: dynamic updates</td><td>139</td></tr><tr><td>12.13</td><td>Summary</td><td>140</td></tr></table>

## 13 Designing the UI: a brief tour 142

<table><tr><td>13.1</td><td>User interfaces</td><td>142</td></tr><tr><td>13.2</td><td>Elementary examples</td><td>143</td></tr><tr><td>13.3</td><td>Coherent conceptual models</td><td>144</td></tr><tr><td>13.4</td><td>Metaphor</td><td>146</td></tr><tr><td>13.5</td><td>Magic</td><td>148</td></tr><tr><td>13.6</td><td>Exercise: design a user interface</td><td>151</td></tr><tr><td>13.7</td><td>Discussion of your results</td><td>152</td></tr><tr><td>13.8</td><td>Isomorphism</td><td>155</td></tr><tr><td>13.9</td><td>Summary</td><td>156</td></tr></table>

## 14 Polymorphism 158

<table><tr><td>14.1</td><td>Dynamic binding</td><td>158</td></tr><tr><td>14.2</td><td>Dynamic binding enables...polymorphism</td><td>159</td></tr><tr><td>14.3</td><td>A word on terminology</td><td>161</td></tr><tr><td>14.4</td><td>Exercise: polymorphism</td><td>162</td></tr><tr><td>14.5</td><td>Solutions and discussion</td><td>162</td></tr><tr><td>14.6</td><td>Exercise: Smalltalk's if-less-ness</td><td>163</td></tr><tr><td>14.7</td><td>Solution</td><td>163</td></tr><tr><td>14.8</td><td>Summary tip</td><td>165</td></tr><tr><td>14.9</td><td>Commentary: performance</td><td>165</td></tr><tr><td>14.10</td><td>Commentary: Smalltalk, C++, and type-checking</td><td>166</td></tr></table>
14.11 Commentary: the tomato in the mailbox 169

14.12 Commentary: multi-methods 170

15 *Practicing polymorphism* 173

15.1 Design exercise I: a shape editor 173

15.2 Solution and discussion 174

15.3 Design exercise II: undo and redo 176

15.4 Solution and discussion 177

15.5 Implementing undo 179

15.6 Summary 180

16 *How object-oriented languages work* 181

16.1 Virtual machines 181

16.2 Method lookup 183

16.3 Memory management: a brief history of garbage collection 187

16.4 The irony of garbage collection 191

16.5 Commentary: why not garbage collect C++? 192

16.6 Smalltalk deviates from uniformity 193

16.7 Exercises 195

16.8 Summary 197

17 *Two kinds of inheritance* 198

17.1 Beauty and the beast 198

17.2 Why types matter: polymorphism 200

17.3 Commentary: an aside on subsets 201

17.4 Commentary: what does "consistency" mean? 201

17.5 Consistency and Smalltalk 207

17.6 Exercise: Smalltalk's container "types" 208

17.7 Solution and discussion 208

17.8 Exercise: Smalltalk's container "classes" 210

17.9 Solution and discussion 210

17.10 Summary 211

17.11 Commentary: standardizing Smalltalk 212

18 *Design patterns* 213

18.1 Notation 214

18.2 Smart container (aka collection-worker) 215

18.3 Reification 216

18.4 Command 217

18.5 Factory method 219

18.6 Objects from records 220
<table><tr><td>18.7</td><td>Proxies and ghosts, I</td><td>224</td></tr><tr><td>18.8</td><td>Proxies and ghosts, II</td><td>226</td></tr><tr><td>18.9</td><td>Dependency</td><td>228</td></tr><tr><td>18.10</td><td>Solitaire (aka singleton)</td><td>230</td></tr><tr><td>18.11</td><td>Duet (aka pas de deux, double dispatch)</td><td>231</td></tr><tr><td>18.12</td><td>Lawyer (aka object handler)</td><td>233</td></tr><tr><td>18.13</td><td>Composite</td><td>235</td></tr><tr><td>18.14</td><td>Visitor</td><td>236</td></tr><tr><td>18.15</td><td>Conclusion</td><td>239</td></tr><tr><td>18.16</td><td>Commentary: history</td><td>240</td></tr></table>

## 19 Frameworks (one hearty example) 242

<table><tr><td>19.1</td><td>Problems</td><td>243</td></tr><tr><td>19.2</td><td>Materialization</td><td>244</td></tr><tr><td>19.3</td><td>Managing object identity</td><td>246</td></tr><tr><td>19.4</td><td>Searching (filtering)</td><td>248</td></tr><tr><td>19.5</td><td>Updating</td><td>251</td></tr><tr><td>19.6</td><td>Summary</td><td>252</td></tr><tr><td>19.7</td><td>Commentary: varieties of brokers</td><td>254</td></tr><tr><td>19.8</td><td>Commentary: buying outdoes inheriting (sometimes)</td><td>255</td></tr></table>

## 20 Metaclasses 257

<table><tr><td>20.1</td><td>Facts about metaclasses</td><td>257</td></tr><tr><td>20.2</td><td>Inheritance</td><td>258</td></tr><tr><td>20.3</td><td>Method new</td><td>259</td></tr><tr><td>20.4</td><td>The full picture</td><td>260</td></tr><tr><td>20.5</td><td>Recapitulation</td><td>262</td></tr><tr><td>20.6</td><td>Exercises</td><td>263</td></tr></table>

## 21 Why developing software is still hard 264

<table><tr><td>21.1</td><td>Misconceptions</td><td>264</td></tr><tr><td>21.2</td><td>Where projects go awry: borders</td><td>267</td></tr><tr><td>21.3</td><td>Characteristics of successful projects</td><td>269</td></tr><tr><td>21.4</td><td>An optimistic conclusion</td><td>272</td></tr></table>

Appendix: Some differences between dialects 275

References 277

Index 283
Acknowledgments

This book derives from two activities—developing and teaching courses, and develop-
ing software. But the real sources are the people I’ve encountered along the way. Many
of them have profoundly shaped my thinking about software—Dave Collins, Peter
Deutsch, Amarjeet Garewal, Steve Goetze, Ralph Johnson, Doug Lea, Bertrand
Meyer, Tom Morgan, Dave Thomas, Rebecca Wirfs-Brock, and Kirk Wolf—and
many others have left smaller but chaotically important impressions: Bruce Anderson,
Marilyn Bates, Katherine Betz, Desmond D’Souza, Phil Hartley, Richard Helm, Felix
Laura, and John Vlissides. From here the list is too long to enumerate, for it includes
individuals with whom I sweated over their businesses’ real object-oriented design and
programming problems, plus all the students and instructors through the years from
whom I learned about teaching objects and Smalltalk and C++.

I am grateful to the many people who were kind enough to share their opinions on draft manuscripts. Bruce Anderson assailed hackneyed expressions and examples; Kent Beck made me rethink my pedagogical approach; Katherine Betz streamlined discussions; Michele Choate caught stylistic slips; Eric Clayberg taught me new things about Smalltalk; Dave Collins, a closet historian, set chronologies straight; Ken Coo- per pointed out awkward transitions; Lisa Goetze suggested improvements to the exer- cises; Steve Goetze was a sounding board for impetuous ideas and, sensitive to the zeitgeist, warned me off gratuitous soapboxes; Ralph Johnson’s enthusiasm and tact kept me going when there was still no end in sight; Doug Lea urged technical respect- ability where there was none; Ruth Liu distinguished what I actually said from what I meant to say; Tom Morgan flushed out structural and conceptual flaws; Larry Smith was the conscience of the IBM Smalltalk product; Dave Thomas alerted me to trends from the ANSI standardization effort; Michael Tsuji painstakingly and repeatedly dis- sected the entire manuscript from the standpoint of someone who professed to be ignorant of objects, and so highlighted innumerable spots where readers would have gone astray; and Kirk Wolf’s razor-sharp sensibilities caught sloppy assertions about objects. Kim Arthur, David Bernstein, Wai-Mee Ching, Bill Creager, Amarjeet Gare- wal, John Granlund, and Greg Lee also provided helpful comments. For felicitous
anecdotal tidbits, I am grateful to Kent Beck, Roy Campbell, Dave Collins, Erich Gamma, Tami Kinsey, Hal Lorin, and Kirk Wolf.

Thanks also to the unsung heroes of the publishing world: Tommy Barker, Steve Brill, Lee Fitzpatrick, Leslie Haimes, Ted Kennedy, Mary Piergies, and especially Marjan Bace for his guidance on the care and feeding of a book; Dave Lynch for his illuminating and provocative copyediting; and Sheila Carlisle for the care and precision with which she transformed the raw manuscript into an attractive form. I also thank IBM for giving me time to begin this project. Neither they nor I imagined it would take so long.

Everything owes something to root causes (had it not been for such-and-such, this-and-that would never have happened). Thus I, and every practicing object-oriented programmer, am indebted to Alan Kay and his associates at the Learning Research Group at Xerox PARC for inventing Smalltalk, and Bjarne Stroustrup for giving us the C++ counterpoint. The dialectic between these schools of thought inspires much of what follows.

CHAMOND LIU
Clarity Computing

<figure><img src="image_1.png" /></figure>
Preface

This book is about Smalltalk and objects, in more or less balanced measure. By this I mean that there is ample Smalltalk to expose and crystallize in the reader's mind all the important object-oriented design ideas, and not so much as to distract from them. Smalltalk is an excellent vehicle for this task because it is small and simple enough that learning about it intrudes as little as possible on learning about design. Yet it is rich enough to precisely clarify what can otherwise degenerate into academic discussions.

By no means is this an advanced book, on either Smalltalk or objects. I have strived to stick to the matters that seasoned Smalltalk developers are fully aware of but consider too obvious to explain. These matters range from what today would be deemed elementary ("What do I mean by an object?") to sophisticated ("Can I reuse a pattern of objects?"), but mostly reside somewhere in the middle ground. I think back to how long (too long) it took me to internalize all these "obvious" matters and imagine that some well-placed explanations along the way could have saved me a good bit of trouble. I hope to save some of you that trouble.

One can't talk about objects and Smalltalk without also talking in practically the same breath about design. "Design" is a word that all computer people know, yet many still disagree about its meaning, or what it produces, or when it begins and ends. For the purposes of this book, to design is to discover alternatives, weigh them, and consciously choose among them. Design, like life, is all about striking the right balance. In this sense of design, we are liable to be designing even at moments when our job description says we are doing something else entirely: we may discover design alternatives and weigh or reject them while we are doing object analysis or modeling, writing code, or peeling carrots.

The goal is to design more like veteran software developers do. They choose among alternatives quickly and subconsciously, drawing upon years of experience, something like chess grandmasters choosing among moves. Lacking this experience, novices have a hard time discovering plausible alternatives, and an impossible time discovering subtle ones. For their sake then, I often argue alternatives and the trade-offs between them, so that they will have an outside chance of considering the same design alternatives that the veterans do.
The approach is not encyclopedic. Absent are systematic tours through class libraries, discussions of the visual programming or collaborative development tools that are available for Smalltalk environments, and discourses about notations and methodologies. Notations are as capable of obscuring ideas as they are of elucidating them, so the few that appear are deferred until they become indispensable to the presentation. If it is not already clear, let me also issue the explicit disclaimer that this is not a catalog of Smalltalk tricks and techniques.

Smalltalk is not the only way to think about object-oriented software. C++, the most widespread object-oriented language, contrasts sharply with Smalltalk in so many ways that awareness of C++ enriches the overall object-oriented experience. Therefore I include remarks about C++ whenever they may enhance your appreciation of objects.

For those new to objects, reading the chapters in order will make most sense. On the other hand, because of my own weakness for selectively reading portions of books, many chapters are relatively independent and accessible without having to digest everything that comes before. Thus, you can pick chapters and sections according to your background and goals, and if you encounter some you can't (or don't want to) crack, leave them and return later. It is even plausible to plunge immediately into Smalltalk (Chapter 3), referring to the first two chapters only as needed.

The examples are all as simple as possible, because the simplest things form the clearest and most surprising lessons. Exercises appear irregularly, whenever understanding the topic at hand demands active participation. There is a blend of design exercises and programming exercises that require a Smalltalk workstation. Solutions accompany the meatier design exercises, but of course even for exercises with solutions I recommend you try them first on your own.

The programming exercises are written on an IBM Smalltalk base. You can work them on either the Professional or Standard version of IBM Smalltalk or VisualAge. Most of them are generic enough that they, or variations of them, can be made to work for other dialects of Smalltalk, but only ambitious readers should attempt to do so. A few small hints for such readers appear in the Appendix. The exercises on windowing are a notable exception: interpreting them into other dialects will be beyond the means of even the most determined reader. Every dialect has its own event and windowing protocols, so building windows in other dialects is a wholly different experience.

Learning occurs differently in different people. That is why diversions—I call them “commentaries”—are separated out for some readers to blow by and others to dive into, according to their fancy. These diversions are variously technical (like comparisons with other ways of doing objects, particularly C++), historical, or philosophical.
When you finish the book, I hope you will be able to think about software problems in some of the ways that the veterans do, and be able to implement your thoughts in Smalltalk. Not expertly, however. Mastery of both object-oriented design and Smalltalk comes only with actual practice. Of course, these are truisms for any activities, from driving a car to playing the piano. But Smalltalk, more than most software tools, requires you to plunge in and abandon yourself to the language and environment. A taste for adventure definitely helps, more than in learning how to drive a car.

## Notes on the organization

This is not an orthodox book. Much of its structure derives from my experiences in sustaining the eagerness and momentum of typical Smalltalk beginners for thirty-six or so hours a week, making sure that they learn some really important things. For example, polymorphism does not appear as a formal topic until Chapter 14, not because it is the fourteenth most important topic, but because students have matured enough by then to get an adrenaline rush from it.

You will not find a predictable or monotonous rhythm. People learn best when they sometimes sweat and program in the depths of Smalltalk proper, and at other times sit back and reflect on how ideas interconnect. One chapter (4) consists entirely of hands-on exercises, but on balance the book is weighted more toward thinking than coding.

Here, then, are a few alerts about the content.

The first fifteen chapters cover the basics, material that every practicing developer absolutely must know about objects in Smalltalk. The first two chapters establish a groundwork of objects, classes, and inheritance in a way that is meant to be completely reassuring. All nuances, paradoxes, and the like are reserved for later.

Chapter 3 is practically the only "language" exposition in the book. It covers probably 95 percent of the Smalltalk language and also forewarns readers of common gotchas. Chapter 4 is a concentrated opportunity to practice the lessons of Chapter 3 as well as many more essentials. You should surface from it with a sound intuition of what it's like to live in a Smalltalk programming environment. The orthodox approach is to spread this material around at least a little, but Smalltalk has so few facts and laws that it is feasible to get the bulk of them out of the way in this one fell swoop.

Chapters 5 and 6 begin the assault on major object-oriented conceptual matters, namely abstract classes, containers, and object identity. The next two chapters, 7 and 8, pause to tackle the nuts and bolts of designing and implementing a basic application. Chapters 9 and 10 resume the discussion of ideas essential to the sound practice of objects. This material questions, among other things, when inheritance produces the right design.
The next three chapters, 11 through 13, form a unit on the topic of user interfaces. They begin with an obligatory discussion of model-view-controller, continue with Motif programming (which is specific to the IBM dialect of Smalltalk), and conclude with how not to make a mess of the user interface. This final chapter in the unit is unusual for a book on objects. It is an attempt to emphasize the connection between objects and user interfaces and confront heads-down programmers with the moral obligation to do it justice.

Chapters 14 and 15 expound on polymorphism from several angles, enough to browbeat everyone into internalizing its value and applicability. These chapters fit- tingly conclude coverage of the essentials, the omission of any of which would be a major embarrassment for me and you.

Chapter 16 demystifies the workings of method dispatch, storage management, and the like, mostly emphasizing Smalltalk, but contrasting with C++ for the sake of perspective. The purpose is not so much academic as to demonstrate how these con- trasting workings influence the development gestalt of an object-oriented language.

Chapter 17 should raise your consciousness about the two distinct rationales for inheriting, which I call beauty and the beast. Sensitivity to this issue is an earmark of mature object-oriented designers. The chapter includes a lengthy discussion of consis- tency (page 201), bordering on the philosophical, which is probably the headiest sec- tion in the book.

Chapter 18 covers some favorite design patterns, and how to realize them in Small- talk. Because it ties together so many ideas, it should reassure you that you have actu- ally learned something, because you will understand the patterns if and only if you’ve been conscientious about all the programming and thinking that have gone before.

Chapter 19 illustrates what object-oriented frameworks are and why they matter by way of one concrete client/server framework.

Chapter 20 is another demystifying chapter, and the most optional one in the book. I discuss the basics of metaclasses (a class’s class) from the standpoint of what they buy the programmer, as well as the extraordinary lengths to which Smalltalk goes to preserve a uniform view of objects. Metaclasses are the final technical topic in the book, and are positioned last because the reader needs to have thoroughly internalized Smalltalk’s conceptual underpinnings before appreciating them.

The book concludes with a subjective assessment (Chapter 21) of what is wrong and right with typical object-oriented development efforts.
## *Typographical conventions*

Boldface type, as in *MyClass*, indicates Smalltalk names and code. Italics indicate emphasis and also special instructions, like picking the *Display* menu item. Text that would appear on a computer screen is in bold italics, as in *Here is the result*.

In keeping with a spirit of candor, no attempt has been made to homogenize the appearance of screen shots of Smalltalk browsers. Browsers vary from dialect to dialect, of course, but also within a dialect (e.g., the standard and Trailblazer browsers in IBM Smalltalk). For that matter, they can even be customized to display or suppress information, according to the whims of the programmer. Rather than present a façade of consistency, the browsers you will see are the ones that I happened to be using at the time.
CHAPTER 1

Objects

The central idea in object-oriented programming is, of course, the programming
object. This opening chapter explores this idea, and along the way introduces just a
little Smalltalk. But don't get caught up in the details of the Smalltalk fragments here;
their purpose is to illustrate concepts.

1.1 Objects

<figure><img src="image_2.png" /></figure>

A programming object has some operations plus some
information. We often portray programming objects
as "doughnuts," as in this drawing of a bank account
object on the left. If you—a "client"—want to use this
object, you are aware of three operations that it ought
to be able to do: tell you its balance, withdraw some
money, or deposit some money. That's it. In fact, you
don't even get to know that $150 are ensconced within

the object. That information is held *privately* within the object, inaccessible to your prying eyes. Thus a more accurate picture of your point of view is as shown below.

We can define a programming object as having
an outside, consisting of the operations you can ask
of it, plus an inside, concealing information from
you that may nevertheless be used by the object's
operations. You can see the outside, but not the
inside. The software engineering term for this idea is
*encapsulation*: the inside of the object is encapsulated

<figure><img src="image_3.png" /></figure>
by the object's operations. As a rule, data are inside and operations are outside. (We will see occasions when this rule is not what we want, but for the time being it is a good rule of thumb.)

If it happens that you really want to know about the inside of an object, like the account's balance, you can hope to get it only indirectly, by using one of the object's operations. In this example, one hopes that, by invoking the **balance** operation, the object will respond by announcing that it contains $150. Notice the notational quirk: **deposit**: and **withdraw**: are followed by colons, but **balance** is not. This is a Smalltalk idiosyncrasy. It's a convenient way to indicate that an operation requires an argument—when you deposit or withdraw money from an account, you specify an amount; when you ask for the balance, you don't.

Another way to conceptualize a programming object is to think of it as a little person: You can ask this little person, this *homunculus* (from the Latin, *man* + *little*), to perform any of his operations, but you haven't any idea how he actually implements them, or what he uses from his own insides to do them. When you're designing an object's operations, you should not be embarrassed to think of the object as a little person and wonder, "What ought a smart little account object be capable of?"

<figure><img src="image_4.png" /></figure>

This blatantly anthropomorphic question sounds like a cheap trick. But metaphor—I include imagery and simile and analogy—is a powerful cognitive tool. Metaphors let you use what you already know about one domain (like people) to clarify your thoughts about a less familiar domain (like banking software). This device encourages you to say things like, "An account ought to be smart enough to hand out money or tell me how much money he has." As a matter of fact, the idea of a programming object in the original Smalltalk, Smalltalk-72, was a metaphor for a biological cell [Kay 1988]. Imagery like this may not measure up to, "Shall I compare thee to a summer's day?" but you get the idea [Shakespeare 1609].

Now that you understand what objects are, let's develop some ways to think about using them. When you "ask" an object to perform one of its operations, you send it a *message*. Now, everyone cavalierly assumes they understand what a message is, which is a sign that they haven't thought much about it. The trouble is that "message" connotes many ideas. (An e-mail message? A whisper? The thing on my answering machine? A Post-it? A TCP/IP packet?) "Message" is too abstract a word. A better word is *telegram*. A "telegram" is tangible: I can touch it, I can see the information it carries, and I can picture the moment it arrives at the door of its addressee. It is not some vague electronic-sounding thing like a "message." Therefore, I encourage you to think of an old-fashioned telegram whenever you see the term "message."
A message has a bundle of information, consisting of the operation's name and any arguments it needs. For example, to withdraw $50 from the account object, you'd send a message (or telegram)—**withdraw: 50**—to it.

<figure><img src="image_5.png" /></figure>

The account object, which has been dormant, awakens and promptly starts executing its **withdraw**: operation. All kinds of interesting things could now happen, producing all kinds of effects. For instance, the account object could in turn send messages to other objects, perhaps with the effect of appending to a report for the bank's auditors. Or, maybe nothing much interesting happens, other than that the $150 concealed within the account object drops to $100. Eventually, though, the account object finishes executing **withdraw**, and returns an object to you. Maybe it's a receipt object. Whatever it is, it's what you've been waiting for. You sent the message, and you expected some result, and now that you've got it, you're ready to do something else.

To reiterate: in Smalltalk, the normal result of your firing a message is always that some object is returned to you. The returned object may even be uninteresting to you, but you always get one, whether you need it or not. You should think of the consequences of any message as twofold: first, something happens—the operation has an effect—and second, at the end of execution, some object is returned. Remember, an *effect* plus a *return*.

Here are some pretty straightforward candidates for programming objects:

* A bank account, as we've just seen, with operations for depositing, withdrawing, and querying the balance.

* A dictionary, with operations to add or remove entries, or update them.

* A window in a user interface, with operations for displaying, resizing, moving, and so on.

(Some languages from the early 1980s have special syntaxes for defining programming objects like these. For example, one could use a *package* in Ada or *module* in Modula-2.)

A more unusual prospect for a programming object is an integer, like 7. Smalltalk embraces a principle: "Everything is an object." So Smalltalk, unlike other object-oriented languages, insists that integers are objects, too. This statement may sound harmless enough, but it will challenge our customary understanding of arithmetic.
Consider an expression like:

$$7 + 4$$

We expect a result of 11, and we expect that reversing the order thus:

$$4 + 7$$

produces the same result. We've been trained since elementary school to expect this expression to behave in this symmetric fashion. Some of us recited slogans like "addition is commutative" to describe this symmetry. We were studying *addition*, and we concentrated on the plus sign.

The object point of view has a different emphasis. That is, if the integer 7 is to be an object, then the focus is going to shift; 7 will be much more interesting and the plus sign much less so. Here's what happens:

<figure><img src="image_6.png" /></figure>

The message, + 4, strikes the 7 object, whereupon the plus operation executes and eventually returns 11, another integer object. Note that the symmetrical feeling you had in elementary school is absent. Instead, the 7 object plays a leading role. It's a homunculus that's clever enough to respond to messages, such as the one labeled + 4. It recognizes + as one of its operations, and it also expects the + to be accompanied by an argument, which in this case is 4. It executes the operation, and eventually returns the object 11 to whomever sent the message. Fortunately, this is the same answer we got in elementary school. But the line of reasoning we used to get it is unlike anything we learned in elementary school. The symmetry is gone, and the center of attention has shifted from the operation (+) to the object (7).

A lot of people find this model of arithmetic distasteful. One of my outspoken friends, who isn't a Smalltalk programmer, denounces schemes like this as conspiracies from the "lunatic fringe" (a label Smalltalk's critics in the early 1970s also used). The only redeeming virtue seems to be consistency: integers, along with bank accounts and dictionaries, are just another kind of object, activated by messages just like the rest. As you hear more about Smalltalk, you'll recognize that Smalltalk is one of the most stubbornly consistent software systems around, whether one likes it or not. Everything will be an object.
Before leaving this lunatic-fringe discussion, what about the argument 4? I men-
tioned that the 11 that's returned is also an (integer) object; is the argument also an
object? Yes, absolutely. Arguments as well as return values are objects in Smalltalk.
Everything is an object.

Now, there is one conceptual distinction between an object like an integer and an
object like a bank account. Think about the inside of the 7 object. Should it change
after the telegram + 4, as the balance inside a bank account changes after the telegram
withdrawal: 50? For that matter, what *is* inside an integer object? Well, think of the
inside as a special *7-ness* quality—the precise bits and bytes don’t matter. This quality
is what makes 7 respond to + 4 with 11 rather than, say, 13. No one else has such a
quality. This 7-ness never changes; later on if we send 7 the telegram + 19, we trust
that it will respond with 26. Objects like integers are *immutable*—they never
change—in contrast with *mutable* objects like accounts, whose insides may change.

1.2 Examples of Smalltalk messages (telegrams)

In Smalltalk, the usual rule of thumb is to parse expressions from left to right. Consider:

9 talk

This syntax differs from that of most programming languages. It means that I'm firing
a message named **talk** to the object **9**. Parsing from left to right, the object comes first,
followed by the message that it receives. What happens next depends entirely on
whether and how integers have been programmed to respond to requests to talk. For
example, in my demonstration Smalltalk system, the result of *executing* 9 **talk** is the
following text on my screen: *Hello, I am one more than 8*. Another example with the
same syntax is:

4 factorial

From left to right, I'm asking the 4 object to calculate its factorial, that is, 4*3*2*1. If
I ask Smalltalk to *display* the result, I'll get 24. (I'll discuss the distinction between *exe-*
*cuting* and *displaying* in the next section.)

This example should be familiar from the discussion of the preceding section:

6 * 7

From left to right, 6 receives the message * 7. If I ask Smalltalk to *display* the result, we
will see 42. This left-to-right rule can cause surprises; about half of Smalltalk novices
guess the wrong answer to:

5 + 6 * 2
The correct answer is 22, not 17. Why? Proceed from left to right. The 5 object receives a request for its `+` operation, namely the `+ 6` message. The result, which is the 11 object, in its turn (left-to-right), receives a request for its `*` operation, namely the `* 2` message. And it (the 11 object) responds with the final result, the 22 object. For the first time we have an example of something in Smalltalk that differs plainly from what we learned in school. Like it or not, that's how Smalltalk works. Of course, if I really want to get the answer 17, I can use parentheses to change the precedence of Smalltalk's parse:

`5 + (6 * 2)`

The next example requires a little guesswork:

`'turnip' reversed`

Proceeding from left to right, the first element, `'turnip'`, is the object that receives the message. Because of the single quotes, it is reasonable to surmise that it is a character string. The message apparently asks it to reverse itself. If we ask Smalltalk to `display` the result, Smalltalk will display the characters of the original string spelled out in reverse order: `'pinrut'`.

This one has a different form than the others:

`HomeBudget spend: 229 on: 'VCR'`

The object on the left appears to be something that manages home accounting and inventory. The message is less obvious. A colon, you recall, signals the presence of an argument. But two colons? Smalltalk's parsing rule for this situation is to treat all the colons and their arguments together as a single message. Thus, `spend: 229 on: 'VCR'` is a complex bundle of information packaged in one telegram aimed at HomeBudget. Evidently, the telegram (message) informs the object of a purchase of a new VCR for $229. In my system, if I ask Smalltalk to `execute` this expression, Smalltalk responds with: *You bought a VCR and you are poorer by 229 dollars.*

## 1.3 Pitfall: the effect versus the return

Notice the distinction between what an operation does—its *effect*—and the object it chooses to return to its invoker. Depending on the situation, you may care more about one than the other. Sometimes the name of an operation suggests that it's the effect that matters:

`7 storeOn: someFile`

This expression looks like it has the effect of placing the 7 object out on a disk, in a file the argument `someFile` refers to. This effect is apparently the purpose of the message;
what the object returns to the sender is irrelevant. Sometimes, part of the effect is to explicitly display feedback to the screen, as in the example, **9 talk**, in the previous section. We don't care what object **9 talk** returns; whatever object it is is irrelevant.

On the other hand, the opposite may be true. In:

### 7 factorial

we don't care about the effects that occur while **factorial** does its calculation. We're much more interested in the object it flings back at us when it's done, which happens to be 5040. In this case we want to see the *return*, not the *effect*.

You can specify whether you want Smalltalk to display the *return* or not. That's the finicky distinction between *displaying* and *executing* in the preceding section. If you *display* an expression, the effect occurs *and* Smalltalk displays the returned object on the screen. If you just *execute* the expression, the effect occurs but Smalltalk ignores the returned object. For the examples so far, you have to trust my choices of *displaying* or *executing* because you haven't seen the code that implements each operation. The names of operations may suggest what their effects and returns are, but the only way to be sure is to read their code. In Chapter 4, you'll work through exercises that will help keep the distinction straight.

## 1.4 Why objects matter

When all the rhetoric is set aside—the rhetoric about reusability and productivity and so on—the salient characteristic of objects is that they reduce translation. That is, objects promote a common vocabulary: everyone, whether a software professional or not, has some intuitive understanding of what an object is. Thus we can understand one another more easily when we use objects to describe our thinking. Objects, then, promote mutual understanding—between users, analysts, executives, designers, programmers, testers.... They reduce the effort of translating one person's thoughts to another's, and therefore reduce misunderstandings as an idea passes from one person to the next.

As for reuse and productivity, they are nothing more than side effects of better understanding. It is more important to concentrate on clear objects than on the side effects; unless the objects are clearly understood, they will be neither productive nor reusable. Concentrate on clear objects and you will eventually produce reusable ones; concentrate on reusable objects and you will produce muddled ones. In this light, the goal of this book is to clarify and deepen your understanding of objects, which in the end will deepen your ability to understand and be understood by other people in the software enterprise. And that is the source of the economic value of objects.
## 1.5 Recap: objects

Programming objects appeal to different people for quite different reasons. Right brain, intuitive individuals appreciate their metaphorical power. For example, the object-oriented customer-information system at Brooklyn Union Gas Company<fnref n="1" /> has gas meter and bill objects, exactly analogous to gas meters and bills in the company's real problem domain. To design gas meter software, developers imagine real gas meters. This expedient helps them reason about programming objects in ways they are already familiar with from their everyday experience; it reduces the gap between the problem (billing for gas service) and the solution (programming). This cognitive economy—breaching the gap between two domains—is the essence of metaphor.

Meanwhile, left-brain, analytic individuals are drawn to the software engineering benefits of objects. If software consists of objects, which are by definition encapsulated, then their insides can be improved without affecting their outsides, and therefore without affecting the rest of the system. Problems are more easily isolated to specific objects and fixed, and the system is generally more tolerant of change, more malleable. In short, modularity in software is desirable, and objects provide a level of modularity beyond traditional structuring techniques.

One other inherent characteristic of objects deserves mention. Traditional software structuring techniques concentrate first on *function*—the function of a program, its sub-functions, their sub-sub-functions.... But human cognition often works the other way, recognizing *things* first, and the functions that connect them afterward. For example, upon hearing that the neighbor's dog bit the mail carrier, I conjure up a picture of the two antagonists first, then a moment later, the dog's jaws closing on the victim's leg. I don't conjure up an abstract bite first. Since our minds are naturally practiced at thinking about *things* in the everyday world, why not parlay that practice into the software world? This is what objects do for us programmers.

To summarize the machinery available so far: if I have programming objects, I can build software out of them, as shown in the diagram on the right. Unfortunately, this software doesn't have much structure—it's just a chaotic bunch of communicating objects. In the next chapter we'll enrich the picture by way of structuring principles—classes and inheritance.

<figure><img src="image_7.png" /></figure>

<footnote n="1">¹ This landmark project, deployed in 1990 under the leadership of Tom Morgan, is noteworthy for being the first large-scale object-oriented mainframe application. See [Davis and Morgan 1993].</footnote>
## 1.6 Exercise: warmup (the image)

Generally, the *image* is the file that contains all the objects you use and create, as well as other critical Smalltalk objects. By starting Smalltalk you activate the image, and all these objects, of which there are tens or hundreds of thousands, spring to life, ready to work when asked. In IBM Smalltalk, the default name for the image file is simply *image*.

* Once you have installed Smalltalk, make some provision for disaster recovery. The minimal provision is to copy your image file to a backup file of your choosing.

* Start Smalltalk by double-clicking on the icon for Smalltalk or VisualAge. If you've never used a cut-and-paste editor, take a few minutes to practice with Smalltalk's. Type a line of text in the *System Transcript* window and figure out how to:

* Split it and rejoin it. (Hint: try the <enter> and <backspace> keys.)

* Copy a portion of it to another place in the same window.

* Move a portion and delete a portion.

* In the transcript, type the following lines, highlight them one at a time, and *display* the resulting object:

```
4 factorial
6 * 7
5 + 6 * 2
5 + (6 * 2)
'turnip' reverse
```

You are now operating with objects in the image.

## 1.7 Commentary: perspectives on objects

The metaphorical character of a programming object (page 2) dates back at least to the pioneering work of Alan Kay at Xerox PARC (Palo Alto Research Center) in the early 1970s. Not everyone agrees that metaphor is valuable in programming. In a 1989 paper, the eminent computer scientist Edsger Dijkstra, father of structured programming (or at the very least, executioner of the GOTO statement), ridiculed the use of analogy and metaphor and advocated purely formal thinking in their stead. His paper set off a firestorm of impassioned rejoinders [Dijkstra et al. 1989].

Research on invention and creativity suggests that imagery, not formal reasoning, fuels the creative process. The study by mathematician Jacques Hadamard includes a response from Albert Einstein that makes this point clearly [Hadamard 1954].
Having found an apt metaphor, one must take care not to let it limit the imagination, either: although the spreadsheet was inspired by an accountant's ledger sheet, it transcended the capabilities of a real ledger sheet. Alan Kay calls this step the "magic" of going beyond a metaphor [Kay 1990]. For the use of metaphor and magic in user interfaces, see Chapter 13.

A complementary property of objects, even a corollary of the anthropomorphic view, is their *autonomy* [de Champeaux et al. 1993; Collins 1995]. Autonomy implies that objects are likely to act independently, which in turn implies that they may act concurrently. Concurrently executing objects are also a natural consequence of the biological metaphor of cells acting concurrently by the billion [Kay 1988]. Although some languages mix concurrency and objects, no consensus exists on a proper model for the two. In practice one usually builds concurrent objects on top of the same facilities that non-object systems use—semaphores or other low-level operating system services. For samplings of research approaches to the problem, see [Yonezawa and Tokoro 1987; Agha et al. 1989; Agha et al. 1991; Briot 1992; CACM 1993].

The contrast between function on the one hand and data on the other leads to two polar approaches to software design, namely, traditional functional decomposition (dating from the 1960s) and data-driven or entity-relationship decomposition (dating from the 1970s). Objects occupy a middle ground; they have the tangibility and data content of an entity, but their outsides are defined by their function or behavior. This synthesis of data and function is what differentiates object-driven approaches from the others.
CHAPTER 2

Classes and inheritance

The previous chapter hinted at the cognitive and programming potential of objects. To fulfill this potential, we need to organize them in our minds. We need two structur› ing principles: classes and inheritance.

2.1 Classes

How do you create objects? In some languages you have to build them one at a time, but it’s more convenient to have a mechanism that produces them for you. This mech› anism is called a class .

You can think of a class as a factory that can produce programming objects. Each factory makes just one kind of object, or product. For example, we could have a BankAccount class, from which we produce bank accounts, a Menu class, from which we produce menus for a user interface, or a Dictionary class, from which we produce objects that behave like real dictionaries.

In Smalltalk, here’s how you might use a Dictionary class:

Dictionary new

Left to right, Dictionary receives the message named new . Because Dictionary is a class or factory, it responds to new by creating a brand-new dictionary object. What happens to this object from now on is up to you. Being a dictionary, it may have oper› ations like add : that would permit you to add a new entry to it. You could gradually add to it and make it into any kind of dictionary you liked.

Realistically, if we want to continue to use this dictionary object, we should establish a handle by which we could refer to it. That is, we would use a variable name, like X :

X := Dictionary new
The `:=` is Smalltalk's assignment. It means that we want to assign the result of **Dictionary new** into the variable X. Assignment is an exception to the left-to-right rule. First, Smalltalk does what's to the right of the assignment (**Dictionary new**), then it assigns that result into the variable to the left (X).

We can now add things to the dictionary by referring to it as X:

X add: ...an entry...

and

X add: ...another entry...

If we need another dictionary, we can just execute:

Y := Dictionary new

X and Y refer to two distinct dictionary objects, but they come from the same class, namely **Dictionary**. And having come from the same class, or factory, they behave similarly. They both support operations appropriate for dictionaries, like adding, looking up, or removing entries. We can use these operations to grow them in much different ways—X into a Danish dictionary, perhaps, and Y into a Portuguese one.

In object-oriented systems, dictionary objects are widely used to associate one kind of information with another. Many dictionaries are present in Smalltalk (that is, in Smalltalk's image—page 9) before you even begin to use it; you won't even be aware of most of them. One of them, the *system dictionary*, is Smalltalk's central object. It records associations between variables and the objects they refer to. For instance, after Smalltalk executes:

X := Whale new

the *system dictionary* contains an entry for X associating it to the actual whale object. There are hundreds of other dictionaries in a live Smalltalk image; they hold all sorts of associations—character names to their numeric values (like 'XKunderscore' to 95), mouse events to window system event numbers (like 'WmButton1down' to 113), and so on. These dictionaries are crucial to running Smalltalk, but mostly operate unbeknownst to you.

In a language like Smalltalk that has classes, objects are not individualistic. Those from the same class have the same operations—their behavior is the same. We can indicate that objects are from the same class by enclosing them in a box. This representation is less chaotic than our picture of objects at the end of Chapter 1 (page 8); the software is more organized. We will soon give it even more organization, when we discuss inheritance.

<figure><img src="image_8.png" /></figure>
## 2.2 The word “class”

“Class” is a mismeaning word because it has meanings that predate object-oriented programming. Schoolchildren are commonly taught to use “class” as a synonym for “set.” Mathematicians, on the other hand, use “class” to refer to collections that were found nearly a century ago to be too large to be treated as sets. (An example of such a collection is the “class of all sets.”)

Of course, both the schoolchild and the mathematician have at the back of their mind some notion of a collection of entities. For object-oriented developers, however, the better conceptual model for a “class” is a *factory* rather than a *collection*. (Not that it’s a crime to lapse into convenient expressions like “this object belongs to that class,” so long as you remain aware that you really mean that “this object was created by that class.”) Inexperienced designers who think of class **Onion** as the collection of all onions run into trouble when they have to partition onions into those on the grocer’s shelf versus those in a shopping basket; they attempt to invent more classes (**Shelf-Onion**, **BasketOnion**,...) when what they really need are containers (shelves, shopping baskets,...) to hold their onions. More on containers in Chapter 6.

Another word that is often confused with “class” is “type.” To casual object-oriented programmers, they are synonymous. Indeed, for many discussions, there is no harm in using the words interchangeably. But in fact types are *not* classes, and we will see later (Chapter 17) why it is perilous to assume they are. Until then, it would be pedantic to fuss over the distinction, and we will suffer little harm by occasionally saying **Onion** is a “type” instead of a “class.” (The terms *abstract data type* or *data type* also occur in software-engineering discussions. They are synonyms or near-synonyms of “type,” but they and their nuances won’t concern us at all in this book.)

## 2.3 Inheritance

Inheritance, our second structuring principle, means that you may specify in your programming language that a class is a special kind of another class. It’s a notion that we all studied in school. The picture at the right meant that an insect is a special kind (“specialization”) of animal, that a butterfly is a special kind of insect, and so on. We called the study of hier-

archical pictures like this *taxonomy*. Object-oriented programmers say that the picture depicts a hierarchy of classes in which **Butterfly** is a *subclass* of **Insect**, or equivalently, **Insect** a *superclass* of **Butterfly**. They also commonly say that **Butterfly inherits** from

<figure><img src="image_9.png" /></figure>
**Insect.** People who work in artificial intelligence sometimes call this relationship *AKO*-A-Kind-Of. **Butterfly** is AKO **Insect**. Whatever the terminology, the underlying idea is the one we learned in school, that of classifying things by increasing degrees of specialization.

The botanist Carl von Linné, better known as Linnaeus, popularized this way of thinking about plants (as well as animals) in the eighteenth century. Nowadays, children take the idea for granted; they think the taxonomy of plants and animals is just a tedious academic exercise. But back then, the idea extended the very way in which people could think about the world. For example, if I connect butterflies with insects, I establish a mental crutch that helps me *reuse* knowledge I already have about insects. Everything I know to be true of insects automatically applies to butterflies—six legs, egg-laying, metamorphose, breathe through holes in their bodies.... All I had to do was stipulate that a butterfly is a kind of insect (or say “inherits from” or “is a subclass of”). That’s a lot of cognition to get free, or for the small price of stipulating an AKO relationship.

Now let's apply this idea to Smalltalk. Part of Smalltalk's inheritance hierarchy looks like this:

<figure><img src="image_10.png" /></figure>

Class **Float** (floating point numbers) is a special kind of **Number**. So too is class **Integer**. Everything that's true of a **Number** object (we can add them, multiply them, and so on) is also true of a **Float** or **Integer** object. It's the same idea as the Linnaean biological taxonomy, only this is a taxonomy of classes in Smalltalk.

Class **Object**, the highest class in the diagram, is analogous to class **Animal**. Just as everything in the Linnaean picture is a kind of **Animal**, everything in Smalltalk is a kind of **Object**. This diagram legitimizes the expression, "In Smalltalk, everything is an object." And just as **Animal** is quite abstract, with few specific qualities, **Object** is similarly abstract.

The other classes in the diagram all have intuitive meanings, with one exception. What role does class **Magnitude** have? Start by thinking about its subclasses. Whatever is true of **Magnitude** objects must also be true of **Date**, **Number**, and **Time** objects. In other words, to imagine what **Magnitude** objects do, you should look for whatever behavior dates, numbers, and times have in common. Try not to think about the insides of these objects. Think about behavior—the outside of the object—rather than the internal, private way in which the object's data happen to be stored. Remember that behavior, the outside, is what matters to users of an object. What behavior do dates, numbers, and times all have?
Here are some bad guesses: multiplication and addition. Although it's reasonable to multiply two numbers together, it's unreasonable to try to multiply two dates, like July 4, 1776 and October 14, 1066. Similarly, addition makes sense for numbers, but we aren't interested in adding 3 o'clock and 2 o'clock, or July 4 and October 14.

Nevertheless, something about dates, numbers, and times is similar. What? Not arithmetic, as we've just determined. What about the sense of order? Dates are ordered, as are numbers and times. But we would have to express this idea in terms of behavior, or operations. How? Why not comparison operations, like > (greater than) or <= (less than or equal to)? A date may be greater than another date, a number greater than another number, or a time greater than another time. These comparisons then are the operations that the subclasses have in common. We'll simply place them in the Magnitude class, instead of replicating them in all three subclasses. The subclasses then inherit them. Instant code savings.

It's a great, Linnaean idea, but in real object-oriented systems, there's sometimes a catch. The subclasses might still have to have their own version of some of the operations, because the code for the operations is likely to depend on how the data inside the object are represented, and this representation could well be different for different subclasses. For example, because the bit conventions used to store floating point numbers are different from those for dates, the code that compares them must be different too. We will deal later with this situation. For now, staying at a conceptual level, let's just celebrate having factored the concept of comparison out of the three subclasses and into their Magnitude superclass.

This discussion illustrates a simple guideline about taxonomy, hence about object-oriented design. Whenever you sense commonalities between classes of objects, consider defining a superclass and "factoring" the commonality out of the subclasses and into the superclass. That's what the Smalltalk-80 designers did late in the 1970s to Date, Number, and Time, and their decision has proved so durable that the design occurs today in all commercial Smalltalk systems.

The little hierarchy under Object and Magnitude is just a part of Smalltalk's class hierarchy. The full class hierarchy includes classes for windowing, the compiler, graphics, text, operating system services, and much more. All told, a fresh VisualSmalltalk (formerly Smalltalk/V) image arrives with about 700 classes, a fresh VisualWorks (Smalltalk-80) image arrives with about 1400, and a fresh VisualAge (IBM Smalltalk) image arrives with about 2000. Here's a view of some IBM Smalltalk classes, with help from a tool known as a browser:
<figure><img src="image_11.png" /></figure>

The upper-left windowpane focuses on subclasses of class Magnitude; it can be scrolled to reveal many more classes. Since class Number is highlighted, the list of operations you see in the middle windowpane, namely `*`, `+`, `-`, and so on, are the ones that numbers understand. In other words, these operations correspond to the telegrams that you can send to Number objects. You can see that numbers understand the usual arithmetic operations. And you could see many more by scrolling the windowpane. Don't forget that because of inheritance, you can also use operations that are defined in any superclasses of Number. By highlighting Magnitude:

<figure><img src="image_12.png" /></figure>
you can see operations that **Number** inherits from **Magnitude**, and they're exactly the comparison operations we suspected earlier, plus a few others. I've elongated the window to show more of **Magnitude's** subclasses. Compare the hierarchy implied by this screen shot with the diagram of Smalltalk's hierarchy on page 14. (The three dots following **Integer** mean that there are subclasses of **Integer**, presently concealed by the browser. To toggle between revealing and concealing these classes, one double-clicks the mouse over **Integer**.)

It is also worth glancing at the lower windowpane. Don't get distracted by syntactic peculiarities or the last three lines; the first line is the most significant. It is the Smalltalk code that makes class **Magnitude** a subclass of class **Object**. Similarly, in the preceding screen shot you can see the code that makes class **Number** a subclass of class **Magnitude**.

Class browsers are standard tools in all Smalltalk products, although their form varies from product to product. Even within one product, there are alternate browsers. The browser above is particularly adept at suppressing superfluous information; other browsers show more information, sometimes more than you care to see. Browsers are the most common way for a programmer to navigate through Smalltalk's code libraries. As you'll see, you can also use browsers to write or change and compile code. (Similar tools, often less nimble, are available in good C++ environments as well.)

One use of inheritance is incremental programming. If you can find a class that comes close to fulfilling your need, but doesn't quite do it, you can create a subclass from it and simply write the relatively small amount of code that distinguishes what you need from what the class already provides. Before you plunge pell-mell into this style of programming, understand that, when practiced imprudently, it can produce obscure and arbitrary designs. In later chapters we'll discuss the challenges of crafting high-quality inheritance hierarchies. For now, think of inheritance as Pandora's box, releasing prospects for hope as well as disaster.

We can picture the inheritance relation between two classes by nesting the rectangles of our earlier schematic (page 12). In Smalltalk, the outermost rectangle represents class **Object**. Since this rectangle contains all the objects, "everything is an object." The nested rectangles on the right could indicate that **SavingsAccount** and **CheckingAccount** are two subclasses of **BankAccount**, or that **Integer** and **Float** are two

<figure><img src="image_13.png" /></figure>

subclasses of class **Number**. Keep in mind that this schematic notation is just that—a notation. Remember to resist the temptation to think of objects as literally being inside their class. It is better to think of objects as being created from their class—the class is a factory for producing new objects.
One fundamental point. You should implant in your mind an intuition that objects of a subclass have more qualities than objects of its superclass. A butterfly has all the qualities of an insect, and then some. A savings account object has all the qualities of a bank account, plus more. The same goes for a date object and a magnitude object. When you subclass, you enrich your objects. This is an essential intuition, even though the time will come later on when we must challenge it.

## 2.4 Terminology

It's time to deal with terminology—the technical jargon that you need to communicate clearly with other object programmers. The following terms arise from the Small-talk community, but they are accepted by the broader community of C++ and other object programmers too.

* Objects are also called *instances*.

* The data inside an object are described by *instance variables*. In other words, these are the variables that belong to an instance.

* An object's operations are called *methods*.

* Invocations of methods are called *messages*, as you already know.

<figure><img src="image_14.png" /></figure>

A message arrives at an object, where it activates a method. The message is like a telegram, and the method represents whatever the object does in response to the telegram. Some simple examples:

<table><thead><tr><td>Class</td><td>Instance</td><td>Message</td><td>Effect or Return</td></tr></thead><tbody><tr><td>Account</td><td>MySavings</td><td>MySavings withdraw: 230</td><td>Processes a withdrawal</td></tr><tr><td>Integer</td><td>134</td><td>134 - 95</td><td>Returns 39</td></tr><tr><td>String</td><td>'hello'</td><td>'hello' size</td><td>Returns 5</td></tr><tr><td>Set</td><td>MySet</td><td>MySet add: 'hello'</td><td>Puts one more object, namely the string 'hello', into MySet</td></tr></tbody></table>
You will sometimes encounter alternative terms. An object's outside, consisting of the "names" of all the methods that a user of the object can see, is known as its:

* protocol

* behavior

* interface

* services

* public member functions (a C++ term)

Instance variables, an object's inside, are also sometimes called the object's:

* attributes

* characteristics

* memory

* state

* private member data (a C++ term)

To be historically precise, **MySet add: 'hello'**, not just **add: 'hello'**, is a message. In other words, messages include their receiver object. Nevertheless, the term "message" is commonly used in both ways, with or without the receiver object. The distinction rarely matters in conversation.

*Technical aside:* Because "everything is an object," Smalltalk messages are themselves first-class objects, too. In other words, telegrams have behavior in their own right. (We'll exploit this feature in the ghost design pattern on page 226.) IBM Smalltalk goes even further, by explicitly observing the distinction above: a "message" without a receiver object is an instance of class **Message**, and a "message" with a receiver object is an instance of class **DirectedMessage**.

Many readers will have correctly noticed a jarring similarity between messages and function (or procedure) calls in conventional languages. Both are invocations of operations. Moreover, although the term "message" may conjure images of simultaneous events, messages are no more simultaneous than calls; rather, both calls and messages are *synchronous*: while the method or procedure executes, nothing else happens; the sender or caller *blocks*. In other words, a telegram's sender waits for a response.

There is a key distinction between messages and function calls, however. A message always has a distinguished "argument," namely the receiver object, who is responsible for responding to the call; a conventional call treats all its arguments as peers.

*Method* usually means the operation, *including* all the code that goes into its implementation. But sometimes we want to refer to a method without also referring to all this code; we want to refer only to its "name." The Smalltalk term for a method's name
is selector (or message selector). In the following picture, the method, shown only in part, is a substantial body of code that you are probably not prepared to read yet, but the selector is simply add:.

<figure><img src="image_15.png" /></figure>

To make matters worse, you'll hear C++ programmers say *signature* instead of selector, and *function* instead of *method*. In casual conversation, most object programmers aren't too careful about all these distinctions. They say *method* when they mean selector, or *message* when they mean *method*. Don't let terminology discourage you. Just retain a firm grasp on the imagery: a telegram (message) arrives at an object (instance), the object recognizes it (the selector) and executes the appropriate body of code (method).

Some data-driven development methodologies, not customarily favored by Small-talk developers, reserve the word *attribute* for only the most primitive kinds of things inside objects—things like integers and characters—but not for complex objects within objects. Thus some people would say that my bicycle's color is an attribute, but its rear wheel is too complicated to be an attribute. But a Smalltalk philosopher insists on evenhandedness to the extreme, and so treats both color and wheel in the same way. They are peer instance variables, one of which happens to be more complicated than the other.

Finally, a really substantive distinction: you must carefully distinguish between a *variable* and the *object* that is its value. In Smalltalk, it's a good idea to think of a variable as a *pointer* to an object. For example,

<figure><img src="image_16.png" /></figure>

in this diagram `MySet` is a *variable* that points to an actual set `object (instance)`. All variables, including instance variables, should be thought of as pointers to objects. Thus, a *wheel* or *color* instance variable inside a bicycle object points to an actual instance of a class like *Wheel* or *Color*.
## 2.5 Exercise: hierarchies

Here are four hierarchies to practice with. For each one, decide whether it may reasonably represent inheritance.

<figure><img src="image_17.png" /><figcaption>Hierarchy 1</figcaption></figure>

<figure><img src="image_18.png" /><figcaption>Hierarchy 2</figcaption></figure>

<figure><img src="image_19.png" /><figcaption>Hierarchy 3</figcaption></figure>

<figure><img src="image_20.png" /><figcaption>Hierarchy 4</figcaption></figure>

## 2.6 Solution and discussion: Aggregation hierarchies

Hierarchy 1 is definitely not inheritance. Engines are not special kinds of cars. Nevertheless, this kind of hierarchy is important. It describes a hierarchy of parts, and goes by various names: *part-of*, *aggregation*, *assembly*, *whole-part*, *composite*, or *has-a* (an auto "has-a" dashboard). In fact, aggregation hierarchies are even more fundamental than inheritance ones. Children realize that things are made up of other things—her hand "has-a" thumb—long before they think about specialization of classes. Aggregation hierarchies have been essential in programming, long before the popularization of inheritance. Some authorities elevate them to one of their defining object-oriented principles [Booch 1994; Collins 1995]. There isn't much hope for your software if you can't do a good job of putting little things together to make big ones.

Hierarchy 2 is a fine example of inheritance. It's reasonable to think of *Hatchback* as a special kind of *Station Wagon*, or *Sedan* as a special kind of *Automobile*.
If you think hierarchy 3 is inheritance, you are saying that Charles is a special kind of Queen Elizabeth. That's an odd statement. Moreover, an inheritance tree should always depict classes, not individual instances of a class. In what way can we interpret Charles as a class (a factory for producing objects)? We are more likely to think of him as an individual instance of some class, perhaps the class Person, or perhaps Royalty. Interpreting hierarchy 3 as inheritance therefore gets us into trouble.

Nevertheless, one could argue that "inheritance" is applicable to hierarchy 3. After all, Charles inherits hair color, blood type, even money from the Queen. The problem is that the vernacular usage of "inheritance" isn't the same as the object-oriented programmer's usage. It's just a case of one word taking on different meanings in different contexts. If we wanted terminology for this kind of hierarchy, we might call it *genealogical, family-tree, or genetic*. (The vernacular meaning aligns neatly with a language called SELF. SELF is an alternative approach to object-oriented programming, in which instances (Charles) rely on other instances (Elizabeth) for behavior, rather than on classes.)

Hierarchy 4 is also not a likely inheritance hierarchy. It again exemplifies aggregation—important but not the same as inheritance. It also demonstrates something common in aggregations, namely that a node may appear more than once in the hierarchy. Both Chips and Cards appear twice here. You will never see that in an inheritance hierarchy. We will revisit this whole matter of aggregation versus inheritance plus some notable connections between them in Chapter 9.

When dealing with aggregation, watch for some subtle distinctions: the automobile aggregation, consisting of its engine and so on, differs qualitatively from the relationship between a pot and its chips. An engine is more tightly coupled to its car than chips are to the pot. Object-oriented designers sometimes call the loose relationship between a pot and its chips a *container*, instead of an aggregation. Pots contain chips and (an earlier example) baskets contain onions. We'll discuss container classes more fully in Chapter 6. Another distinction is sharing. A sub-object in an aggregation may or may not be shareable. My arm is mine alone, but a word-processing document has sub-objects (like graphics or spreadsheets) that are sometimes shared by other document objects.<fnref n="1" />

## 2.7 Example: aggregation plus inheritance

You may remember from our snapshots of a class hierarchy browser that defining a subclass in Smalltalk has this unwieldy form:

<footnote n="1">¹ For a lengthier treatment of these nuances, see [Civello 1993].</footnote>
```
Number subclass: #Fraction
instanceVariableNames: 'numerator denominator'
...
```

This code specifies an inheritance relationship between fractions and numbers and also defines instance variables to represent the numerator and denominator of a fraction. On the right is a pictorial representation of the fraction object 3/4, where I've embellished the sketch with some of the methods that a fraction ought to have. The instance variables are, in effect, parts of the fraction. Since they should represent the integer objects 3 and 4, respectively, I'll add those objects to the sketch below.

<figure><img src="image_21.png" /></figure>

Again, I've embellished the integers with some of the methods they ought to have. This final sketch demonstrates the interplay between aggregation and inheritance: 3 and 4 are parts of 3/4 (aggregation) and at the same time both Fraction and Integer are subclasses of Number (inheritance). In object-oriented software,

you don't get far without both aggregation and inheritance.

<figure><img src="image_22.png" /></figure>

## 2.8 Syntaxes for inheritance

Here is the syntax for specifying inheritance in seven object-oriented languages. The first is the Smalltalk syntax you just saw:

<table><thead><tr><td>Inheritance Syntax</td><td>Language</td></tr></thead><tbody><tr><td>Insect subclass: #Butterfly ...</td><td>Smalltalk</td></tr><tr><td>Insect Class Butterfly (...</td><td>Simula-67</td></tr><tr><td>class BUTTERFLY inherit INSECT ...</td><td>Eiffel</td></tr><tr><td>@implementation Butterfly : Insect {...</td><td>Objective-C</td></tr><tr><td>class Butterfly extends Insect { ...</td><td>Java</td></tr><tr><td>type Butterfly = object(Insect) ...</td><td>Object Pascal</td></tr><tr><td>class Butterfly : public Insect { ...</td><td>C++</td></tr></tbody></table>
For sheer clarity of expression, it's hard to beat Eiffel or Java. But the real point of the table is that every object-oriented language has a direct way to express inheritance.

## 2.9 Example: inheritance in Smalltalk

Suppose I ask Smalltalk to execute:

```
Whale new talk
```

Left to right, **Whale** is a class, **new** creates a new instance of the class, in other words a whale object, and this instance then receives the **talk** message. In my demonstration system, Smalltalk would respond with: **I am pretty quiet.** In which class is the **talk** method that executed?

One begins of course by looking in class **Whale**. If we don't find **talk** there, we'll keep looking up the class hierarchy until we do. Here are two browsers with class **Whale** and its superclass **Mammal** highlighted:

<figure><img src="image_23.png" /></figure>

<figure><img src="image_24.png" /></figure>
Neither browser shows any instance methods at all defined in these two classes. We surmise that the `talk` method must be inherited from still higher in the hierarchy, and so we examine class `Animal`:

<figure><img src="image_25.png" /></figure>

This time we see not only the `talk` selector, but its code in the lower pane. Moreover, this code contains the string of characters we sought—'I am pretty quiet'. Evidently this is the method that executed.

Now suppose I want whale instances to talk in a way that is appropriate for whales, but I don't want to affect the way in which other animals talk. I had better not modify the `talk` method in the `animal` class. Instead, I'll write another `talk` method, in the `whale` class. In this method I'll replace 'I am pretty quiet' with a string more suitable for whales:

<figure><img src="image_26.png" /></figure>
Now if I again execute:

Whale new talk

Smalltalk will display: *I spout and sing!* I've altered the behavior of only the intended objects, whales, without perturbing the rest of the system. If I execute:

Animal new talk

Smalltalk will still display: *I am pretty quiet.*

Inheritance lets us reuse default behavior from superclasses when we want it (*I am pretty quiet*), but also lets us override and alter the behavior when we want that (*I spout and sing!*).

**Summary:** Whenever two or more methods with the same selector (talk) could respond, Smalltalk executes the first one it finds as it goes up the class hierarchy. In other words, same-named methods lower in the hierarchy override or eclipse those above them. (We'll discuss a small exception (page 54), when we talk about the special variable super.)

## 2.10 Exercise: building a class hierarchy

In IBM Smalltalk or VisualAge, any code you write must belong to an *Application*. An application generally contains several classes and their methods.<fnref n="2" />

* Create an application:

1. From the transcript, drop down the *Smalltalk tools* menu, and pick *Manage Applications*.

2. From the Application Manager, pick *Applications > Create > Application*. (For prerequisites, the defaults will do.)<fnref n="3" />

3. Select your new application, then pick *Applications > Browse Application*.

* Build the class hierarchy shown on the right, popularized by Digitalk in its Smalltalk/V tutorials. Start by making *Animal* a new subclass of *Object*. To define a new class, select its proposed superclass and pick the *Add Subclass*

<figure><img src="image_27.png" /></figure>

<footnote n="2">² There are situations in which some of a class's methods may belong to one application, and some to others, but we won't worry about them in this book.</footnote>

<footnote n="3">³ This sequence of menu selections is just a guide; the actual sequence you need will vary between versions of the product.</footnote>
menu option. (In the dialogue box that pops up, select subclass.) When you finish this step, you should have an application browser that resembles this one:

<figure><img src="image_28.png" /></figure>

☐ Finally, give all your animals the ability to have a name, by defining an instance variable *name* in class *Animal*. Do so by editing the text for *Animal*, as the browser above shows, and picking the *Save* menu option.

## 2.11 Commentary: what is object-oriented programming?

In the mid-1980s, there wasn't much consensus on what constituted "object-oriented programming." Although everyone agreed that Smalltalk and C++ were object-oriented, some also said Ada and Modula-2 were object-oriented, and a few people said they had been doing object-oriented programming in C and Pascal. In those days, a lot of unproductive disputes were incited by people who were naturally reluctant to acknowledge that their favorite programming style or language was deficient in some way.

To move beyond these disputes, the community needed a stake in the ground. Happily, in 1987, Peter Wegner proposed a definition for object-oriented languages [Wegner 1987]. Definitions act like benchmarks; they are arbitrary points of reference, and hence nothing is intrinsically right or wrong about them. We gauge them by their usefulness—how they help us understand the world around us. Wegner's definition was deemed useful; people embraced it as a plausible benchmark, and in so doing got back to the business of discussing substantive software matters instead of defending their prejudices about their favorite programming languages.
Wegner's definition had three elements, essentially the three principles we have discussed. For a programming language to be *object-oriented*, he required that it:

* Be *object-based*, meaning that you can easily make encapsulated programming objects in it.

* Be *class-based*, meaning that every object belongs to (is manufactured from) a class.

* Support *inheritance*, meaning that classes may be arranged in a subclass-superclass hierarchy.

He depicted his definition this way:

<figure><img src="image_29.png" /></figure>

The three principles—objects, classes, and inheritance—are a starting point for discussing object-oriented development. Most authorities add *late* or *dynamic binding* to their definitions, something we'll discuss in the chapter on *polymorphism*, Chapter 14. Whether there should be still other defining characteristics of the object-oriented paradigm depends on the authority. As we discussed earlier, some add *aggregation* to the definition. [Meyer 1988] insists on *garbage collection* and *multiple inheritance*, important topics that we'll discuss in Chapters 9 and 16. Again, there is no such thing as a “correct” definition. It is more important to understand what the ideas are and how they affect software development than to lapse into disputing what ought to be part of the definition.

By the way, there are also languages that everyone agrees are object-oriented, but that *don't* comply with the Wegner requirements. The most significant of these is the research language SELF, which displaces classes and inheritance with *delegation*. *Delegation* lets one object delegate to another object whatever behavior the first cannot handle. Instead of a chain of superclasses, each object relies on a chain of delegates. See [Chambers 1989] for SELF, and [Lieberman 1986; Lalonde 1986] for other discussions of delegation.

Wegner's three object-oriented programming principles are already part of everyone's experience. When you adjust your refrigerator or drive a car, you're using encapsulated objects; you needn't be aware of their inner workings. When you think of the notion of a dog, you think of the features shared among normal dogs—the dog class. And when you think of successive levels of specialization, like furniture then sofas, you're subclassing or inheriting. None of these ideas is new; we are just transporting them into the realm of programming.
## 2.12 Commentary: other languages

Here's a lineup of languages against the three principles:

<table><thead><tr><th></th><th>Objects</th><th>Classes</th><th>Inheritance</th></tr></thead><tbody><tr><td>Ada</td><td>+</td><td></td><td></td></tr><tr><td>APL</td><td></td><td></td><td></td></tr><tr><td>C</td><td></td><td></td><td></td></tr><tr><td>CLOS</td><td>+</td><td>+</td><td>+</td></tr><tr><td>CLU</td><td>+</td><td>+</td><td></td></tr><tr><td>COBOL</td><td></td><td></td><td></td></tr><tr><td>C++</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Eiffel</td><td>+</td><td>+</td><td>+</td></tr><tr><td>FORTRAN</td><td></td><td></td><td></td></tr><tr><td>Java</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Modula-2</td><td>+</td><td></td><td></td></tr><tr><td>Objective-C</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Pascal</td><td></td><td></td><td></td></tr><tr><td>Prolog</td><td></td><td></td><td></td></tr><tr><td>Simula-67</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Smalltalk</td><td>+</td><td>+</td><td>+</td></tr></tbody></table>

Whether a language has one of the characteristics (objects, classes, or inheritance) can be a matter of opinion; you could reasonably challenge some entries in the table. For example, in both Ada and Modula-2, it's not too much of a stretch to define classes as well as objects.<fnref n="4" /> Also, variants of many standard non-object-oriented languages are object-oriented. Examples include Borland's Pascal products and Apple's Object Pascal, as well as Ada95 (known earlier as Ada9X) and versions of COBOL and FORTRAN.

There are also some unreasonable challenges: one could argue that a language like C is object-based, because it is possible, with work, to build objects in C. One could

<footnote n="4">⁴ Nevertheless, Wegner classified them only as object-based. That's because Ada and Modula-2 objects do not necessarily come from classes; indeed, they generally don't, and so software built from those languages often lacks the structural coherence of the drawing on page 12.</footnote>
even argue that all languages are object-oriented! After all, they are all computationally complete, which is a technical way to say that any task that can be done by any one of them can be done by all of them. For example, you could theoretically use any of them to write a C++ compiler. Therefore, they can all support objects, classes, and inheritance. This generous interpretation of what it means to support objects (or classes or inheritance) is plainly unproductive. We want to know that a language has constructs that make it effortless to use objects, not that objects may be used through some circuitous route.

## 2.13 Commentary: history

Plato postulated a theory of “forms,” wherein an ideal form of a bed is the basis for all the ordinary beds in the world [Plato 375 B.C.]. His forms prefigured Smalltalk’s classes, a historical debt that was explicitly acknowledged in an article on Smalltalk-72 [Shoch 1979]. However, Plato’s emphasis is the opposite of an object-oriented programmer’s: Plato argues that the ordinary beds are less significant than the ideal bed.

Linnaeus’s classification of plants [Linnaeus 1753] became an international standard. Although he was first to apply inheritance systematically on a wide scale, the intellectual roots of inheritance go all the way back to Plato’s successor Aristotle, who wrote, “If we do speak of the animals severally, it is plain that we shall often be saying the same things about many of them” [Aristotle 330 B.C.]. Thus if two classes have common features, Aristotle suggests that we can save our breath by ascribing those features instead to what we could today call a superclass.

Inheritance and object-oriented programming have been around since the mid-1960s. Smalltalk itself evolved at Xerox PARC during the 1970s. That work culminated with Smalltalk-80, the first commercial Smalltalk. See [Kay 1993] for the fullest account of its history. Smalltalk-80 later evolved into ParcPlace’s Objectworks\Smalltalk and VisualWorks (which includes visual-programming tools) but is still commonly called Smalltalk-80. The Digitalk Smalltalk/V family originated in the mid-1980s and is now known as VisualSmalltalk, and IBM Smalltalk (often bundled in VisualAge) appeared in 1994. In 1995, ParcPlace and Digitalk joined into one company, ParcPlace-Digitalk, which is now combining the two families of products (VisualSmalltalk and VisualWorks) into one dialect. Other less-prominent Smalltalks are also available commercially today.

An ANSI committee is defining a Smalltalk standard that will consist of a core body of classes and methods. However, because this core will be only a small proportion of any one dialect, the standard will not be able to ensure portability of whole Smalltalk applications.
The following family tree shows some of the milestones in the history of object-oriented languages. (Object-oriented languages are in boldface type.)

<figure><img src="image_30.png" /></figure>

Two early landmarks were Sketchpad and Simula-67. Sketchpad, a direct manipulation graphics system developed at MIT by Ivan Sutherland, evinced the principles we've discussed but was not a programming language. Thus, people regard Simula-67 as the first object-oriented programming language. Between Smalltalk-72 and Smalltalk-80 were Smalltalks -74, -76, and -78; inheritance first appeared in Smalltalk-76. CLOS (Common Lisp Object System) is part of the Common Lisp standard.
CHAPTER 3

Smalltalk introduction

Smalltalk’s language is tiny. You will learn almost all of it from this chapter alone. And much of the chapter reviews what you’ve already seen in the first two chapters. Not that Smalltalk itself is tiny. A typical Smalltalk system out of the box includes a library of thousands of classes. And in Smalltalk you can’t do anything without classes, even, as you’ll soon see, something as ordinary as a conditional or a loop. Though it is a quick matter to learn the language, learning “Smalltalk” is a heftier challenge. To become effective you will have to learn many (but by no means all) of the classes. Moreover, using them wisely really amounts to doing good object-oriented design. This mastery takes months of practice—getting in there with your own fingers and snooping through the system and writing and stumbling through your own applica- tions. A modicum of curiosity and daring helps.

3.1 Elementary objects

A few elementary Smalltalk objects merit their own special notations. Here are some examples:

<table>
   <thead>
    <tr>
     <td>
      Sample Instance
     </td>
     <td>
      Its Class
     </td>
    </tr>
   </thead>
   <tbody>
    <tr>
     <td>
      37
     </td>
     <td>
      Integer (really the subclass SmallInteger)
     </td>
    </tr>
    <tr>
     <td>
      'To be or not to be'
     </td>
     <td>
      String
     </td>
    </tr>
    <tr>
     <td>
      2.71828
     </td>
     <td>
      Float
     </td>
    </tr>
    <tr>
     <td>
      $p (the character p)
     </td>
     <td>
      Character
     </td>
    </tr>
    <tr>
     <td>
      true
     </td>
     <td>
      Boolean (really the subclass True)
     </td>
    </tr>
    <tr>
     <td>
      false
     </td>
     <td>
      Boolean (really the subclass False)
     </td>
    </tr>
   </tbody>
  </table>
One of the by-products of these notations is that you do not issue the customary messages **Float new** or **Integer new** to produce a number object. Instead, the expression `2.71828` by itself produces a reference to a floating point object. In fact, executing or displaying **Float new** or **Integer new** results in an error or walkback window.<fnref n="1" /> Smalltalk disables the new message for numeric classes.

## 3.2 Messages and their precedences

Smalltalk has exactly three kinds of messages: **unary**, **binary**, and **keyword**. **Keyword messages** are messages that contain colons. The message:

```
HomeBudget spend: 229 on: 'VCR'
```

is an example. It's the keyword message whose selector is **spend:on**.

Note that this selector consists of two keywords that are smashed together. Each of them expects an argument. Hence this message includes two argument objects, namely `229` and `'VCR'`. A keyword message can have any number of keywords (i.e., colons), and it must have one argument following each colon.

Now, another way to mentally parse the message above is:

```
(HomeBudget spend: 229) on: 'VCR'
```

that is, in the form of one message following another, for a grand total of two messages. This is an alternative, but it is not the way Smalltalk works. The original expression had no parentheses, so Smalltalk interprets it in just one way, as a single message that happens to have two arguments riding on it. If you want instead to indicate two separate messages, you must explicitly use the parentheses.

**Binary messages** are the simplest to recognize. They're denoted by special symbols, such as `+ - * / < <= > >=`.

```
17 <= 14
```

is a binary message. Its selector is `<=` and the object it returns is the **false** object.

The comma is a surprising example of a binary message. You use it most often to concatenate two **String** objects:

```
'Let them eat ' , 'cake.'
```

If you ask Smalltalk to **display** the result, Smalltalk displays: `'Let them eat cake.'` **Commas** and comparisons and arithmetic symbols aren't the only binary selectors. You can define a binary message using any one or two of the symbols `+ - * / \ - > <= @ % | & ?`,

<footnote n="1">¹ These windows are known as *walkbacks* in Smalltalk, because, as you will see in Chapter 4, they let you “walk back” through the code that executed just before the error.</footnote>
as a selector. Not that you should. The selector `@\` is perfectly valid, but it is hard to imagine a good use for it.

All other messages—those whose selectors neither are special symbols nor have colons—must be *unary messages*. The selector for a unary message consists of a single word. Examples are:

'smart' reversed

whose selector is *reversed*, and:

`4 factorial`

whose selector is *factorial*.

When faced with a more complicated expression, comprising more than one kind of message, Smalltalk's *precedence rule* is unary, then binary, then keyword. For example,

`12 between: 7 and: 9 + 2`

contains a keyword message and a binary message. Since binary has higher precedence than keyword, `9 + 2` executes first, resulting in `11`. Next, `12 between: 7 and: 11` executes, which is a keyword message (with two arguments) asking `12`, "Are you between 7 and 11?" to which `12` finally responds with the *false* object.

What happens if we alter the expression by inserting parentheses?

`(12 between: 7 and: 9) + 2`

The parentheses change the precedence; in this case the result will be an error window (walkback). Here's why. The parenthesized expression executes first, resulting in the *false* object. Then `false + 2` executes, which asks the *false* object to add `2`. Because the Smalltalk *false* object doesn't understand addition, it pops up the walkback window, announcing an error. As in any other language, parentheses make a big difference.

## 3.3 Pitfalls: basic Smalltalk gotchas

The first simple pitfall is that Smalltalk is case-sensitive, which means that you can't write *whale* instead of *Whale* and expect your code to work the same. We'll discuss Smalltalk's capitalization conventions in the upcoming section on variables (page 39).

Another pitfall is that Smalltalk assignments are *not* messages.<fnref n="2" /> Assignment is an exception to the left-to-right rule. Smalltalk processes the right-hand side of the `:=` first, then puts the resulting object in the variable on the left-hand side. For example,

<footnote n="2">² In a twisted sort of way, you can think of an assignment as a peculiar kind of message, of lower precedence than the other kinds, and where the receiver is the object that "owns" the variable being assigned to. For example, an assignment to an instance variable can be interpreted as a message to the instance of the form `instVarAt:put`. But it is neither customary nor linguistically illuminating to view assignments in this way.</footnote>
X := 12 between: 7 and: 9 + 2

doesn't mean that X refers to the 12 object. It means that the entire expression on the right of the assignment executes, resulting in the false object, only after which does assignment occur. In the end, X refers to the false object, not the integer 12.

More insidious pitfalls surround the differences between instances of Character, String, Symbol, and Array. But before telling you about the differences, I want to highlight a similarity. Along with numbers such as 19 or 2.71828, these objects are often called literals. In IBM Smalltalk, literals are immutable—they are read-only objects and cannot be modified. (Literal strings and literal arrays are mutable in other dialects.) Here is how you indicate literal objects:

<table><thead><tr><td>Smalltalk</td><td>Meaning</td></tr></thead><tbody><tr><td>19 and 2.71828</td><td>Numbers (aSmallInteger and aFloat)</td></tr><tr><td>$b</td><td>The single character b</td></tr><tr><td>'rosebud'</td><td>aString</td></tr><tr><td>#rosebud</td><td>aSymbol (explained below)</td></tr><tr><td>#(5 'rosebud' 7)</td><td>anArray</td></tr></tbody></table>

(It's a Smalltalk tradition to ram words together and use just an uppercase letter to mark the boundary, as in aString.)

An instance of Symbol is a sequence of 1 or more characters beginning with a number sign (#). Aside from cosmetic differences between symbols and strings, they differ in one profound respect: Two strings may have the same character sequence, but no two symbols may have the same character sequence. Even if the symbol #rosebud occurs more than once, Smalltalk construes all occurrences as referring to one and the same underlying object. As a by-product, copying a symbol results in ... the same symbol! This behavior of symbols plays a role in matters of object identity, which we will discuss in Chapter 6.

An instance of String is a sequence of 0 or more characters delimited by single quotation marks. Note that although " has no characters and 'b' has one character, both denote legitimate instances of String. And don't confuse the string 'b' with the character $b$; they are instances of entirely different classes. As in many other languages, a quote within a string must be doubled: 'Alice''s Restaurant'.

Again, a Smalltalk system may contain many instances of the string 'rosebud', but at most one instance of the symbol #rosebud. In Smalltalk, it so happens that Symbol is a subclass of String. Thus, you can think of a symbol as a special kind of string in which the meaning of "sameness" or identity differs.
Notice that by putting parentheses after #, instead of characters, you no longer get a symbol. Instead, you get an array. The array #(
5 'rosebud' 7) has three elements: first the integer 5, then the string 'rosebud', and finally the integer 7. You can nest literals inside a literal array. As examples, #(
5 #rosebud 7) has three elements, the second of which is a symbol, and #(
5 #(
2 11 13) 7) also has three elements, the second of which is another array. (In these last two examples, odd as it may seem, the inner # is optional in IBM Smalltalk.)

Finally, quotation marks delimit comments, and are ignored by Smalltalk. Thus, "rosebud" is a comment. You can use comments freely anywhere white space occurs in your code.

## 3.4 Examples

What do you expect will be returned from each of these expressions?

```
3 - 5 * 2
Integer superclass
#(me you they) at: 2
```

The answers should be -4, Number, and #you. The first consists of two consecutive binary messages, processed left to right. The second is a unary message sent to Integer, asking this class to tell us its superclass. The last is a keyword message with a single argument, 2, asking the array object to reply with its second element; this second element is the symbol #you.

What do you expect to be the effect of each of these messages? Don't think about the return, just the effect.

```
#zero at: 1 put: $h
'zero' at: 1 put: $h
'zero' copy at: 1 put: $h
#zero copy at: 1 put: $h
```

The first two messages should fail (!) because literals are immutable. The third one works fine; copying the literal string produces another string, which is not a literal. This copy's first letter is replaced, so that the copied string becomes 'hero'. The final message again fails. That's because the copy has the same sequence of characters as the original symbol, and for symbols the copy must then be the same as the original, which we know to be immutable.
3.5 Exercise: a hypothetical method

The code below is an entire, hypothetical Smalltalk method named replaceLastBy:. It
introduces several elements of the language. Look it over and try to answer these two
questions:

What does the method do?

What is a class for which it would make sense?

Here is the code:

replaceLastBy: anObject
    |last|
    last := self size.
    self at: last put: anObject.

You will need explanations for several things you are seeing for the first time:

* The first line just has the selector—the keyword `replaceLastBy:`—plus a dummy name the method will use for the argument. I've chosen `anObject` for this name, which represents a healthy, orthodox Smalltalk coding style, but in theory any name is equally legal.

* The next line (after the comment) declares a local variable between the vertical bars; its name is `last`, although again it could be anything we like. You can use local variables throughout the method to refer to objects. And you can declare any number of them between the bars, separating them by blanks.

* To understand `self`, which appears in the final two lines, it helps to think anthropomorphically. Imagine that I am the object for which the method is executing. `self` is a special Smalltalk variable that refers to `me`. (But you may not know who I am yet because that's the second question in this exercise.)

* Finally, notice the periods at the ends of lines; they separate Smalltalk statements. Because periods are separators, the final period is optional.

As a final hint before attacking the two questions above, imagine a concrete situation. Imagine that some object has several elements within it and receives the message `replaceLastBy: $e`.
## 3.6 Solution and discussion

What does the method do? Imagine that I have, say, 4 elements. In other words, imagine that I am some sort of collection. Then self size calculates my size, which is 4. And self at: 4 put: anObject substitutes anObject for whatever my 4th element is. For instance, suppose that I am a string containing the characters b, l, u, and r, and a variable Me refers to me. If I receive the message (or telegram):

Me replaceLastBy: $e

then I am being asked to replace my last element with the character e. The method thus transforms me into a string with characters b, l, u, and e. In general, no matter what object Me refers to, the method will attempt to replace that object's last element.

As for the second question, what is a likely class for Me? An obvious candidate is String, because 'blur' is a string. Others? Perhaps Array, or any class whose instances have an indexed ordering on them. String and Array are the two most obvious, but you will encounter others as you learn more about Smalltalk.

Another language element that appears often in methods is the caret, ^. ^xyz means that the method should return xyz to whoever invoked it and stop executing. If there's a complicated expression to the right of the ^, the whole expression executes, then the method returns to the invoker whatever the expression produced and stops executing. Thus, the statement:

^5 + 6 * 2

in a method would terminate the method and return 22 to its invoker. Or,

^self

would terminate the method and return "me" to the invoker.

Now, if a method, like the one in this exercise, contains no carets, Smalltalk still insists that the method return something—Smalltalk methods always return some object. This default return object is always self. Therefore the method could have been written equivalently as follows:

replaceLastBy: anObject
|last|
last := self size.
self at: last put: anObject.
^self
## 3.7 Kinds of variables

Variables may be spelled with any letters. Whether the first letter of the variable is uppercase or lowercase is a matter of preference in some Smalltalks (IBM Smalltalk and VisualWorks), but is strictly enforced in others (Smalltalk/V). Although IBM Smalltalk offers considerable latitude in this regard, I recommend you use the common conventions (which are the same as the Smalltalk/V rules). Your Smalltalk code will then resemble other Smalltalk code, which fosters mutual readability. Here are the conventions:

Begin variables like `anObject` or `last`, which are visible to only one object, with a lowercase letter. The most common kinds of these variables are:

* formal arguments like `anObject`, declared along with the selector at the top of the method.

* local or temporary variables like `last`, declared within vertical bars.

* instance variables like `numerator`, declared along with its class `Fraction` (page 23).

We'll come to another kind of variable when discussing *blocks* on page 55. Although all these variables are visible to just one object, the first two kinds (`anObject` and `last`) are even less visible; they are usable only within the single method that defines them. By contrast, instance variables like `numerator` are usable by any of the object's methods.

Begin variables that are shareable among many objects with an uppercase letter. The most common kind of uppercased variable is a *global variable*. Global variables are universally visible; any object in Smalltalk can see and use them. You're already familiar with one variety of global variable—classes. More precisely, names like `Fraction` and `Whale` are global variables (that happen to point to the actual classes for fractions and whales). The other common variety of global variable consists of the ones you invent so that you can refer to an object at a later time. An example is the global variable `X` in the expression `X := Whale new`. `X` provides a handle by which you can refer to the whale instance. (Recommendation: Experienced object programmers limit their use of global variables, because globals are the antithesis of encapsulation. Your goal is to hide as much as possible, and global variables have the opposite effect. But you can't shun global variables entirely: for example, you can't do much in Smalltalk without classes.)

Another kind of shareable (uppercase) variable, a *class variable*, is not quite global. These are variables that may be shared among all the instances of one class and its subclasses. For example, a graphical icon might be a class variable, because every
instance of a class does not need to have its own private copy of the icon. Or, if we want to copy and paste text among several text windows, it might be convenient for all text window instances to share a *TextBuffer*. Class variables, being visible to more than one but not all objects, occupy a middle ground between global variables and the variables that a single object enjoys.

Another kind of shareable (uppercase) variable is known as a *class instance variable*. Class instance variables are handy for implementing *solitaires* (page 230); I will save their explanation until then.

*Summary:* To conform to the preponderance of Smalltalk code in the industry, begin global, class, and class instance variables with an uppercase letter, and begin any variable that makes sense to only one object with a lowercase letter.

## 3.8 Pitfall: variables ≠ objects

It bears repeating that a variable is not an object (page 20). Rather, a variable refers to or “points to” an object. At one moment the variable X could refer to the integer 92, at another moment, merely by reassigning it, X could refer to the string 'Call me Ishmael'. Smalltalk permits X to refer to any type of object at all. That's why you will hear people say, “Smalltalk is an untyped language.” (Remember that, until Chapter 17, it is safe to think of “type” as just another word for “class.”)

Although the type of a variable can vary from moment to moment, the type of an object is never ambiguous. 92 is and always will be an instance of class *Integer* (actually *SmallInteger*, the subclass of *Integer* consisting of the 31-bit positive and negative integers) and 'To be or not to be' is always an instance of class *String*. Thus one can say, “In Smalltalk, variables are untyped, but objects are strongly typed.” The only exception is a powerful Smalltalk method, *become*: which can actually alter the class of an object. (See the discussion on proxies and ghosts in Chapter 18.)

## 3.9 Classes are objects

In the spirit of “everything is an object,” Smalltalk classes (factories) are themselves special kinds of objects. Like other objects, they can receive messages, new being the most frequent. This is no mean feat—classes are decidedly not objects in most other object-oriented languages. That's why you hear the expression: “Smalltalk classes are first-class objects.”
The methods that apply to classes are called *class methods* and those that apply to instances are called *instance methods*. Both kinds of messages occur in the expression:

Whale new talk

The object that receives the new message is class `Whale`; thus `new` is a class method. The object that receives the talk message is the whale instance that comes out the factory door; thus `talk` is an instance method.

Smalltalk browsers present instance and class methods to us separately. This browser:

<figure><img src="image_31.png" /></figure>

shows three instance methods at the upper right. We know they are instance methods because the pushbutton near the middle of the window says *instance*. Toggling this button gives us:

<figure><img src="image_32.png" /></figure>

Class `Semaphore` defines only one class method, namely `new`. This reflects the general situation: Smalltalk has many more instance methods than class methods. That shouldn't be a surprise, for it's the instances themselves which you want to do most of your useful computing.
### 3.10 Control flow

One of the earliest facts you learn about programming is that programs need to be able to branch conditionally (if-then) and loop, as well as sequence statements one after the other. Yet Smalltalk has language statements for neither conditionals nor loops. Smalltalk accomplishes these in the only way it knows how to do anything, via messages. We need one additional language element first.

A *block* is a special kind of object, delimited by brackets [...]. A block acts like a chunk of code without a name. Here's a simple block:

```
[Whale new talk]
```

Since it's an object, you treat it like an object, assigning it, passing it as an argument, and sending messages to it. For example, I can assign it to a variable by executing:

```
MyBlock := [Whale new talk].
```

Smalltalk obliges, but nothing appears on the screen. That's because all I've done is assign the block to `MyBlock`. I haven't done anything to execute the block. To do so, I send the block a special message named `value`:

```
MyBlock value
```

And now Smalltalk finally responds with 'I spout and sing!' Blocks, in effect, are a way to defer the execution of code until it is appropriate.

Now, conditionals and loops. Here's an example of a conditional branch:

```
MyValue < 17
    ifTrue: [Whale new talk].
```

Because binary messages (<) precede keyword messages (ifTrue:), Smalltalk first determines whether `MyValue` is less than 17, resulting in either the true object or the false object. If the answer is the true object, the `ifTrue:` method evaluates the block. Control then passes to any subsequent statements. If the answer is the false object, the `ifTrue:` method does nothing; it doesn't bother to evaluate the block of code, and control still passes to any subsequent statements. The result then is as you would hope: depending on the outcome of `MyValue` < 17, either the block executes or not.

There are several methods for looping. Here is a simple message that invokes such a method:

```
6 timesRepeat: [K := K + 1]
```

This message causes 6 repetitions of the block of code. Notice that the receiving object is 6, a lowly integer. In other words, class `Integer` has behavior so rich that all its instances can control loops; they all understand the keyword message `timesRepeat:`. This example illustrates how extreme the Smalltalk object model is. Nothing stands in the way of giving rich behavior to innocuous objects like integers.
3.11 Commentary: metaclasses

This section takes an entirely optional glimpse at an advanced topic that I treat fully in Chapter 20. One of the consequences of admitting classes as first-class objects is that classes themselves must then be instances of some other class. In effect, a factory must come from some sort of higher-level factory. Thus every class, like Whale , is itself an instance of some class, which happens to be called its metaclass. Moreover, class Whale happens to be the one and only instance of its metaclass. As a matter of fact, every class is the one and only instance of its own metaclass.

Now, if every class has an associated metaclass, and the class is the only instance of this metaclass, that doubles the number of class-like objects running around the sys- tem. You’re probably fearing the worst—that this goes on forever, with meta-meta- classes and so on. Fortunately not. The next level is much simpler. All the metaclasses are instances of one and the same class, whose name is, naturally enough, Metaclass . The explosion of class-like objects stops cold with this one class. You can even count them all up. If your system has 2000 ordinary classes—mind you, that’s really 1999 plus one called Metaclass —then it also has 2000 metaclasses. And all 2000 of these metaclasses are instances of Metaclass . That’s just 4000 class-like objects in all.

Now, 4000 is 2000 more than a class browser really needs to make you aware of. The class browser is a practical tool and was designed to conceal those 2000 meta- classes. How? By giving you the convenient toggle you saw that lets you look at "class methods." The so-called class methods of Whale are actually the instance methods of Whale ’s metaclass! By this sleight-of-hand, the Smalltalk browser conceals Whale ’s metaclass, and portrays its methods to us as an artificial breed of method called "class methods."

You can program for a long time in Smalltalk without knowing as much as I’ve already said about metaclasses. The noteworthy theme is that metaclasses preserve the conceptual consistency of Smalltalk. (“Everything is an object, and everything is there- fore also an instance of some class.”) This consistency is unlike what you’ll find in most other object-oriented languages. C++ classes are not objects; they aren’t eligible to receive messages, for example. C++ classes are limited to the role of describing the system rather than participating in it.

Again, the details of the metaclass story appear in Chapter 20. Meanwhile, the next step is to begin programming in Smalltalk.
CHAPTER 4

Exercises—Foundations

Smalltalk is so compact that almost all its essentials can be practiced in one sitting. This chapter covers these essentials—the language elements in Chapter 3, plus tools for maneuvering through Smalltalk. It consists entirely of hands-on exercises. Only by experiencing Smalltalk firsthand will you understand what is unique about object-oriented programming in Smalltalk. Reading this or any other book without doing Smalltalk will get you nowhere. Do the exercises, look around, try experiments, be curious. Set aside at least half a day for this effort.

Warning

Do not get distracted by the myriad menus and options present in the Smalltalk environment, nor by the code version and management tools that are available. These exercises emphasize the nature of objects in Smalltalk, and only enough menu options and tools to survive. You will acquire the rest gradually, through experience and self-discovery. Confronting fundamental conceptual matters is more valuable now than becoming proficient in mechanical skills.

4.1 Precautions

I mentioned in Chapter 1 that each Smalltalk workstation has a crucial file known as the "image." The image contains executing objects, and it therefore grows and shrinks. The name of this file varies among Smalltalk dialects, but in IBM Smalltalk and Visual-Age, the default name is simply *image*. You should imagine it as consisting of objects and their methods, but not their source code. Although source code may be present in
the images of some dialects, this is an artifact of the dialect rather than an inherent characteristic of Smalltalk. Source code is needed to describe objects and their behavior, but it is not part of the objects themselves; hence it is not an essential ingredient of an image.

Of course, developers need access to a reliable copy of their source code. Smalltalk stores code that you write either in a text file or in a special library or repository. The standard versions of IBM Smalltalk or VisualAge use a text file called *changes.log*, local to each workstation:

<figure><img src="image_33.png" /><figcaption>Standalone</figcaption></figure>

(You may notice exclamation points peppering files like *changes.log* that contain Smalltalk source. They delineate methods and other chunks of code, and they are read and inserted automatically by the tools that handle source code.)

The team and professional versions of these products use a shared library with a qualifier of *dat*, such as *manager.dat* or *abtmgr30.dat*.

<figure><img src="image_34.png" /><figcaption>Team or Professional</figcaption></figure>

Notice that the image contains instances of class X as well as class X itself. This is a reminder that in Smalltalk, classes are first-class objects. The class X wouldn't be a live object in C++, nor is the idea of an image relevant.
The point of this discussion is that you need two things—a sound backup image and a reliable repository of your source code—in the event that your image becomes corrupt, as it inevitably does sometime in every complex development project. Then you can always reconstruct an up-to-date image by merging your work into the backup image. The bottom line is that you should conscientiously back up *changes.log* or *manager.dat*, plus at least one trustworthy image.<fnref n="1" />

## 4.2 Finding things in Smalltalk

Finding things is a basic survival skill. Smalltalk developers most frequently need to find classes and methods.

### Classes

* One workhorse tool is the browser on *all* the classes in the system. To open one, pick *Smalltalk tools > Browse Classes* from the menu bar of the system transcript window. Familiarize yourself with this browser by clicking, double-clicking, and scrolling around; don't try to read any code yet, though. Spend a few minutes (no more) trying to find class Set; if you fail, read on.

<figure><img src="image_35.png" /></figure>

<footnote n="1">¹ In the standard environment, you might as well back up both *image* and *changes.log* at the same time. This precaution ensures that the live objects and the source code are in step with one another.</footnote>
* This browser's alphabetical listing doesn't help much if you're looking for a class that's nested deeply in the hierarchy. For example, because Set isn't a direct descendant of Object, it doesn't appear in the browser's initial alphabetical listing. To find it, pick *Classes > Find Class* from the browser's menu bar. Type *Set* in the dialogue box, and click *OK*.

## Methods

* Suppose you want to find all the implementations of the `at:put:` method. Pick the *Smalltalk tools* menu from the transcript again, but this time pick *Browse Implementors*. Type `at:put:` in the dialogue box and click *OK*. A list of the many implementations of `at:put:` that exist in Smalltalk appears. Select one for a glimpse at the source code; don't try too hard to understand the source code yet, though.

* Anything that happens in Smalltalk happens, ultimately, by way of a message. In particular, the effect of the *Smalltalk tools > Browse Implementors* menu sequence above is to *execute* this message:

### System implementors

Instead of using the menu, type this message in the transcript, highlight it, and *execute* it, then produce a list of all the implementations of the `+` message.

By the way, the transcript is an obvious place to type and experiment with messages, but you can actually type them and try them in any textual window in Smalltalk. In general, if you can type somewhere you can also execute there. Regardless of which window you happen to have typed and executed messages in, you are making Smalltalk use live objects in the image.

* Similarly, you can find every method that sends a message by *executing*:

### System senders

or by picking *Smalltalk tools > Browse Senders*. Use either technique to produce a list of all senders of the message `at:put:`. Use the other technique to produce a list of all senders of the (recursive) message *factorial*.

* To understand a method, say `remove:`, we often need to understand the methods it invokes in turn. Let's investigate class *Collection's remove:*. Since there are `remove:` methods in many classes, Smalltalk developers use the notation `Collection>>remove:` to distinguish *Collection's* method from the others. Select *Collection>>remove:* from the list, then pull down the *Methods* menu (or pop it up with a right mouse click), pick the *Browse Messages* menu item, then its *Implementors* sub-item. Smalltalk brings up a list of the messages that `remove:` sends. There are
only two in this case. Selecting either one produces a list of all its implementors. We could repeat this procedure indefinitely. That is, we can drill as deeply as we wish into the implementation of any method by repeatedly picking *Browse Messages > Implementors*.

* Apply this technique to the method that tests whether a date occurs between two others. In other words, by alternately selecting *Browse Messages* and *Implementors*, trace the implementations of this chain of methods: between:and:, <=, <, and year.<fnref n="2" />

## 4.3 Elements of Smalltalk

### Establishing global variables

* Add the global variable T to your image:

Smalltalk declareVariable: #T.

This message establishes an entry for T in the so-called system dictionary.

Global variables should generally be avoided. Professional developers use them sparingly because they conflict with the object-oriented spirit of limiting the visibility of information, and there is almost always a way around using them. But they can help illustrate ideas and facilitate experimentation, and in this opening chapter we use a few of them.

### Global versus temporary variables

* In the transcript window, *display* this entire chunk of code (remember that periods separate statements, and the final period is optional):

T := 'dig' copy.
T at: 2 put: $o.
T.

* Repeat the experiment with this chunk:

|t|
t := 'dig' copy.
t at: 1 put: $p.
t.

<footnote n="2">² In older versions of IBM Smalltalk an additional > method occurs in this chain.</footnote>
□ Now *display* the global variable *T*. Then try *displaying* the temporary variable *t*. The latter is no longer defined; it was valid only when it was highlighted together with its declaration *lt*.

### The ^ (caret)

□ Smalltalk methods always return some object. The ^ specifies the object. Use the classes browser to familiarize yourself with the hierarchy under class *Magnitude* that we examined on page 14. Locate the method whose selector is *max*: and read through its code. Notice that the ^ precedes the object that the method returns. The ^ also terminates execution of the method.

Many methods contain no ^ at all. Nevertheless, the method must return an object. In this default situation, that object is *self*, the receiver of the message. Notice that unless you look into a method's code, you cannot be sure of what it returns because you can't know if and where there are any ^'s. Sometimes, as you will see shortly, the returned object isn't what you expect.

### Execute versus Display

*Execute* and *Display* both compile and execute the highlighted code. The only difference is their treatment of the returned object. *Execute* ignores it. *Display* prints it on the screen.

□ Declare a new global variable *W*. Then *execute*:

W := 3.14 - 2 * 2.

Next *execute*.

W

Nothing should appear on the screen. But you can verify that the code has compiled and executed by *displaying*:

W

□ Similarly, merely *executing*:

Array with: 'Tolstoy' with: W

produces nothing on the screen, but *displaying*:

Array with: 'Tolstoy' with: W

displays the resulting array instance on the screen. (The *with:with*: class method is an easy way to produce an array instance.)
□ As a final example, execute:

Transcript show: 'War and Peace'

In this case, the effect of the execution is to echo back the string to the transcript window. But don't confuse this effect with the return. What is the returned object? Short of reading source code, you can find out by displaying:

Transcript show: 'War and Peace'

The same effect will occur, and Smalltalk will print the returned object—an *EtTranscript*—which is Smalltalk's description of an instance of class *EtTranscript*. As a matter of fact, that's what *Transcript* is—a global variable pointing to an instance of *EtTranscript*.<fnref n="3" />

The next exercise illustrates several returns, one of which astonishes nearly everybody.

## Messages

□ Display the returns from each of these messages:

```
4 factorial
8 max: 5
8 between: 5 and: 7
#(vanilla ice cream) at: 2
#(vanilla 'ice' cream) at: 2
'milk and ' , 'honey'
'salt' at: 1 put: $m "Remember that literals are immutable"
'salt' copy at: 1 put: $m
```

The return from the last message surprises most people. They expect `at:put:` to return the (modified) string that received the message; instead it returns the argument `$m!` This experience emphasizes that you cannot always guess the return. You must either read the method's code or experiment by sending a message.

□ Finally, either displaying or executing:

```
#salt copy at: 1 put: $m
```

brings up a walkback window. The error occurs because symbols are unique, so that the *copy* message is ineffectual; it returns the original literal symbol, which is immutable.

<footnote n="3">³ In other dialects of Smalltalk, *Transcript* points instead to an instance of class *TextWindow* or *TranscriptWindow* or *TextCollector*.</footnote>
## Parsing precedence

Remember that unless overridden by parentheses, unary messages precede binary messages, which precede keyword messages.

* Apply this rule to predict and confirm the returns for:

```
#(6 5 4 3 2 1) at: 2 * 3
```

and:

```
'eat bran' size * 4 between: 6 negated and: 3 factorial * 5
```

## Classes and instances

* Examine the hierarchy of Animal classes you built on page 26. Predict and confirm the returns from these messages:

```
'eat bran' class
Penguin new class superclass
(2/7) class superclass superclass
String allInstances size
Penguin allInstances size
```

* Create a new global variable, P, then execute `P := Penguin new. Display` the returns from:

```
P isKindOf: Animal
P isMemberOf: Animal
```

* Finally, count the number of penguins in the system again by displaying:

```
Penguin allInstances size
```

## Inspectors

* Examine the penguin object by executing `P inspect`. This window is called an *inspector*, by clicking on its entries, you'll see the values of the penguin's instance variables, including any it inherits from its superclasses. You can also inspect an object by highlighting it and using the *Inspect* menu option. Try this technique too.

* You can use inspectors to plunge through several layers of complex object structure. For example, inspect this object:

```
Array with: P with: 'ice cold' with: -273
```

and double-click on the array's three instance variables to examine the underlying objects.
## Cascading messages

Smalltalk offers an economical syntax for repeatedly sending messages to the same object. Instead of writing:

```
SomeObject msg1.
SomeObject msg2.
SomeObject msg3.
```

you can *cascade* the messages by writing:

```
SomeObject msg1:
    msg2;
    msg3.
```

A cascaded message—one following a semicolon—is delivered to the same object that the previous message was delivered to. Here's another way to think about it: figure out the last message before the first semicolon; whatever object received that message also receives all the other cascaded messages.

### ☐ Execute:

```
Transcript cr;
    show: 'If I had a';
    cr;
    show: 'hammer'.
```

(The message `cr` just instructs the window to do a carriage return.)

### ☐ What is the return from:

```
5 + 2 * 3;
+ 7;
+ 9.
```

Verify your answer by displaying this code.

### ☐ The simple but handy message *yourself* returns whatever object it is sent to. Putting *yourself* together with a cascade gives us a convenient way to see the effect (instead of the return) of `at:put:`. Try displaying:

```
'salt' copy at: 1 put: $m;
    yourself
```

## Writing methods

### ☐ Bring up an application browser on the animal application you prepared earlier. (Just as before, first *Manage Applications*, then select your application, then finally *Browse Application*.)
□ Select class Animal , check that the instance / class button is toggled to instance , pull down the Methods menu and pick New Method Template . Write a display : method that looks like:

display: aString "Display aString in the transcript" Transcript cr; show: aString; cr.

Compile the method by picking the Save menu option.

□ Now write a talk method in Animal so that animals say 'I have nothing to say' . This method uses the method you just wrote, and is simply:

talk "Speak tersely" self display: 'I have nothing to say' .

□ Test your work by executing :

P talk

Assuming that P is still your penguin, the response should be 'I have nothing to say' .

□ As in the Smalltalk/V animal hierarchy, we are going to make parrots behave a little differently. Parrots should have vocabularies. Define an instance variable vocabu- lary in class Parrot . Also write and compile a method setVocabulary : that assigns a string to this instance variable. Last, write a talk method for parrots with this code:

talk "Repeat my vocabulary" self display: vocabulary.

□ Assign a new parrot to a new global variable P2 . Ask this parrot to talk. Do you understand this response? Now give P2 a vocabulary (’I want a cracker’) by send- ing it the setVocabulary : message. Ask P2 to talk again.

□ In class Animal , write and compile a setName : method that assigns a string to the name instance variable.

□ Create a Human subclass of Mammal . Assign a new human to a global variable H . Does H have a name? (Inspect H to confirm your answer.) Give H a name (’Claude Monet’) by sending it the : message. Finally, write a talk method so that all humans will say ’My name is ____ ’. Verify that H says his name properly.
## Special variables self and super

* Write a new instance method `blab` for humans. The method's body should simply be: `self talk`.

Predict and confirm the result of `executing H blab`. Replace the variable `self` with the variable `super` and recompile `blab`. What is the result of `executing H blab` now?

Here's the explanation. Changing `self` to `super` alters Smalltalk's rule for searching for methods. Instead of beginning the search in the class of the object—**Human** in this example—**super** causes Smalltalk to begin searching in the super-class of the method containing **super**. In this example, Smalltalk bypasses the **talk** method in class **Human** and begins its search in class **Mammal**. Thus, **super** is a way to access a superclass method that would ordinarily be eclipsed by an overriding subclass method. Notice that **super** and **self** both refer to the same object; they differ only in how they affect the starting point for method lookup.

* Make a small addition to your **talk** method in class **Human** so that humans say both 'I have nothing to say' and 'My name is ____'.

Now that you've developed some code of your own, you should save your work by saving the image. It's prudent to get into this habit, because a recently saved image simplifies recovery if and when the system crashes.<fnref n="4" />

## Accessing variables

Consider a class hierarchy like this:

<figure><img src="image_36.png" /></figure>

Suppose `Up` defines an instance variable named `u` and a class variable named `U` and `Down` defines an instance variable `d` and class variable `D`.

* Sketch an instance of `Up` and an instance of `Down`. Can instance methods of `Down` use `u`? Can instance methods of `Up` use `d`?

<footnote n="4">⁴ In Professional IBM Smalltalk, VisualAge, or any Smalltalk dialect with the `Env` library control system add-on, you can also create a version of your code. A version is a permanent snapshot of your code.</footnote>
□ Can instance methods of **Down** use U? Can instance methods of **Up** use D?

□ Can class methods of **Down** use u or U? Can class methods of **Up** use d or D?

If you are uncertain about your answers, create a brand-new application and perform the experiments. (To create a new application, use your Application Manager. Pop up a menu and pick **Applications > Create**.)

### Blocks [...]

Like everything else in Smalltalk, a *block* (sometimes also called a *context*) is an object. It is defined by placing code between brackets [...]. But it is stranger than most objects, because the code it represents might never execute. Meanwhile, you can assign it to a variable, pass it around as an argument of a message, and send it messages—in short, you can treat it like any other Smalltalk object. The code will execute only if the block receives an explicit request for it to do so. Here's an example.

□ If you execute:

X := [ H talk ]

the assignment to the variable X occurs, but the code for talking does not execute. Only by sending the message:

X value

does the code actually execute.

□ Blocks occur regularly in conditional messages. Execute this:

(H isKindOf: Mammal)
ifTrue: X

and:

(H isKindOf: Mammal)
ifTrue: [ P2 talk ]
ifFalse: [ H talk ]

□ They also occur in loops. Execute:

6 timesRepeat: [ P2 talk ]

□ With a little syntactic twist, blocks can also have arguments. For example, to multiply all the elements in a set, *display* (don't forget to declare global variables):

MyProduct := 1.
S := Set with: 5 with: 3 with: 4.
S do: [ :number | MyProduct := MyProduct * number].
MyProduct
The `do:` method is one of the most common ways to loop. It iterates over all the elements of `S`, substituting them one at a time for the variable `number` in the block. The name of this variable is arbitrary; it could just as well have been called `:element` or `:n` as `:number`.<sup>5</sup>

## Class Date

Date objects occur frequently in applications. Class `Date` is unusual because it has many more class methods for creating instances than other classes do. For example, knowing a day from 1 to 366 and a year, the `newDay:year:` class method can create a date instance for this date. Or, from a day and a month and year, the `newDay:-month:year:` class method can create a date instance for that date.

* Display the object returned from sending the message `today` to `Date`.

* Use the `newDay:year:` method to create December 31, 1999; assign it to a global variable `X`.

* Use the `newDay:month:year:` class method to create your birthday; assign it to a global variable `Y`. Read the comment in the method first to determine the form that it expects for its arguments.

* Verify that `X > Y` returns a sensible object.

## Rendering any Smalltalk object into text

The `printString` message attempts to return a string from any object at all, although the string may not be very informative. Some examples:

* To see how useful it is to be able to render an object as a string, contrast *displaying*: 'The bird is ' , `P2` with *displaying*: 'The bird is ' , `P2` `printString`

<footnote n="5">5 IBM Smalltalk also supports an infrequently used feature known as *block temporary variables*. These are variables that are declared inside a block for use only within that block. For example, in the block `[ lxl ... ]` the variable `x` has been declared and may be used freely within the block. If the block also has an argument, the form is `[ :number | lxl ... ]`.</footnote>
□ Similarly, contrast *displaying*:

Y, ' is my birthday

with *displaying*:

Y printString, ' is my birthday

Many Smalltalk implementations have a single `printString` method, located in class `Object`. IBM Smalltalk has a few, but not many, more implementations of `print-String`. (How many?!) How then is `printString` rich enough to render practically every kind of object into a meaningful text string? In fact, it is not at all rich enough. Instead, it invokes another method that is implemented individually in many classes; it is this method and not `printString` that does the brunt of the work of rendering objects into strings.

□ Find this method. How many implementations of it are there? (Hundreds!)

## 4.4 Smalltalk's debugger

### Debugging

□ Create a new application (or use one of yours), then a subclass `AAA` of `Object`, with an instance variable `iv` and an instance method `m` whose body is:

iv := 4.
self badMessage.
Transcript show: 'Done'.

### Execute:

AAA new m

The debugger window that appears is called a *walkback* because the list in the upper left windowpane lets you scroll, or “walk back,” through the method invocations leading to the error. Each line represents a class and method. The order is that in which the methods called each other, with the caller beneath the callee. In all, they depict the frozen stack of method invocations at the time of the error.
<figure><img src="image_37.png" /></figure>

The line `AAA>#m` indicates the method you wrote. Selecting this line displays your own code in the large windowpane, as you can see above. (The notation `AAA(XXX)>>#mmm`, means that although the object is an instance of AAA, the `mmm` method is inherited from the superclass XXX. Depending on the whim of the tool, the `#` may or may not be part of the notation.)

* Examine the present object (an instance of AAA) by double-clicking on `self` in the middle windowpane. An inspector opens on the object, from which you can determine the current value of the instance variable `iv`.

* You can fix the problem directly in the debugger, without having to use a browser: remove the erroneous message in the large windowpane, then *save* (recompile). Close the walkback window and verify that:

AAA new m

runs correctly.

## *Controlling execution step by step*

Once the debugger freezes the execution stack, you can often continue executing with the `into` button (which stops immediately after plunging down into the current, highlighted message), the `over` button (which stops after completely executing the highlighted message), the `return` button (which stops after completing the current method,
just before returning to its calling method), or the *resume* button (which executes as far as possible).

* Replace `self.badMessage` with `self.halt` in the preceding exercise, and again execute `AAA new m`. This time, experiment with the buttons.

## 4.5 Provocations

### Aliasing

* Display or inspect:

```
|r p|
r := Rectangle origin: 20@20 extent: 10@10.
p := r corner.
"p x: 50; y: 50."
r
```

Now remove the quotation marks, and *display* or *inspect* again. Did you expect `r` to change? `p` refers to `r`'s corner—`p` is an *alias* for the corner point. Thus, by changing `p`, `r` itself changes. In Smalltalk, aliasing occurs because variables are pointers, even though there is no syntactic cue that they are.

* Replace the third line with `p := r corner copy` and *display* or *inspect* again. This time, `r` is unaffected. That's because `p` is no longer an alias for the corner point itself, but a separate object that is a copy of the corner point.

Smalltalk shields programmers from the pointer bugs that afflict programs in languages with explicit pointers, but at the cost of making aliasing less apparent than in conventional languages.

### Concise reuse

* Write a method *foobar* in class *AAA* with this body:

```
"... Lots of code ..."
Transcript show: 'To be or not to be'.
"... Lots more code ..."
```

* Create a subclass *BBB* of *AAA*. Make instances of *BBB* behave the same as instances of *AAA*, except that they respond to *foobar* messages with 'My kingdom for a horse' instead of 'To be or not to be'. The ground rules are not to copy code—
for example, copying "... Lots of code ..." to another method would not be a concise form of reuse. Instead, consider modifying the foobar method in AAA and defining brand-new methods in AAA and BBB.

Because no one can anticipate in general how code will be used, or reused—we did not know of the requirement for BBB>> foobar until after AAA>> foobar was working—no one can expect to produce reusable designs without considerable trial and error. "Not until you try to reuse do you discover what's wrong" [Sarkela 1989].
CHAPTER 5

Abstract classes

This chapter and the next introduce essential object-oriented concepts that build on and go beyond the elemental principles of objects, classes, and inheritance.

Abstract classes are a simple idea that profoundly influences software design. The definition sounds paradoxical: an abstract class is a class that never has any instances. Why bother to build a class that won't have any instances? We'll spend this chapter answering this question, going so far as to argue that such classes are indispensable in good object-oriented design. We begin with some examples.

Class Magnitude is abstract. (See the drawing on page 14.) No one has any use for something as abstruse as an instance of Magnitude. Nevertheless, class Magnitude has subclasses like Date and Time, whose instances are quite useful. An abstract class can act as a center for gathering behavior and expectations common to its subclasses. In this case, as we saw on page 15, the behavior common to Magnitude's subclasses is comparability. For example, two instances of the subclass Date can be compared via messages like <=. Although Magnitude has no instances to enjoy this behavior, its subclasses evidently do.

Animal is another abstract class. We have little interest in an instance of class Animal—it's instances of Whale and Dog that we care about. This idea is not just a programming nicety; it's a cognitive distinction in the everyday world. The concrete objects we visualize are whales and dogs, not animals. What after all would something as abstract as an animal look like?

In Smalltalk, the most abstract of all abstract classes is class Object. An instance of class Object is too nebulous to be useful to a programmer. Yet class Object is an invaluable center for gathering expectations we have about all Smalltalk objects: all objects should be copyable, displayable, testable for equality with other objects, and so on. The idea sounds tidy, but there's a rub. Copying or displaying an object depends
a lot on the particularities of the object. It would be naive to hope that we could write code in class **Object** for copying or displaying and have it work meaningfully for all subclasses. That's why an abstract class is a repository for *expectations*. We *expect* objects to be displayable and we *expect* animals to move, but how they do it depends on the kind of object or animal. The actual code to display and copy is likely to reside in concrete subclasses, not the abstract class.

## 5.1 Exercise in object-oriented design

Consider this fictitious hierarchy of class **Table** and its subclasses. An instance of **ArrayTable** is organized as an array; that is, its elements are stored at consecutive offsets in memory, the first at the first offset, the second at the second, and so on. An instance of **LinkTable** is organized by a chain of pointers; its elements are scattered through memory, the first pointing to the second, the second to the third.... We are going to examine the object-oriented implications of searching these tables.

<figure><img src="image_38.png" /></figure>

Here's some plausible pseudo-code for a search method:

search for an <item>
    start
    loop while (not end and next ≠ <item>)
        end loop
    if end then return not_found
    else return found

Underlines indicate methods. Thus the **search** method calls three other methods, namely **start**, **end**, and **next**.

In which classes should each of these four methods be coded?

## 5.2 Solution and discussion

We begin with **next**. The way in which a table advances to its next element depends on the kind of table. An **ArrayTable** adds 1 to its current index (**index** := **index** + 1) while a **LinkTable** updates a pointer (**current** := **next**). Since the logic is different, the two subclasses will need their own separate versions of the **next** method.
The situation for the **start** method is similar. An **ArrayTable** starts by initializing the index to the first element (**index** := 1) while a **LinkTable** initializes the pointer to the head of the chain (**current** := **head**). Again, separate versions of **start** must occur in the two subclasses. There also must be two versions of the **end** method: an **ArrayTable** must test for the upper limit of the array (**index** > **upper**) while a **LinkTable** tests for a null pointer (**current** = **nil**).

So far, then, we're forced to write separate versions of the **start**, **next**, and **end** methods in the two classes **ArrayTable** and **LinkTable**:

<figure><img src="image_39.png" /></figure>

Do we also need two versions of the **search** method? That would be foolhardy, for the code in both versions would be identical; both would simply be based on the pseudo-code illustrated above. Instead, we will write it once, in class **SequentialTable**, and let the subclasses inherit it:

<figure><img src="image_40.png" /></figure>

Now, why not move **search** still higher, into class **Table**? Because our **search** method has a strongly sequential flavor, and some kinds of tables behave in non-sequential ways. Consider a hash table, for example. A hash table searches directly instead of sequentially. Given a search item, the table uses the item itself to calculate ("hash") a position where the item may reside. This kind of table doesn't iterate through its items one by one. Hashing calculations don't resemble the sequential pseudo-code above at all. Therefore a hash table needs its own version of **search**, so we end up with our methods distributed through the hierarchy like so:
<figure><img src="image_41.png" /></figure>

## 5.3 Pure virtual (subclassResponsibility) methods

So far, Table has no behavior at all. We dared not write search there, because its subclasses required their own versions. On the other hand, one could argue that a class with a name like Table ought to be searchable; we expect any table to be searchable. Object designers settle this quandary by boldly writing a search method in Table anyway, but one that does nothing. This disembodied method is variously called a pure virtual function (C++), implementedBySubclass or subclassResponsibility method (Smalltalk), a deferred routine (Eiffel), or an abstract method (Java). I will use these terms interchangeably, even the C++ term pure virtual, because it is so evocative. (What could do less than something that is purely virtual?)

Why bother with a method like Table>>search that does nothing? There are two reasons: it announces to potential consumers of Table's subclasses that they ought to be able to find things in any table by using a method named search. And it announces to the programmers who will write any Table subclasses that they are obligated to supply a search method. At the very least, then, a pure virtual method is effective documentation. In Smalltalk, it's little more than this; the pure virtual search amounts to an informal contract between Table consumers and Table developers. Nothing enforces this contract. But in a language like C++ where the compiler can settle contract disputes, once the designer specifies a pure virtual function, the subclasses must provide a concrete ("do-something") implementation of the function, or the code will fail to compile. That is, a pure virtual function in C++ enforces the contract between consumers and developers.

Notice one logical consequence of pure virtual methods: a class that has such a method is necessarily an abstract class. An instance of Table is nonsensical, since it has no working code for its search method.
## 5.4 Exercise: discovering pure virtuals

* Returning to our example, the hierarchy contains, in addition to Table, one other abstract class. Which class is this, and does it present another opportunity for pure virtual methods?

## 5.5 Solution and discussion

Do any other classes in the hierarchy have no instances? SequentialTable is such a class. Its subclasses can have instances because they support a full complement of behavior, namely start, next, end, plus an inherited search, but any instances of SequentialTable itself would be worthless. Hence SequentialTable is an abstract class.

Now an abstract class is rather hollow unless we have a sense of what can be expected of it. The mechanism for recording these expectations is to declare pure virtual methods. What should these methods be for SequentialTable? The suspects are, of course, start, next, and end. Not only are these natural qualities of sequential-ness, the search pseudo-code actually demands their presence. What better way to remind the ArrayTable and LinkTable developers to implement them than to declare them as pure virtual, subclassResponsibility methods? The final hierarchy, then, looks like this:

<figure><img src="image_42.png" /></figure>

## 5.6 Ensuring no instances

We have determined that Table is an abstract class; an instance of it would be worthless because it would not have sufficient executable behavior. It would be nice if object-oriented languages could protect programmers from mistakenly creating such an instance. Smalltalk can't quite. The best it can do, if a wayward instance of Table has been created, is to alert the programmer at the time the instance receives a search message. If Table>>search is absent, the message triggers the familiar doesNotUnderstand: walkback that occurs whenever an object receives a message that it can't resolve.
The walkback duly alerts the programmer, but the preferred technique is not to omit search, but to write the method as follows:

search: anItem self subclassResponsibility

Then any attempt to send the search message to an instance of Table will invoke the subclassResponsibility method. This method too produces a walkback, but one that specifically describes its cause as the absence of a proper implementation of search. As we discussed earlier, writing search in this way also delivers the most important service of pure virtual methods—documentation of the abstract class.

Compiled object-oriented languages like C++ can do even better. By specifying even one pure virtual function in a class, the compiler rejects any code that declares an object of that class. Thus, the mere presence of a pure virtual function guarantees that the class will have no instances and will really be abstract.<fnref n="1" />

In either case, Smalltalk or C++, the goal is the same: we don't want programmers to use instances of the abstract class because the abstract class lacks a full complement of behavior. It presents expectations but doesn't have the assets to back them up.

*Technical aside:* Sometimes a shrewd designer will write a benign method in an abstract class with no code at all, not even the message self subclassResponsibility. Here's an example:

customInitialize "This method does nothing, not even cause a walkback! It executes harmlessly, but if you wish to provide some subclass-specific initialization code, feel free to override it in your subclass."

Let's say that some method in the abstract class (perhaps its initialize method) executes some standard code, but along the way also executes self customInitialize. The programmer of a subclass can optionally override customInitialize to do something special, but if she does not, the inherited customInitialize method executes harmlessly. The designer has therefore opened an optional back door for custom code, analogous to what was called a user exit in the heyday of mainframe system software. Today these back doors are sometimes referred to as hook methods.

<footnote n="1">¹ The C++ jargon for an abstract class is an ABC, or abstract base class.</footnote>
## 5.7 Concrete behavior in abstract classes

Let you write off abstract classes as devoid of substance, you should know that it's possible and often beneficial to imbue them with concrete behavior too. In other words, not all methods in an abstract class need be pure virtual. The class may still have lots of code that is shareable among its subclasses. For example, Smalltalk's Collection class is an abstract class with plenty of behavior its concrete subclasses—Array, Set, SortedCollection, and many others—gratefully inherit.

A concrete method in an abstract class will sometimes appear to invoke one or more pure virtual methods. This is not as odd as it sounds. In the table example we just studied, the search method in class SequentialTable is a concrete method that appears to invoke SequentialTable's pure virtual methods next, start, and end. These pure virtual versions actually never execute. Instead, because we use only instances of the subclasses of SequentialTable, the concrete, overriding versions execute. This is such a typical characteristic of sound object-oriented designs, and so often misunderstood by newcomers, that I want to belabor the point by examining another example.

Consider a method max: that returns the maximum of two magnitude objects. Nothing deters us from implementing max: concretely in the abstract class Magnitude:

```perl
max: anotherMag
    self < anotherMag
    ifTrue: [ ^anotherMag ]
    ifFalse: [ ^self ]
```

The odd aspect of this code is that although it is in class Magnitude, it uses a method, <, that cannot be implemented in class Magnitude. (That's because comparisons like < depend on the internal representation of an object, and these representations differ from subclass to subclass. For instance, the representation for objects of the Time subclass differs from that for the Float subclass. That's the "catch" we discussed on page 15.)

With this background—that max: uses a method that must be defined in subclasses—what kinds of objects in the Magnitude hierarchy can execute max:'s code? Clearly not instances of Magnitude itself, since Magnitude is abstract and should have no instances. Hence, only instances of subclasses qualify. Consider 13.7, an instance of Float, and the message:

```perl
13.7 max: 17.3
```

The relevant portion of the class hierarchy is:

<figure><img src="image_43.png" /></figure>
Now 13.7's class, Float, doesn't implement max: . Thus 13.7 searches up its inherit- ance tree until it finds a superclass that does implement max: —in this case Magni- tude . The max: code above then executes. The first line sends the binary message < back to self (13.7). This time 13.7 recognizes < as a method that its own class Float implements, and hence executes it without recourse to inheritance. The result is true (because anotherMag is 17.3), and so the code executes the branch that returns 17.3 ( anotherMag ) as the final result.

To recap, the code for max: was written in Magnitude with the full understanding that it depends on pure virtual methods that can't possibly be written correctly in Magnitude . No instances of Magnitude , only instances of its subclasses, can success- fully execute max: . And finally, because the code in max: refers to self , execution can flow from the superclass method ( max: ) down to the subclass method (<) .

This example is typical of sound object-oriented design. It maximizes reuse because there is just one max: method and as many versions of < as necessary, but no more than are necessary. More important, subclass implementors can direct their attention to sub- class-specific methods like < ; they enjoy the benefit of max: without thinking about it.

You should seek opportunities to write reusable methods like max: in your own applications. Unfortunately on larger projects, where different subclasses are written by different developers, opportunities for unifying common function aren't often rec- ognized. In effect, each developer writes a slightly different version of max: . The price is redundant thinking, design, code, and especially maintenance. The redundancy can cost hours and days when the methods in question are more complex than max:

5.8 Summary: methods in abstract classes

The methods in an abstract class have three primary forms. Some are pure virtual (sub- classResponsibility, deferred, abstract, implementedBySubclass); subclass developers must override them with concrete implementations. Some are concrete and self-contained; subclass developers inherit them without any obligations. And some are like max: (or SequentialTable >> search ) above; subclass developers are obligated to provide some con- crete behavior that the method needs, but they do not override the whole method.

There is no consensus on terminology for distinguishing the three forms, but [Wirfs-Brock et al. 1990] and [Johnson and Russo 1991] call them abstract methods (the Java term), base methods , and template methods , respectively. [Gamma et al. 1995] also call the last kind template methods . I think of them as yo-yo methods because exe- cution bounces up and down with respect to a subclass, and framework designer Kirk Wolf refers to the phenomenon as an apparent down-call .

You will see in Chapter 19 that abstract classes and these three kinds of methods are at the heart of object-oriented frameworks.
CHAPTER 6

Containers and other indispensable ideas

In the everyday world, containers—things that contain other things—are everywhere. Pots, spoons, baskets, buses, countertops, books, CD-ROMs, and pea pods are all containers. Containers commonly even contain other containers. My kitchen contains a pantry, which in turn contains shelves, which in their turn contain boxes and cans, which contain cereals and soups. My kitchen also contains a refrigerator, which contains shelves and a door, both of which are also containers.

Containers are such indispensable everyday objects that we should expect them to also be indispensable software objects. The patterns that occur among software objects should reflect the ones that we observe among everyday objects.

For a programmer, important containers include queues, stacks, arrays, sets, and the like. Object-oriented programmers, and especially Smalltalk programmers, sometimes call containers collections. That's because the container classes in Smalltalk are all subclasses of an abstract class named Collection:

<figure><img src="image_44.png" /></figure>

For our purposes, collection and container are interchangeable.
The hierarchy above shows just a few of IBM Smalltalk's container classes. Here are the most commonly used Smalltalk containers, and some of their distinguishing characteristics.

<table><thead><tr><td>Class</td><td>Characteristics</td></tr></thead><tbody><tr><td>Dictionary</td><td>Like a real dictionary, it organizes information by a lookup key.</td></tr><tr><td>Array</td><td>Its elements are arranged in consecutive slots. Also, its size is fixed.</td></tr><tr><td>OrderedCollection</td><td>Like an array, but its size may increase or decrease.</td></tr><tr><td>Set</td><td>Its elements are not arranged in any order. Also, an object can occur in it at most once.</td></tr><tr><td>String</td><td>It contains 0 or more characters.</td></tr><tr><td>byteArray</td><td>Like an array, but its elements are bytes.</td></tr><tr><td>SortedCollection</td><td>Smarter than an ordered collection, it maintains its elements in an ordering determined by some sorting criterion.</td></tr><tr><td>IdentityDictionary</td><td>A special, efficient dictionary, suitable mainly if the keys are Symbol or SmallInteger objects.</td></tr><tr><td>Stream (not a collection, but similar)</td><td>Smarter than a collection, it remembers where it was last accessed.</td></tr></tbody></table>

A final word of introduction to the study of containers: practically every object-oriented design you do will require one or more containers, including your first sizable design exercise in the next chapter. Learning to recognize the need for containers in your designs is a major step toward becoming a good object-oriented designer.

## 6.1 Heterogeneity and homogeneity

In the everyday world, some containers, such as drawers, hold many kinds of things and others, such as three-ring binders, hold just one kind of thing, such as pages. Smalltalk's containers are like the drawers. That is, a typical Smalltalk container won't verify that its contents are all of the same type; it can hold integers, or whales, or even a mixture of integers and whales. This drawer-like property, the ability to hold heterogeneous elements, is attractive but potentially dangerous. Its attraction is evident: you
can pick up and use a container without worrying about whether it will work for the kinds of objects you want to hold—it’ll hold any Smalltalk object. On the other hand, if your container is one that maintains elements in sorted order (see the exercise in the next section), what good would it be to hold a mixture of integers and whales, or for that matter, whales alone? Or, suppose you have a set that presently holds integers, but you’ve accidentally deposited a whale into it. If you double all the elements, the whale will protest, via a walkback, that it doesn’t understand multiplication by two.

6.2 Exercise: heterogeneity and homogeneity

Ordered collections are like arrays, except that their size is not fixed. Define a class **Whale**, then explore heterogeneity by displaying the following. (Don’t forget to declare global variables like OC.)

OC := OrderedCollection new. OC add: ‘a‘; add: ‘c‘. "OC add: Whale new." OC.

Remove the quotation marks and try again. This exercise demonstrates that the ordered collection is able to accommodate any kind of object. However, if you want to do something meaningful to OC, its heterogeneous contents are a problem. Why does executing the following code produce a walkback?

Pet := ‘t‘. OC do: [:elem | Pet := elem , Pet]. Pet

But if you now re-comment the whale line by replacing the quotation marks, and display the whole sequence of statements, from beginning to end, the errors vanish and Smalltalk displays ‘cat‘.

Another subclass of class Collection is SortedCollection. An instance of class Sorted- Collection is a collection whose objects are always in sorted order. Display:

X := SortedCollection new. X add: 3; add: 2; add: 5. X

What defines the order? The answer is that every SortedCollection object has a sort block that defines the ordering operation. The default operation is <= . Reverse the order by displaying:
```
X sortBlock: [:a :b | a >= b].
X
```

□ How heterogeneous is a sorted collection? Unlike a set, which accepts any object you add to it, a sorted collection starts sending comparison messages as soon as you add more than one object. If an object you add isn't comparable, the sorted collection will protest with a walkback. For example, *execute*:
```
X add: Whale new.
```

Thus the first object you add to a sorted collection can be of any class, but all subsequent ones had better be comparable to the first.

## 6.3 Exercise: dictionaries

□ Looking things up—in dictionaries, phonebooks, software help files, relational database tables, and so on—is an elemental activity for both humans and computers. Smalltalk's container class for this activity is **Dictionary**. Dictionaries are among the most widespread containers in a typical Smalltalk application. (Arrays, however, are even more prevalent.) To see the relative occurrence of these objects in your current image, *display* these lines, one by one:
```
Set allInstances size.
Dictionary allInstances size.
Array allInstances size.
String allInstances size.
```

□ A Smalltalk dictionary consists of entries that Smalltalk calls *associations*. Each association has a key and a value. *Executing*:
```
X := Dictionary new.
X at: 'Kilauea' put: 'Most active volcano';
at: 'Denali' put: 'Formerly Mt. McKinley'.
```

constructs a new dictionary with two associations whose keys are geographic names and whose values are descriptions of the associated places. You can look up an association by *displaying*:

```
X at: 'Denali'
```

or you can examine the entire dictionary by *executing*:

```
X inspect.
```
## 6.4 Preparatory exercise: identity versus equality

Like any object system, Smalltalk maintains a critical distinction between *identity* and *equality*. You will need to grasp this distinction to understand identity dictionaries in the next section.

To say that "two" objects are identical is to say that they are actually the same object. The message selector that tests for this condition is `==`. As an example, `X == X` results in the true object, no matter what object the variable `X` may refer to.

* The `==` message can be used to resolve some fundamental questions in Smalltalk. For one, do different occurrences of an integer refer to different objects or the same object? To answer this question, execute the first two lines below, one at a time, then display the last line:

```
X := 3.
Y := 3.
X == Y.
```

Since the result is the true object, we conclude that there is only one 3 object in all of Smalltalk. (The same is true for any "small" integer, which means technically any instance of the class `SmallInteger`. Each dialect of Smalltalk has a range, beyond which an integer is no longer an instance of `SmallInteger` but `LargeInteger`. For IBM Smalltalk, this range is from $-2^{30}$ to $+2^{30}-1$, or $-1073741824$ to $+1073741823$.)

* Symbols are like integers: there can be at most one symbol with a given spelling, as you can verify by executing these lines, one at a time, and displaying the last one:

```
X := #Hobbes.
Y := #Hobbes.
X == Y.
```

On the other hand, repeat the experiment, again line by line,<fnref n="1" /> with:

```
X := 'Hobbes'.
Y := 'Hobbes'.
X == Y.
```

<footnote n="1">¹ In some Smalltalk dialects, including IBM's, the behavior of examples like these depends on whether the code is compiled all at once, or piece by piece. When compiled all at once, the compiler can perform optimizations that camouflage the striking results we want to see.</footnote>
The result, **false**, forces us to conclude that the two instances of the string 'Hobbes' are distinct from each other. In other words, strings are not identical, even if they consist of exactly the same characters! Picture it in this way:

<figure><img src="image_45.png" /></figure>

Just one

<figure><img src="image_46.png" /></figure>

Possibly many

<figure><img src="image_47.png" /></figure>

The other test, *equality*, uses the message selector `==`. This is a weaker test than identity. In rough terms, equality merely measures whether two objects are "indistinguishable." The precise meaning of "indistinguishability" depends on how the programmer defines it for a given class; that is, on how the programmer overrides the `==` method.

□ Execute the first two lines, one at a time, and *display* the last:

X := 'Hobbes'.

Y := 'Hobbes'.

X = Y.

The result, **true**, tells us that the two strings are *equal* to each other, even though we have just seen that they are not the same, *identical* string object. Thus, objects may be equal—indistinguishable—without being identically the same object. On the other hand, identical objects are necessarily equal.

Identity is such a fundamental Smalltalk notion that if you override the `==` method Smalltalk ignores your override.<fnref n="2" /> By contrast, you can override the `=` method at will. Therefore, in your own classes, the definition of equality—"indistinguishability"—is entirely up to you. As a case in point, Smalltalk's designers decided on their own definition of equality for strings, namely that two strings are equal if they contain the same characters in the same order. But before you override equality in your classes, read the upcoming section "Overriding equality."

## 6.5 Identity dictionaries

Class **Dictionary** has a famous subclass named **IdentityDictionary**. These two kinds of dictionaries use different tests to determine whether two keys are the "same." Ordinary dictionaries use the equality test, and identity dictionaries use the identity test.

<footnote n="2">² Actually, there is an uncommon way to force your own `==` method to execute. See the technical aside on page 197.</footnote>
What's more, in many Smalltalk products, the implementations of `at:put:` and `at:` in class `IdentityDictionary` execute faster than in class `Dictionary`. And identity dictionaries occupy less storage than ordinary dictionaries. When performance matters, identity dictionaries may be preferable. But you can use them only if equal keys are also identical. For example, using strings as keys in identity dictionaries is inadvisable. That's because most programmers who write code like:

```
someDictionary at: 'Hobbes' put: '17th century philosopher'.
someDictionary at: 'Hobbes' put: 'stuffed tiger'.
```

expect the second `at:put:` to replace the value `'17th century philosopher'` by `'stuffed tiger'` at the (sole) dictionary entry for `'Hobbes'`. Ordinary dictionaries indeed behave this way. If, however, the dictionary is an *identity* dictionary, we know that the two strings are distinct objects, so that, contrary to expectation, a separate second entry will be created.

To summarize, almost all identity dictionaries in practical use have keys that are either small integers or symbols. These make suitable keys for identity dictionaries because for these kinds of objects, equality implies identity. For most applications, ordinary dictionaries suffice, and they have the advantage of operating reliably for any kind of key at all.

## 6.6 Exercise: identity dictionaries

Explain why this code, executed line by line, produces a walkback:

```
X := IdentityDictionary new.
X at: 'Heidegger' put: 'Difficult existentialist'.
X at: 'Heidegger'.
```

## 6.7 Overriding equality

We've seen that developers have the prerogative of overriding the `=` method as they please in their own classes (page 74). Those who do, however, risk introducing a subtle bug into their programs. They will find, for instance, that objects they add to a set may appear not to be there later on. I call this the "anomaly of the disappearing element," and you will experiment with it in the exercise in the next section.

Here's how the anomaly occurs: sets use hashing to determine where to insert an added object, and the default hashing algorithm produces different hash values for two distinct (non-identical) objects. The set therefore tends to place non-identical objects in different positions, which is ordinarily desirable and harmless. But if the
developer overrides the = method so that the two distinct objects are equal, adds the first one to the set, then searches the set to see if the second, equal one is present, expecting that it is, he will find that it isn’t. That’s because the set will begin its search at a different position, determined by the different hash value of the second object. The developer’s error was to expect the second object to behave as though it were identical to the first, when in fact it is only equal to the first.

This scenario may seem unlikely, but it arises in client/server systems, which commonly use a proxy for an object to stand in for the object itself. To determine which proxy stands for which object, the system uses an overridden equality test that compares a problem-specific datum (like a social security number or other unique identifier) in the proxy and the object. Although the proxy and its object aren’t identical, they are equal because they have the same identifying datum. The system then treats the proxy and its object as though they are the same, which was the purpose for overriding equality. But it also exposes the system to the “anomaly of the disappearing element.” The different hash results of the proxy and the proxied object specify different positions for the two objects:

<figure><img src="image_48.png" /></figure>

To prevent this anomaly, whenever you override the = method for a class, also override the hash method. Whatever the = method compares, write the hash method so that it hashes the same thing. In the client/server example above, if the = method compares a social security number, write the hash method so that it too hashes the social security number. This ensures that when a set hashes to determine the position of an object, it will compute the same position for both the proxy and its object.

## 6.8 Exercise: anomaly of the disappearing element

* Write a subclass Book of Object with an instance variable isa and methods set-Isbn: and getIsbn that simply set and answer the instance variable. Override the = method so that it compares ISBN numbers:
  = anotherBook
  ^self getIsbn = anotherBook getIsbn
The following code will construct a library with an initial capacity of 100 holdings, add a holding, then test the library for the holding. *Execute* the first two lines, one at a time, then *display* the last line:

```
Library := Set new: 100.
Library add: (Book new setIsbn: '0-671-20158-1').
Library includes: (Book new setIsbn: '0-671-20158-1').
```

The result, *false*, demonstrates the anomaly of the disappearing element. (The set is large enough that it is statistically unlikely for the result to be *true*, but if it is, adjust the size of the set.) Now amend class *Book* so that the anomaly does not occur.

* Once you've solved the preceding exercise, here is an additional wrinkle. An object's identity may occasionally change. Perhaps the book has been re-assigned a different ISBN number. This change affects future searches through the library: the book will again not be found. Why not?

## 6.9 Exercise: excursion into Streams

Stream classes are not officially under Smalltalk's Collection hierarchy, but streams are so closely allied with collections that this chapter is a sensible place in which to introduce them. Streams do something that collections cannot: a *Stream* remembers where it was. You can work somewhere in the middle of one, go away for a while, and then continue working on it at the same place you were before. For example, a stream over a string can remember where you last accessed one of its characters, so that at any time you can ask the stream for its *next* character. Collections cannot remember where something last happened to them.

* Predict the result of *displaying* this code:

```
|stream|
stream := ReadStream on: 'Van Gogh'.
stream next; next; next; next; next; next.
```

Notice that the stream remembers its position between *next* messages.

* One of the most common everyday programming problems is having to construct a string from various sources of information, then passing it off as an argument to some distant object. Complete this code sequence:

```
|string|
string := "You write a few lines".
Transcript show: string.
```
in such a way that executing the sequence will produce this text in the transcript:

*Sunflowers*

*Irises*

*Starry Night*

*Hint*: When you want your string to advance to the next line, you have little choice but to physically advance using the <enter> key on the keyboard. Unfortunately, the resulting code is awkward to read and maintain.

It is more elegant to create a stream and incrementally add chunks to it until it is complete. For incremental processing, streams excel and strings founder. It is contrary to a string's nature to grow, since a string has a fixed length.

* To illustrate this approach, reproduce the result above by completing this code sequence:

```csharp
|stream|
stream := ReadWriteStream on: ''.
stream      cr;
            nextPutAll: 'Sunflowers';
            "You write a few messages".
Transcript show: stream contents.
stream close.
```

To summarize, if you need to access or add consecutive elements of a collection, you will have to write code that keeps track of the positional information. Better to use a stream, which relieves you of this obligation by absorbing the responsibility into its own behavior.

## 6.10 Containers versus aggregations

Aggregations and containers share a main characteristic: a bigger thing holding smaller things. They differ in that an aggregation is, by convention, a rigid relationship between an object and its parts. The makeup of a container, by contrast, is expected to evolve, with elements taking up residence and departing over time. A telephone, comprising a handset, a dial, and so on, is an aggregation. So too is a compiler, comprising a lexical analyzer, a parser, and a code generator. On the other hand, a set or a queue is a container, one of whose principal responsibilities is the comings and goings of objects within it. Containers should therefore respond to add and remove requests.
You can verify this property by browsing through Smalltalk's **Collection** hierarchy and noticing all the **add:** and **remove:** methods.<fnref n="3" /> An object like a telephone for which pickup and dial, rather than add and remove, are the more apparent behaviors, should not be designed as a container.

The trouble is that this apparent distinction is sometimes not so crisp. Whether an object has the rigidity of an aggregation or the plasticity of a container is a distinction in degree only. Consider the leaves on a branch. They are rigidly located at fixed locations on the branch, yet they come and go from year to year. One could argue that a branch is an aggregation or a container.

In many situations an object is predominantly an aggregation but also has containment properties. A human body is an aggregation of limbs and organs, yet it also contains blood cells that are continually replenished. That doesn't make the body a container—you wouldn't define it as a subclass of **Collection**. It is an aggregation, but one of the components of the aggregation happens itself to be a container, namely, the **circulatorySystem**, which is a container of blood cells. The component of the body, rather than the body itself, is the container.

Similarly, a class browser, though principally an aggregation of user interface widgets, also contains the collection of methods for the class it browses. Again, the browser itself is not a container, but one of its constituents—its **methods** instance variable—is an instance of **SortedCollection** that contains methods.

Designs that resemble these decompositions are plentiful. A body and its circulatory system, a browser and its methods, or a refrigerator and its vegetable drawer are all objects with many sub-objects, one or more of which is a container object. You will see several of these designs in this book; they represent a design pattern, the *smart container*, in Chapter 18.

## 6.11 Shallow and deep copying

Copying an object sounds straightforward. In fact, it's one of the subtlest and most trouble-prone areas in object-oriented programming. The essential question arises when an object refers to other objects. Consider a container. If we copy the container, what should happen to the elements in it? For an even simpler example, suppose one object has an instance variable v that points to a second object and we copy the first. What should happen to the second?

<figure><img src="image_49.png" /><figcaption>Before copying</figcaption></figure>

<footnote n="3">³ In some dialects, **add:** and **remove:** are pure virtual (subclassResponsibility) methods in **Collection**, reminding us that the subclasses are obligated to support adding and removing.</footnote>
The question has two possible answers. If the element or referenced object is also copied, the copy is *deep*; if it isn't copied but instead shared, the copy is *shallow*.

<figure><img src="image_50.png" /></figure>

As the drawing illustrates, shallow copying is appropriate when you intend to share the referenced objects. Container objects are usually shallow copied because we intend to share their contents. In fact, shallow copying is the prevalent (and default) copy in Smalltalk. A realtor, for example, would prefer a shallow copy of the county's collection of real estate listings because he can then be sure that he and everyone else is modifying the same, shared entries. (He'd be even happier to have access to the master collection itself rather than any kind of copy at all, for then he could also keep up with deletions and new listings.)

Deep copying is appropriate in some situations. A Xerox copy is a deep copy because the copy and the original don't share anything. The copy is a complete clone of the original. Deep copying is also often appropriate for aggregations—a house and its garage, for example, or a bicycle and all its parts and, recursively, all their subparts. Two houses shouldn't share one garage, nor should two bicycles share one seat. Aggregations generally retain rigid associations with their components.

There is, however, a gray area between deep and shallow copying. Suppose the house has an instance variable for its builder and we intend for copies of the house to share the same builder. Then copies of the house should have both shallow and deep characteristics. They must be shallow, to share the builder, and deep, to replicate the garage, as well as the kitchen and other rooms. This example illustrates that the developer of any class whose objects are likely to be copied must design its copy method in accordance with the sharing requirements of the object's instance variables.

## 6.12 Commentary: value and reference semantics

Smalltalk is based on reference semantics. Its programming model relies on pointers that refer one object (or variable) to another. In Smalltalk, though you may think of a bicycle object having a seat object embedded in it, the bicycle object merely has a pointer to the seat object. Thus, when a message passes argument objects, it is really
passing pointers to those objects. (At a machine level, little objects like characters and small integers are passed around bodily and indeed embedded in bigger objects rather than pointed to by those bigger objects. But a Smalltalk programmer’s conceptual view is pointer-based; that is, reference semantics.)

By contrast, C++ supports *value* semantics as well as reference semantics. A C++ programmer may optionally embed a seat solidly into a bicycle. Also, messages frequently pass an object around by passing a copy of the object instead of a pointer to the object. Because of this tendency for C++ code to copy objects, C++ programmers discipline themselves to think rigorously about whether their copies should be deep or shallow. Copying demands so much attention in C++ that each class has a special feature (a *copy constructor*) with which the programmer defines just how copying of its instances should work. Smalltalk programmers tend to be less disciplined in thinking about copy behavior, and get away with it because copying occurs so much less frequently in Smalltalk.

## 6.13 Commentary: containers in C++

C++ containers are like three-ring binders: they generally hold objects from a single class (or subclasses of that class). These containers are less flexible than Smalltalk’s, but safer, for any code that attempts to add an object of the wrong class to a C++ container fails to compile. This safety comes at a price, though, because you need to develop a class of container specialized for each kind of object you intend to hold—a *SetOf-Whole* as well as a *SetOfInteger*. A C++ language feature (*templates*) simplifies the definition of such container classes, but container libraries in C++ still tend to be unwieldy, complex, and difficult to write. The need for fast, robust containers has spawned a cottage industry for container libraries. Sometimes these libraries are called *foundation* libraries, to acknowledge their essential place in object programming. Sadly, foundation libraries are sometimes not interchangeable,<fnref n="4" /> because they are often integrated into larger libraries or frameworks that provide other services like windowing or communications or persistence. By contrast, every Smalltalk dialect includes an integrated *foundation library*—the subclasses of *Collection*. This library cannot be decoupled from Smalltalk because so much of Smalltalk itself is built using collection classes.

<footnote n="4">⁴ Standardization will help. The ANSI C++ standard now specifies a *Standard Template Library*.</footnote>
CHAPTER 7

CRC cards

We now shift from the essential concepts of containers and object identity to a con- crete design problem, and some techniques to help solve it. After working through the design here you will, in Chapter 8, write the Smalltalk code to implement it.

Probably no object-oriented subject fuels as much debate as object-oriented design methods. 1 The question of what contributes to a good design method is large and inter- esting, but not our focus in this book. Rather, I present a simple technique that helps with one inescapable step in designing an application—discovering classes. This tech- nique is a simplification of CRC cards, an idea published in 1989 by Kent Beck and Ward Cunningham. Since then CRC cards, or Class-Responsibility-Collaboration cards, have been widely used and imitated. (See the commentary at the end of this chapter.)

Start with a pile of index cards, 3 x 5 inches or 4 x 6 inches, as you wish. (Their paper stipulated 4 x 6 inches, but Kent and Ward themselves don’t agree.) If you don’t have index cards, tearing up several full sheets of paper into quarters is almost as good. On each card, sketch an instance of an object:

<figure><img src="image_51.png" /></figure>

<footnote n="1">1 Also known as methodologies. Methods is the trendier, more precise term, but suffers from already meaning something else to object-oriented programmers. I’ll use the terms interchangeably, except where there is risk of confusion.</footnote>
Record as responsibilities whatever you think instances of the class ought to be able to do, the “know-how” that instances should have. Record them at a level of detail you find helpful. For example, you may first want to describe the responsibilities of a traffic-light object broadly: “Mediate orderly flow of vehicles through an intersection.” Later, if you’re almost to the point of writing code, you might describe responsibilities more concretely: “advanceColor,” “initializeGreenDuration:,” and so on. Whatever you do, don’t use the cards dogmatically. They are an informal tool, and they should stimulate your creativity rather than limit it.

If you feel unhappy about something you’ve written, throw away the card and start again. Cards are inexpensive, and disposability is one of their happiest virtues. In this early phase, the price one pays for stupidity ought to be low; the more dumb ideas you can discard early, the better your final design will be. This is an eternal human truth, even for the most successful thinkers. Francis Crick, who shared a Nobel prize for discovering the double-helix structure of DNA, said, “If we deserve any credit at all, it is for… the willingness to discard ideas when they become untenable” [Crick 1988]. The software designer who doesn’t explore some dead ends won’t learn much.

Another virtue of CRC cards is tangibility. Designers wave them around for emphasis, move them as arguments of a message, or arrange them on the table to illustrate relationships. This tangibility explains why attempts to represent CRC cards in computerized tools have been disappointing. Entombing them in a computer, no matter how advanced the user interface may be, constrains your thinking at a time when you need to excite your imagination and brainstorm as much as possible. The time for methodical thought comes later.

## 7.1 Design exercise

* Use CRC cards to design a simple personal-computer application that could keep track of a checking account. Transactions should be retained in a log or register, and ordered by date.

Remember to explore competing alternatives and throw away cards that are least promising. In the next chapter you will write the code for this exercise, so keep the design simple—don’t get bogged down in all the detailed kinds of data that a full-blown application needs, and don’t go overboard into extensions like on-line checking. Aim for a range of two to five cards. Finally, remember the lesson in Chapter 6: containers are essential participants in almost every object-oriented design.
## 7.2 Solution and discussion

If you have trouble getting started, try looking for nouns and verbs in the problem description. Nouns are candidates for objects, and verbs are candidates for responsibilities or methods. This is a suggestion, not a general rule. (For example, in Chapter 15, verbs will also be excellent candidates for objects. Design always depends on the problem at hand.)

From the problem statement, these nouns are promising: account, log, transaction, and date. We know from our earliest glimpses of Smalltalk that class Date is already available in Smalltalk. Let's concentrate then on the other three classes, beginning with some plausible responsibilities for them:

<figure><img src="image_52.png" /></figure>

Although account balances and transaction amounts are not explicit in the problem statement, they seem like unavoidable elements. On the other hand, I've chosen to omit a host of ancillary elements—account number and description, check number, payee, memo—on the grounds that they would contribute little to understanding the essential object interactions that we are after. Adding such information would be straightforward and accurate but distracting. Note that I've overlain the edge of the Log card on the Account card to emphasize the close collaboration implied by the responsibility, "The account keeps a log."

So far, the transaction objects are bland. This is about to change. The log's chief responsibility—sorting—recalls a class we worked with in Chapter 6 with exactly this responsibility. That class was SortedCollection (page 71). Thus, rather than defining a new Log class, we will reuse the SortedCollection class. Remember that a sorted collection object sorts the objects added to it, provided that its sortBlock makes sense for
the objects. The default `sortBlock` assumes that the objects understand the `<=` method. That's why integers and their kin are all automatically sortable. To ensure that transactions are sortable via the default `sortBlock`, they too must be comparable via `<=`. Therefore an additional responsibility for the transaction card above is, "Comparable to one another."

With an eye toward eventual implementation, we can summarize our observations with a more detailed, Smalltalk-biased version of the cards:<fnref n="2" />

<figure><img src="image_53.png" /></figure>

The dashed lines around `SortedCollection` indicate that it doesn't warrant a new card or class because, like `Date`, it is already present in Smalltalk. That leaves just two classes to write, `Account` and `Transaction`. The kinds of objects the methods expect as arguments, omitted from the drawing to reduce visual clutter, are:

* `handleTransaction: aTransaction`

* `initialBalance: anInteger`

* `initialAmount: anInteger date: aDate`

* `<= anotherTransaction`

* `add: aTransaction`

* `remove: aTransaction`

where `anInteger` represents a monetary amount, such as dollars.

<footnote n="2">² Spelling out actual method selectors departs from the responsibility-based spirit of pure CRC cards. We are slanting the design toward Smalltalk, and also blurring the distinction between "what" a class does and "how" it does it. But a little help with method names now will help you write the code in the next chapter.</footnote>
Now we turn to relationships like inheritance and aggregation. Inheritance is irrelevant for the classes in this design, but aggregation matters. The usual way to implement “knowing” and “keeping” responsibilities of a CRC design is to define instance variables. Thus, for the responsibility, “An account knows its balance,” define an instance variable in **Account** named **balance** to hold the account’s current balance. And for an account to “keep a log,” define an instance variable **log**, which will refer to a sorted collection. Similarly, because transactions “know” their amounts and dates, they ought to have instance variables **amount** and **date**.

What about the log's responsibility for “containing transactions”? Since we intend to reuse class **SortedCollection**, which Smalltalk has already implemented for us, we don’t really have to worry about the details for discharging this responsibility. (Here, nevertheless, is an aside about the internals of containers like sorted collections. A container cannot practically describe each object in it by an instance variable with a name. A Smalltalk container therefore has an unspecified number of *unnamed* instance variables, and the number of such variables appears to increase or decrease as one adds or removes objects to or from the container.)

If we enlarge the insides of our objects to emphasize instance variables (and the “knowing,” “keeping,” and “containing” relationships they imply), our cards suggest this arrangement of objects:

<figure><img src="image_54.png" /></figure>

Although I have said little about the “collaboration” part of CRC cards, you can see that instance variables impart collaborative relationships to a design.

The progression in this section is more orderly than you should expect from real, large-scale problems. Experienced designers working together on large problems will,
at times, shuffle dozens of cards as fast as they can scribble notes on them; between the frantic scribblings will be lulls consisting of hard thinking and discussion. The crude product of all this effort eventually needs to be rewritten with more thoughtful and lucid wordings, to communicate the ideas to developers who weren't present for the session.

## 7.3 Common questions and answers

There is little chance that everyone who tries the problem above will arrive at exactly the same conclusion along exactly the same path. Some of the common deviations are:

1. Why not use plural names for classes, like Accounts and Transactions? The short, irrefutable answer is that it is a convention among object-oriented designers to use singular names for classes. But another answer, subtle but important, is that using a plural name suggests a collection, and we wouldn't want to mislead anyone into thinking of a class as a collection. The preferred way to think of a class is as a factory (Chapter 2).

2. Why not subclass Account (Checking, Savings,...) and Transaction (Check, Deposit,...)? These extensions would make the design more realistic. It is nevertheless almost always better to master the simplest form of a design first, and save the embellishments for later. One danger in enriching a design too early is in making it so rich that developers never implement it. This is a frequent cause of failed projects. Better to have accomplished something simple than nothing at all. (Our solution is so simple that our mechanism for distinguishing deposits from checks is to use a positive transaction amount to denote a deposit and a negative one to denote a check or debit. It is simple enough that you will be able to write the code for it in one sitting.)

3. Why not make transactions responsible for "processing themselves"? This is an acceptable alternate design, consistent with the term "transaction," which computer professionals define as a "unit of work." On the other hand, home users of this kind of application feel that a typical transaction like a check is relatively inert, and that accounts are the center of activity. I've deferred to the user's viewpoint rather than the professional's.

4. Where should you record class responsibilities or methods on a CRC card? Good question. Methods like new don't belong in the picture of an instance because an instance doesn't understand them. Only the class understands them. If they are worth capturing, I generally scribble them in the upper-right corner of the card.
In addition, you can prefix them with a special symbol, like a $ as in some notations [Rumbaugh et al. 1991].

5. Can we shift the responsibility for comparison from the transactions to the log? Yes, this is an attractive alternative. In the present design, the log does not know it contains transaction objects; it assumes only that the objects it contains respond to <= messages. Removing the <= from Transaction implies that the log (a sorted collection) must assume more knowledge of its contents. The log's sortBlock must now retrieve and compare the dates from the transactions. To specify such a sortBlock, send the message:

`log sortBlock: [:t1 :t2| t1ITTDate <= t2TDate].`

This log doesn't entrust comparison to the transactions; instead it compares their dates itself. The same idea can be used to sort the transactions by other criteria, like amounts. Just update the sortBlock by sending the message:

`log sortBlock: [:t1 :t2| t1TAmount <= t2TAmount].`

## 7.4 Commentary: analysis, design, and implementation

Methodologists often partition software development into three phases: *analysis* (fully expressing the application's requirements in a vocabulary comprehensible to users), *design* (determining software structures to solve the problem), and *implementation* (rendering the design in a specific operating environment and computer language(s)). Each phase is, in effect, the "how" of the preceding phase's "what."

Unfortunately, one person's "what" is another's "how," and so the phase boundaries blur unavoidably. Is deciding how to make "an account have a log" the act of designing or the act of implementing? (You could define a log instance variable in class Account, as we've done, or you could add a single entry to a dictionary whose keys are account objects and whose values are logs. The dictionary is overkill for the small personal system we studied, but it may be more attractive in a distributed computing environment where account information—like name, number, PIN—and transaction histories may reside on different computers. As you weigh these two alternatives, are you designing or implementing?)

Even the level of abstraction—design or analysis—you ascribe to the relationship, "an account has a log," is inconclusive. Nothing precludes a relationship from appearing at two levels of abstraction. Indeed, in object-oriented methodologies, objects and their relationships generally endure from one phase to the next. Despite the inherent ambiguities, it is still customary to try to distinguish among analysis, design, and implementation phases. Thus one usually ascribes the responsibility cards in the