is true if `x` and `y` have different Boolean values, and `false` otherwise. In Smalltalk, `xor` is implemented as a Boolean keyword message `xor`: with one Boolean argument

`aBoolean xor: anotherBoolean`

As an example of the meaning of `xor`, assume that a restaurant customer ordering from a fixed menu must choose either a cake or an ice cream but not both. An expression to check that an order follows this rule could be written as

`legalOrder := ordersCake xor: ordersIceCream`

where `ordersCake` and `ordersIceCream` are true or false. If the expression returns true, the order is OK, otherwise, something is wrong.

Implementing `xor`: requires only checking whether the receiver and the argument are the same objects and then inverting the result using logical `not`. There is no need to have one definition for `True` and another for `False`, and `xor`: is thus defined in class Boolean as

**xor: aBoolean**

`^(self == aBoolean) not "The == message tests equivalence."`

Classes `True` and `False` inherit this definition.

The definition of `xor`: introduces the notion of *equivalence*, an important new concept implemented by the `==` binary message. *Objects x and y are equivalent if they are one and the same object, in other words, if they are identical.* Compare this with *equality*, a relation implemented with the `=` message: *Two objects are equal if their values are equal in some well-defined sense.* Obviously, two equivalent objects are equal (because they are the same), but the opposite may not be true as in the following example: When VisualWorks Smalltalk executes

```
| x y |
x := 'John Smith'.
y := 'John Smith'
```

the first assignment statement creates an internal representation of the string 'John Smith' and stores it in memory. The second statement again creates an internal representation of the string 'John Smith' and stores it in memory. We now have two different representations of 'John Smith' (Figure 4.18) which are equal in the sense of string equality (the corresponding characters of the two strings are the same) - but *not* equivalent because each has its own identity, its own bit pattern stored in its own place in memory.

<figure><img src="image_88.png" /><figcaption>Figure 4.18. Two strings may be equal while not being equivalent. `x=y` is true but `x==y` is false.</figcaption></figure>

On the other hand, `x` and `y` in

```
| x y |
x := 'John Smith'.
y := x "y is bound to the same object as x."
```

are not only equal but also equivalent because both `y` and `x` are bound to the same object (Figure 4.19).

<figure><img src="image_89.png" /></figure>
<figure><img src="image_90.png" /><figcaption>Figure 4.19. `y := x := 'John Smith'` binds `x` and `y` to the same object and both `x=y` and `x==y` are true.</figcaption></figure>

As another example, consider that class `True` and `False` each have only one instance. As a consequence, equivalence and equality of Boolean objects mean the same thing.

The check of equivalence is faster because it only compares the memory addresses of the internal representation of the two objects. If the addresses are the same, the objects are equivalent; they are one and the same object. Checking whether two objects are equal may take much longer. As an example, to decide whether two non-equivalent strings are equal, we would probably first check whether they have the same size (if not, they cannot be equal) and if they do, we would have to check the individual character pairs one after another. Imagine how long this will take if the two strings are, for example, two versions of this book!

If the test for equivalence is so much simpler, why do we need equality? There are at least two reasons. One is that restricting equality to equivalence would sometimes be very inefficient. Consider again strings. If two strings that contain the same characters had to share one memory representation<fnref n="2" />, then every time that we change a string, we would have to check whether we already have a string with the same characters. If we do, we must discard one and make all reference to it point to the already existing instance. This would be extremely inefficient.

Another reason why we need both equality and equivalence is that two objects are sometimes 'equal' even though they are not quite the same. As an example, two $100 bills are interchangeable in terms of their value even though they are not one and the same object. In fact, a 'currency object' consisting of two $50 bills and is also interchangeable with a $100 currency object.

As another example, consider filenames. On some platforms, filenames are case insensitive, and strings such as `'filename'` and `'FileName'` are then two different versions of the name of the same file. Consequently,

`'abc' asFilename = 'ABC' asFilename` "true on platforms with case insensitive filenames."

On case insensitive platforms, we could thus define `=` for filenames as

**= aFilename**

`^ self string asLowercase = aFilenameString string asLowercase`

where we assumed that the name of a filename is accessed by message string.

When should we use equivalence and when should we use equality? The answer is that you should *always use equality* unless you want to check that two references refer to the same object. In those situations in which equivalence and equality mean the same thing, they are defined to mean the same thing and there is no loss of speed in using equality. This definition is inherited from `Object` where

**= anObject**

`^self == anObject`

It is very important to note that when `=` is redefined, the hash method must also be redefined. We will see what `hash` is and why it is so closely related to equality later.

<footnote n="2">² For special needs, there is a subclass of `String` called `Symbol` in which two identical values are stored only once and share the same location</footnote>
## Main lessons learned:

* Exclusive or of two Boolean arguments returns true if and only if the arguments are different.

* Two objects are equivalent (message ==) if they are one and the same object. Equality (message ==) means that two objects are in some sense interchangeable.

* The definitions of = and == inherited from Object give the same result for equality and equivalence. Many classes, however, redefine equality to satisfy their special meaning of 'interchangeable'.

* Testing for equivalence is very simple and fast, testing for equality may take much longer.

* Equivalence is stronger than equality: If two objects are equivalent, they are also equal, but two equal objects may not be equivalent.

* Always use equality unless you need to know that two expressions refer to the same object.

## Exercises

1. Draw the truth table of exclusive or. Can *xor* be short-circuited? If not, how does this relate to the fact that the argument of *xor*: is a Boolean and not a BlockClosure?

2. List all combinations for which the ice cream - cake order test returns false.

3. Implement the following problems:

a. Female patients who have a sore throat and a headache, and male patients who have a sore throat but not a headache get medication M1; other patients don't get any medication. Write a code fragment to request gender and the medical problem and advise on the medication.

b. A qualified programmer will be hired if she wants to work in Santa Barbara and accepts a salary below $130,000, or if she requires $145,000 but accepts a location not in Santa Barbara. The program obtains the information and reports whether the candidate is acceptable.

4. Study the definition of *xor*: and comment on its consistency with the definition of *xor*. Are there any situations in which the definition will not produce the expected result?

5. Define equality of complex numbers with real and imaginary part. Note that it must be possible to compare complex numbers with other kinds of numbers.

6. Give your own example of a situation in which two objects should be considered equal even though all their components are not the same.

7. Count how many classes have their own definitions of = and explain two of them in detail.

## 4.9 Use of Booleans to repeat a block of statements

Almost all programs require repetition of a block of actions until some condition succeeds or fails. As an example, a search for a book in a library catalog must search catalog entries one after another until the desired entry is found or the search reaches the end of the catalog.

The process of repeating a block of actions until some condition is satisfied or fails is called *iteration* or *enumeration* and Smalltalk contains several methods to implement it. In the rest of this chapter, we will look at the most general ones and leave the more specialized for later.

### Example 1: Print all positive integers whose factorial is not bigger than 15,765

*Solution:* The obvious solution is as follows:

1. Define a variable called, for example, number to hold the current value of the value over which we are iterating. Initialize number to 1.

2. Check whether number factorial is less or equal 15765. If yes, print the number, increment it by 1, and repeat this step, otherwise stop.

This algorithm can be implemented as follows:

```
| number |
number := 1.
```
Transcript clear.

[number factorial <= 15765] "This is the condition for doing another iteration"

whileTrue: [Transcript show: number printString; cr. number := number + 1]

In this example, iteration is performed with the whileTrue: message. Its general form is

conditionBlock whileTrue: iterationBlock

and it works as follows (Figure 4.20): The conditionBlock is evaluated; if the result is true, the iterationBlock is evaluated and conditionBlock is re-evaluated. Iteration continues until evaluation of conditionBlock returns false. Note that conditionBlock must always evaluate to true or false; if it does not, the message fails and opens an Exception Window.

<figure><img src="image_91.png" /><figcaption>Figure 4.20. Evaluation of conditionBlock whileTrue: argumentBlock is based on looping.</figcaption></figure>

The whileTrue: message is very useful but it must be used very cautiously. The danger is that if the receiver block never returns false, the program will continue looping around and never stop, a situation known as an *infinite loop*. Our program, for example, would get into an infinite loop if we forgot to increment the value of number in the iteration block.

In spite of all possible caution, you will undoubtedly eventually write a program that does get into an infinite loop and something that should take milliseconds will be running, and running, and running. If this happens, interrupt execution by pressing the <Ctrl> and <c> keys simultaneously. Smalltalk will open an Exception Window as if you halted the program with self halt and you can correct the program using the debugger or terminate execution.

### Example 2: A simple shopping calculator

**Problem:** As a part of a Smalltalk application running a portable shopping calculator, we need a function that lets the user enter prices of grocery items, print them, and calculate and display a running total. When the total exceeds a preset limit, the program displays the total and displays a warning message.

**Solution:** The real application will require several classes and a graphical user interface (GUI) but since we are not in a state to implement it yet, we will test the general idea on a code fragment and a specific limit value, and display the required data in the transcript. The algorithm is as follows:

1. Initialize variable total to 0 and clear the Transcript.

2. While total <= 100 is true, do the following:

get price of the next item

display price in Transcript

update total

3. Display warning window and print total in Transcript.

This algorithm can be easily converted into the following program:

| price total |
"Initialize total and clear Transcript."

total := 0.

Transcript clear.

"Keep gathering item prices and displaying them until the total exceeds 100."

[total <= 100]

whileTrue:

[price := Dialog request: 'Enter next price' initialAnswer: "".
Transcript show: price; cr.
total := total + price asNumber].

"Open warning window, print result, and stop."

Dialog warn: 'The total has exceeded 100, end of input'.

Transcript show: 'The total is now ', total printString,

### The whileFalse: message

Iteration is also available in the form whileFalse: which repeats execution as long as the receiver is false. You can always switch between whileTrue: and whileFalse: and the better choice is the one that makes more sense in the current context. With whileFalse:, the previous program could be rewritten as

| price total |

"Initialize total and clear Transcript."

total := 0.

Transcript clear.

"Gather item prices, display them, calculate running total."

[total > 100]

whileFalse:

"Inverted condition."

"Instead of whileTrue:"

[price := Dialog request: 'Enter next price' initialAnswer: "".
Transcript show: price; cr.
total := total + price asNumber].

"Open warning window, display result, and stop."

Dialog warn: 'The total has exceeded 100, end of input'.

Transcript show: '[The total is now ', total printString, ' - more than 100'

### The definition of whileTrue: is based on recursion

How is the whileTrue: method defined? Since the receiver is a block, its definition is in class BlockClosure and the definition is as follows:

#### whileTrue: aBlock

^self value ifTrue: [aBlock value.

[self value] whileTrue: [aBlock value]]

This is a bit obscure and requires an explanation. The first line of the definition

^self value

evaluates the receiver, just as we would expect from Figure 4.20, and sends it the ifTrue: message.

If the returned value is false, the ifTrue: message has no effect and execution is finished. If the returned value is true, execution continues with

[aBlock value.

[self value] whileTrue: [aBlock value]]

Here aBlock value takes the argument block and evaluates it as in Figure 4.20, and execution proceeds to

[self value] whileTrue: [aBlock value]

which is equivalent to
[self value] whileTrue: aBlock

Since `self value` is the evaluated value of the original block, `[self value]` is the same as the original block `self`. As a consequence,

[self value] whileTrue: aBlock

is the same as

self whileTrue: aBlock

This agrees with Figure 4.20 which shows that when we finish one iteration, we do another one, just like the one before. In effect, when the condition of `whileTrue`: succeeds (returns true), the `whileTrue:` message is sent again, and again, and again, until the condition finally fails.

A message that sends itself is called *recursive* and the concept is related to recursive definitions which we have already encountered.

Although recursion looks like magic, it is very natural even in real life situations. Consider, as an example, a person asking how to find the railway station in a large city. If the railway station is far, the best answer might be something like 'Go to the third intersection and ask again.' This advice is recursive because it requires re-execution of the original request.

Recursion often considerably simplifies the solution of a problem but it is often very inefficient because each recursion step produces a new message send and this results in extra execution time and memory overhead. For this reason, Smalltalk tries not evaluate `whileTrue`: using recursion and the compiler converts `whileTrue`: messages to in-line code whenever it can. The in-line code - direct translation into a sequence of machine instructions - will work faster and requires less memory.

The situations under which the definition of `whileTrue`: is in-lined is described in the comment of `whileTrue`: which goes essentially as follows:

"This method is in-lined if both the receiver and the argument are literal blocks. In all other cases, the code above is run.

Note that the code above is defined recursively. However, to save time and memory each time this method is invoked recursively, we have used the '[...] whileTrue: [..]' form in the last line, rather than the more concise 'self whileTrue: aBlock'. Using literal blocks for both the receiver and the argument allows the compiler to inline `#whileTrue:`, which could not be done if we were to use 'self whileTrue: aBlock'."

The comment refers to the concept of a *literal block* which is a block of statements surrounded by square brackets such as

[Transcript clear]

In other words, a literal block is a block that is directly recognized by the compiler. On the other hand, the block stored in the `aBlock` argument of the definition of `whileTrue`: is not literal because the compiler cannot determine whether the value of `aBlock` is a block or not. In fact, if we wrote something like

[x < 3] whileTrue: Transcript clear

the argument would not be a block but the expression should at least start executing because the receiver (a `ClcokClosure`) understands the message.

The comment in the definition of `whileTrue`: means that if the argument of `whileTrue`: is a literal block, the compiler can recognize it as such and create in-line code. If the argument is not a literal block, the compiler cannot create in-line code because it does not have enough information. In this case, it will generate code to execute the definition (rather than creating in-line code as it would otherwise) by sending messages in the usual way. As an example, the `whileTrue:` message in

| block x |

x := 1.
```
block := [x := x + 1].
[x squared < 10] whileTrue: block.
Transcript show: (x - 1) printString
```

will be executed by message sends (executing the whole definition of `whileTrue:`) rather than in-lined because the argument is not a literal block. When you attempt to execute this example, Smalltalk will open the window in Figure 4.21 which warns you that the argument of `whileTrue:` is normally a literal block and asks you if you really intend to use a non-literal. In this case, a non-literal is exactly what we want so click *proceed* and the program executes as expected.

<figure><img src="image_92.png" /><figcaption>Figure 4.21. Warning produced when the argument of `whileTrue:` is not a literal block.</figcaption></figure>

Besides the point that we have just explained, the comment has another even more obscure part that deals with the case when the argument is *not* a literal block. The essence is that if the compiler cannot in-line the original formulation, the recursive part is formulated so that the compiler *can* in-line the second execution and thus execute all iterations beyond the first one more efficiently. Consider the definition again:

```
whileTrue: aBlock
    ^self value
    ifTrue:
        [aBlock value.
         [self value] whileTrue: [aBlock value]]
```

If `self` or `aBlock` are not literal blocks, the message cannot be in-lined and the previously compiled definition executes. Now consider how this code has been compiled. Where the body contains a `whileTrue:` message:

```
[self value] whileTrue: [aBlock value]
```

the receiver and argument are both literal blocks and the compiled code is thus in-lined. Although the first iteration was thus executed less efficiently as a message, the remaining iterations are efficient because they use the in-lined code. Only the first iteration will thus be truly recursive, saving both execution time and memory space. This saving would not be possible if the formulation of the iteration was the more natural

```
self whileTrue: aBlock
```

because this code would again use a non-literal block.
## Main lessons learned:

* Iteration is repeated execution of a block of statements. In its `whileTrue:` form, iteration stops when the receiver block returns `false`, in the `whileFalse:` form, it stops when the receiver block returns `true`.

* If the stopping condition is never satisfied, an infinite loop occurs. To interrupt an infinite loop, press <Ctrl> and <c> simultaneously.

* Recursion is the technique of defining a method in terms of itself.

* Recursion often leads to very simple solutions but it is usually inefficient in terms of speed and memory space.

## Exercises

1. What is the value returned by the `whileTrue:` message?

2. Solve the following problems:

a. Open a confirmer asking the user whether to stop or not. If the answer is yes, the program stops, otherwise the confirmer is displayed again.

b. Print the square of all numbers between 10 and 20 in the Transcript.

c. Print all numbers that are between 1 and 1,000 and are divisible by 11 or 13 in the Transcript.

3. The factorial of a positive integer `n` is defined as follows: When `n=1`, the factorial of `n` is 1. When `n>1`, the factorial of `n` is `n` times the factorial of `n-1`. Write and test a recursive method derived directly from this definition. (The factorial method in the library is not defined recursively.)

4. The iteration methods covered in this section are all defined in class `BlockClosure`. Could they be redefined in the `Boolean` classes? If so, how?

5. What is the advantage of using a block rather than a Boolean expression as the receiver of a message?

## 4.10 Other forms of iteration

To close this chapter, we will introduce messages that strip the `whileTrue` and `whileFalse` ideas to a bare minimum by removing the argument. This means that all work done during the iteration must be done in the condition block. These messages have the following form:

aBlock whileTrue "Repeats until aBlock evaluates to false."

aBlock whileFalse "Repeats until aBlock evaluates to true."

aBlock repeat "Repeats forever or until termination is forced inside aBlock."

When you examine the library, you will find that it does not use these messages. (The references that you will find are not message sends.) Yet, they are useful and most of the uses of `whileTrue:` and `whileFalse:` can be easily converted into this form.

### Example 1: Find and print the largest integer number `x` for which `x + (270*x²) < 100,000`

This problem can be solved either with

```
|x|
x := 1.
[x + (270 * x squared) < 100000] whileTrue: [x := x+1].
Transcript show: (x - 1) printString
```

or with

```
|x|
x := 0.
[x := x + 1. x + (270 * x squared) < 100000] whileTrue.
Transcript show: (x - 1) printString
```
The first solution is more natural and easier to read which is probably why `whileTrue` is not used.
To implement the same task with `repeat`, we would have to change the structure to

```
| x |
x := 0.
[x := x + 1.
   x + (270 * x squared) < 100000
   ifTrue: [Transcript show: (x - 1) printString. ^self]] repeat
```

where we force exit from the loop with the return operator.

### Example 2: Finding the root of a function

**Problem:** We need to find an approximate solution of

$$1 + \sin(x) = x$$

**Solution:** The problem can be solved by converting the equation into

$$f(x) = 1 + \sin(x) - x = 0$$

and finding the root of $f(x)$ - the value of $x$ that produces $f(x) = 0$. Since this approach can be used to find the solution of any kind of equation with one unknown, we decide to restate the problem as follows:

**Problem:** Define a general purpose method to solve

$$f(x) = 0$$

**Solution:** Perhaps the simplest approach is as follows (Figure 4.22): Start with a suitable first guess for $x$ and calculate $f(x)$. Increment $x$ by a fixed increment and calculate $f(x)$ again. If the new $f(x)$ has the same sign as the old $f(x)$, increment $x$. Keep repeating these steps until the new and the old value of $f(x)$ have a different sign. At this point, decrease the size of the step (for example, divide it by 3), change its sign, and proceed as before (in the opposite direction, because the sign is different). Keep going back and forth until the value of $f(x)$ becomes small enough or until the number of repetitions reaches a preset maximum.
<figure><img src="image_93.png" /><figcaption>Figure 4.22. Finding root of f(x) = 0 by iteration.</figcaption></figure>

We will now solve the problem in a simplified form by repeating the iteration until the two consecutive end-points are less than a predefined value `delta` apart. The algorithm is as follows:

1. Initialize starting value of `x` and use it as the current end-point.

2. Calculate the first value of `f(x)`.

3. While the termination condition fails, repeat the following steps:

a. While the old `f(x)` and the new `f(x)` have the same signs `signs` Increment `x` and calculate new `f(x)`.

b. Divide increment by 3 and change its sign.

c. Re-evaluate the termination condition.

d. Store `x` as the current end-point.

Before writing the method, we will first test this algorithm on the following code fragment:

```Smalltalk
| delta x oldx step oldF newF condition |
"Initialize."
delta := 0.01.
step := 0.1.
x := 0.
oldx := 0.
condition := false. "Termination condition - initially not satisfied."
newF := 1 + x sin - x.
[condition] whileFalse:
    [[x := x + step. "Increment x and calculate new value."]
oldF := newF.
newF := 1 + x sin - x.
oldF sign = newF sign] whileTrue.
step := (step / 3) negated. "Update x and count."
condition := (oldx - x) abs < delta.
oldx := x].
"Output results."
Transcript clear; show: 'The approximate value of the root is x = ', x printString; cr;
show: 'The value of the approximation is f(x) = ', newF printString
```

When we executed this code, we obtained the following output:

The approximate value of the root is `x = 1.93457`

The value of the approximation is `f(x) = -6.67572e-6`
This result is reasonable and we will thus convert the test fragment to a method.

The first question is what form the method should have. The method will need to know the function (this can be implemented as an evaluated block) and the following numbers: the starting point, the initial increment, and the value of delta. We thus decide on an implementation with selector `rootFrom:by:untilDelta:` that will be used as in

```Smalltalk
|function root |
function := [:x | 1 + x sin - x].
root := function rootFrom: 0.0 by: 0.1 untilDelta: 0.01.
Transcript clear;
    show: 'The approximate value of the root is x = ', root printString;
    cr;
    show: 'The value of the approximation is f(x) = ', (function value: root) printString
```

Note that we took the output out because the method could be used in situations in which no output is required.

The rest of this section is somewhat advanced for this point in the text and you may skip it without missing anything because we will return to the presented concepts later.

Where should the new method be defined? Our example shows that the argument is a block and so the definition will be in class BlockClosure. The implementation based on a few changes in our code fragment is as follows:

### rootFrom: firstx by: firstStep untilDelta: delta

```Smalltalk
"Find root of self value = 0 starting from firstx in steps starting with firstStep. Use iteration back and forth until x end points differ by less than delta."
| x oldx step oldF newF condition |
"Initialize."
step := firstStep.
x := firstx.
oldx := 0.
condition := false. "Termination condition - initially not satisfied."
newF := self value: x.
[condition]
    whileFalse:
        [
            [x := x + step. "Increment x and calculate new value." oldF := newF.
             newF := self value: x.
             oldF sign = newF sign] whileTrue.
            step := (step / 3) negated. "Update x and count."
            condition := (oldx - x) abs < delta.
            oldx := x].
    ^x
```

This definition requires several comments:

* We could not use arguments `firstx` and `firstStep` in the iterations because arguments cannot be assigned new values inside a method. We thus had to introduce temporary variables `x` and `step` and initialize them to `firstx` and `firstStep`.

* The block that represents `f(x)` must have an argument so that we can evaluate `f(x)` for a particular value. To be able to supply an argument into a block, we must use a block with an internal argument as in

```Smalltalk
[:x | 1 + x sin - x]
```

Note the special syntax: `x` is inside the block, preceded by a colon and followed by a vertical bar. A block may have as many internal arguments as we need.

* To evaluate a block with an argument, we must send it an argument object and the value message is thus insufficient. For a block with one argument, use message value: instead as in
[:x | 1 + x sin - x] value: 0.4

When we tested the new definition with

```
|function root |
function := [:x | 1 + x sin - x].
root := function rootFrom: 0.0 by: 0.1 untilDelta: 0.01.
Transcript clear;
    show: 'The approximate value of the root is x = ', root printString;
    cr;
    show: 'The value of the approximation is f(x) = ', (function value: root) printString
```

we obtained the same result as before. The method is thus a correct translation of the original code fragment.

## Main lessons learned:

* Methods `whileTrue`, `whileFalse`, and `repeat` don't have an argument block and all work must be done in the condition block.

* The use of `repeat` requires forced exit from the block.

## Exercises

1. Solve the following problems from the previous section using `whileTrue`, `whileFalse`, and `repeat`:

a. Open a confirmer asking the user whether to stop execution or not. If the answer is yes, the program stops, otherwise the confirmer is displayed again.

b. Print the square of all numbers between 10 and 20 to the Transcript.

c. Print all numbers between 1 and 1,000 divisible by 11 or 13 to the Transcript.

2. Draw a flowchart describing the operation of the `whileFalse` method.

## Conclusion

This chapter focused on Boolean objects and blocks. Booleans are used to represent the outcome of tests and yes/no questions. They are an essential component of most computer programs because they are the basis of decision making (should we execute a block of statements or not?), selection (should we execute block A or block B?), and iteration (should we execute the block again?).

In Smalltalk, Boolean objects are implemented by the abstract class Boolean which leaves the implementation of most of its methods to its subclasses True and False. Classes True and False each allow only one instance represented by literals `true` and `false`.

Another essential component of decisions, selections, and iterations is the block object, an instance of BlockClosure, a sequence of statements surrounded by square brackets. Class BlockClosure defines various forms of the value message which evaluate the statements inside the block in its proper context. Until a block object receives the value message, it is just a container holding a deferred sequence of statements.

Messages implementing decisions are defined in classes True and False. They include the one-keyword messages `ifTrue:` and `ifFalse:` and the two-keyword messages `ifTrue:ifFalse:` and `ifFalse:ifTrue:.`. All use blocks as arguments. Classes True and False also implement logic operations `and`, `or`, `exclusive or`, and `not`. Operations `and` and `or` are implemented in two forms - fully-evaluating and non-evaluating. The non-evaluating message does not evaluate its argument unless it is required to obtain the Boolean result. It is thus faster and preferable. Besides, it can be used as a safeguard protecting illegal evaluation of the argument.
Iteration methods are defined in class BlockClosure and their receiver block must evaluate to true or false. All forms of iteration defined in BlockClosure except for repeat require the evaluation of a condition block which determines whether to iterate again or proceed to the next message.

The body of the definition of `whileTrue`: re-sends the `whileTrue:` message, a technique known as recursion. Recursive solutions are often simpler than iterative ones but they are usually less efficient because of the extra work and memory overhead required by each new message send. In most cases, recursion can be easily replaced by more efficient iteration.

Although the Smalltalk library contains formal definitions of `ifTrue:`, `ifFalse:`, and `whileTrue:`, the compiler usually does not use them when compiling Smalltalk code. Instead, it uses pre-defined machine code that implements the operation more efficiently. This technique is called in-lining and its use in Smalltalk is rather rare. The vast majority of method definitions in the Smalltalk library are compiled into message sends reflecting directly the original code.

Important classes introduced in this chapter

Classes whose names are **boldfaced** are very important, classes whose names are printed in *italics* are less important, classes whose names are printed in regular font are not of much interest.

**BlockClosure**, **Boolean**, **Date**, **Dialog**, **False**, **Time**, **True**.

Terms introduced in this chapter

*and* - Boolean operation; returns true if and only if the receiver and the argument are both true

*Boolean* - general term denoting true and false objects and operations on them; basis of tests

*block* - instance of class BlockClosure; sequence of statements surrounded by square brackets and evaluated together; to evaluate it, send it message value

*body* - last part of method definition - sequence of statements implementing method behavior

*confirmer* - a dialog window offering a yes/no choice

*conjunction* - another name for the *and* operation

*conversion message* - message converting an object into a related object

*dialog* - window-based interactive communication between the user and a program

*disjunction* - another name for the *or* operation

*equality* - two objects are equal if their values are in some sense interchangeable; the = message

*equivalence* - two objects are equivalent if they are identical, one and the same object; the == message

*exclusive or* - Boolean operation; returns true if and only if the receiver and the argument are different Booleans

*file-in* - reading and compiling a file-out file and inserting its contents into the library

*file-out* - storing a method, protocol, class, or category in a file using a special format suitable for a file-in

*flowchart* - a diagram showing the order of execution of an algorithm

*fully-evaluating and/or* - implementation of *and/or* in which both the receiver and the argument are always evaluated

*heading* - the first part of method definition; specifies the selector and argument names, if any

*in-line code* - machine code inserted by the compiler into method translation instead of code to invoke a message; used for a few frequently used messages to increase speed of execution

*iteration* - repetition of a block of statements until some condition is satisfied

*literal* - an object created by the compiler from its textual form without a creation message

*logic* - synonym of Boolean

*method definition* - formal specification of the implementation of a message

*non-evaluating and/or* - implementation of *and/or* that evaluates the argument only if necessary

*notifier* - a dialog window displaying text and offering only an *OK* button for continuation; created with the warn: message to class Dialog

*or* - Boolean operation; returns false if and only if both the receiver and the argument are false

*recursive* - referring to itself
*singleton* - the single instance of a class that does not allow multiple instances

*truth table* - a table defining a Boolean operation by listing all combinations of *true* and *false* operand values and the corresponding value of the result
# Chapter 5 - Numbers

## Overview

VisualWorks library contains many classes representing numbers of various kinds, mainly because computers internally represent and process different kinds of numbers differently. In addition, computer programs often require facilities that go beyond basic hardware capabilities and Smalltalk number classes satisfy these additional needs.

Although the main use of numbers is for calculations, numbers are also used to implement iteration. This includes execution of a block of statements a fixed number of times or over a range of numbers with given start and end values. Several methods implementing these very important functions are included in the library.

## 5.1. Numbers

All Smalltalk number classes are defined in the Magnitude - ArithmeticValue part of the class hierarchy. Its structure is as follows:

Object ()
Magnitude ()

ArithmeticValue ()
  Complex ('real' 'imaginary')
  Number ()
    FixedPoint ('numerator' 'denominator' 'scale')
    Fraction ('numerator' 'denominator')
    Integer ()
      LargeInteger ()
        LargeNegativeInteger ()
        LargePositielInteger ()
      SmallInteger ()
    LimitedPrecisionReal ()
      Double ()
      Float ()
    MetaNumeric ()
      Infinitesimal ('negative')
      Infinity ('negative')
      NotANumber ()
      SomeNumber ('value')
Point ('x' 'y')

In this diagram, the most important classes are **boldfaced**, less important classes are *italicized*, and
classes rarely encountered are in regular font.

The hierarchy starts with the abstract class Magnitude which gathers the general properties based on comparison<fnref n="1" />. Subclasses of Magnitude include mainly number classes but also other classes whose instances can be compared such as Date, Time, and Character. Numeric subclasses of Magnitude are collected under ArithmeticValue, another abstract class, which gathers methods shared by all numbers such as addition, subtraction, and absolute value. Concrete definitions of most of these methods are left to concrete subclasses but some are defined here, for example changing the sign of an instance by methods abs and negated.

Some of the subclasses of ArithmeticValue, such as Complex, are little used and Complex and MetaNumeric are not even included in the standard library and must be filed in. All the frequently used kinds of numbers are subclasses of the abstract class Number which is responsible for scalar entities -

<footnote n="1">¹ Note that although most classes that understand comparison are gathered under Magnitude, some important classes such as strings are located under a different class.</footnote>
numbers that have magnitude but cannot be used as vectors - indicators of direction or coordinates of points in space. (Instances of Complex and Point are related to vectors.) Number defines methods such as division and mathematical functions such as sin and cos, mostly on the basis of conversion to floating-point and delegation to floating-point number classes. A large conversion protocol is included which allows conversion of almost any kind of number to almost any other kind.

The concrete subclasses of Number are LargeNegательInteger, LargePositivelnteger, and SmallInteger (all of them numbers without a decimal point), Fraction (based on integer instance variables numerator and denominator), FixedPoint (with instance variables numerator, denominator, and scale), Double and Float (numbers with decimal point and fractional part), and special classes Infinitesimal, Infinity, NotANumber, and SomeNumber - all subclasses of MetaNumeric. If you are interested in numbers, the implementation of some of the methods provides rich material for the study of very interesting algorithms.

Before introducing the most important properties of number classes in detail, we will now briefly
outline their purpose and functionality.

Integers

Integers are numbers without a decimal point such as 13, -45700089, and 0. Computers implement integers and integer arithmetic differently from other kinds of numbers, and the number of bits that they use to store integers determines the maximum size that they can handle in hardware. In VisualWorks Smalltalk, integers directly processed by computer hardware are implemented by class SmallInteger and their maximum and minimum values can be obtained as follows:

<table>
   <tr>
    <td>
     SmallInteger minVal
    </td>
    <td>
     “Returns, for example, -536870912”
    </td>
   </tr>
   <tr>
    <td>
     SmallInteger maxVal
    </td>
    <td>
     “Returns, for example, 536870911”
    </td>
   </tr>
  </table>

Although the exact value of the limit depends on your computer's CPU, it is obvious that the range
of SmallInteger is not so small after all. In fact, the name SmallInteger is due to the fact that Smalltalk also
implies essentially unlimited integers using two 'large integer' classes. One special feature of
SmallInteger objects is that they are among the few objects that are not accessed by pointers: Whereas the
most other objects are represented by the memory address of their detailed description (a pointer to the
internal representation), SmallInteger objects are directly represented by the binary code of the integer value
itself; this makes their access very efficient.

The idea behind introducing special classes for large integers is that if your computer has a lot of
memory, there is no reason why the available bytes could not be used to store a representation of very large
magnitudes, in principle an unlimited sequence of digits. Unlike SmallInteger objects, such numbers cannot
be processed by a single CPU instruction and require special treatment which is implemented by classes
LargeNegательInteger and LargePositivelnteger, both subclasses of LargeInteger. These 'large integers'
allow arithmetic without any concern about magnitudes. As an example, LargePositivelnteger allows you to
calculate the factorial of 200, in other words, the number obtained by multiplying
200*199*198*197*...*3*2*1. The expression

200 factorial

returns

7886578673647905035523632139321850622951359776871732632947425332443594499634033429203
0428401198462390417721213891963883025764279024263710506192662495282993111346285727076
3317237396988943922445621451664240254033291864131227428294853277524242407573903240321
257405579568660226031904170324062351700858796178922222789623703897374720000000000000
00000000000000000000000000000000000000000

This is a result that few other languages would let you obtain as easily. Although there are not
many applications that need to calculate the factorial of 200, unlimited numbers are very useful in business
and other applications. (Unfortunately, national debts easily go beyond the limits of SmallInteger.) There is,
of course, a price for this computational power and this price is that calculations with LargeNumber take
considerably longer than calculations with SmallInteger. We will see how much longer later, when we show how to measure the time that it takes to execute a statement.

The unlimited range of Smalltalk numbers is a valuable feature but if you had to treat 'small' and 'large' integers differently and keep track of the boundaries between them during arithmetic, the advantage of having unlimited integers would be small. This is why Smalltalk performs conversion between the three classes automatically and you don't even have to know that the three classes exist; all you need to understand is the concept of an integer. Technically speaking, implementation of integers is transparent to the programmer.

## Floating-point numbers

Floating-point numbers are numbers with a decimal point such as 3.14, -789000000.123, 0.000000341, 0.0 or 1.33185e17 (1.33185 * 10¹⁷). Like most other languages, Smalltalk has two floating-point representations implemented by two floating-point classes - Float ('single precision') and Double ('double precision'). The difference between them is how many bytes they use and how much precision and what range they provide. Unlike the automatic conversion between SmallInteger and LargeInteger, conversion between Float and Double is not automatic and requires conversion messages asFloat and asDouble. The comment of Double explains the principle of the class as follows:

Instances of class Double represent floating-point numbers in IEEE 64-bit format.

These floating-point numbers are good for about 14 or 15 digits of accuracy, and the range is between plus and minus 10^307.

Here are some valid floating-point examples:

8.0 13.3 0.3 2.5d6 1.27d-30 1.27d-31 -12.987654d12

The format consists mainly of no imbedded blanks, little d for tens power, and a digit on both sides of the decimal point.

The bizarre phrase 'about 14 or 15 digits of accuracy' reflects the fact that internal representation of floating-point numbers is binary and conversion of decimal values to binary usually results in loss of accuracy.

Representation using letter d is mainly for very large and very small magnitudes and the letter separates the magnitude part from the exponent part. As an example

$$1.27d-30 = 1.27 * 10^{-30} = 0.00000000000000000000000000000000127$$

$$-12.987654d12 = -12.987654 * 10^{12} = 12987654000000.0$$

$$127d3 = 1.27 * 10^{5} = 127000.0$$

Note that .123d is illegal because the decimal point must be surrounded by digits.

When you inspect a Double number, such as the Double class constant Pi (returned by class message Double pi) the inspector shows that Double numbers use eight bytes which agrees with the comment which states that 64 bits are used. The actual bytes are normally of no interest to the programmer.

<figure><img src="image_94.png" /></figure>
Figure 5.1. Inspector on Double class constant Pi obtained by message Double pi.

The comment for class Float is similar to the comment for Double, the main difference being the range and accuracy. Note also that Float representation uses letter e instead of letter d for decimal point. The comment for Double is similar to the comment for Integer, the main difference being the range and accuracy. Note also that Double representation uses letter d instead of letter e for decimal point.

Instances of the class Float represent floating-point numbers in platform-dependent short float format. These floating-point numbers are good for about 8 or 9 digits of accuracy, and the range is between plus and minus 10^38.

Here are some valid floating-point examples:

8.0 13.3 0.3 2.5e6 1.27e-30 1.27e-31 -12.987654e12

The format consists mainly of no imbedded blanks, little e for tens power, and a digit on both sides of the decimal point.

An important point about floating-point numbers is that the displayed value is not exactly what is stored in memory because of the incompatibility of the internal binary representation and the decimal representation on the screen. The number of digits displayed on the screen is controlled by the value returned by the message defaultNumberOfDigits:

Float defaultNumberOfDigits

returns 6, and

Double defaultNumberOfDigits

returns 14 which explains the Inspector in Figure 5.1. Both Float and Double numbers are thus displayed with less than their full accuracy. You can change this constant if you wish by changing the definition of defaultNumberOfDigits but no matter how many digits you print, the internal representation is fixed and changing defaultNumberOfDigits will only change the display but not the precision of arithmetic.

It is useful to note that the library contains a class that converts numbers to formats other than the default. This class is called PrintConverter and the display method is print: number formattedBy: string. It is used as follows:

PrintConverter print: 1000 * Float pi formattedBy: '#####,###.##' "Returns 3,141.59."

but other formats are also available.

Fractions

Instances of class Fraction represent values such as -3/5 or 14/27. Each fraction is internally represented by two integer objects - an integer numerator and an integer denominator - so that there is no conversion and no loss of accuracy in arithmetic. Arithmetic on Fractions uses the well-known principles of combining numerators and denominators. As an example, the Fraction method for addition is defined essentially as follows<fnref n="2" />:

+ aFraction

^Fraction numerator: numerator * aFraction denominator + (aFraction numerator * denominator)

denominator: denominator * aFraction denominator

The body first calculates the value of the numerator and denominator, and then creates a new fraction with these numerator and denominator values. The process requires the creation of a new instance, three multiplications (notoriously time-consuming), and one addition; it is thus clear that addition of Fraction objects will take much longer that addition of Integer objects. The redeeming advantage of

<footnote n="2">² In reality, the definition uses double dispatching which is explained later in this section.</footnote>
fractional arithmetic is that it fully preserves accuracy, which is not true for floating-point representation
which is inherently inaccurate.

Fixed point

According to the comment of class FixedPoint

FixedPoint numbers represent 'business' numbers - numbers with arbitrary precision before the decimal
point, but limited precision after the decimal point. A prime example of their use is in expressing currency
values, which are always rounded off to the nearest hundredth, but which could easily have more digits than
a Float (or possibly even a Double) could accurately express.

Main lessons learned:

* Smalltalk's rich hierarchy of number classes is rooted in the abstract classes Magnitude, ArithmeticValue, and Number.

* The most important types of numbers are integers, floating-point numbers, and fractions. Each uses a different internal representation and performs arithmetic differently. Some types of numbers are directly implemented in hardware, others are not, and this results in different ranges, accuracy, speed of arithmetic, and memory requirements.

* Smalltalk integers consist of 'small' integers (directly implemented in hardware) and 'large' integers for essentially unlimited magnitudes. Smalltalk automatically converts between the different forms when this is required by the calculation.

* Floating-point numbers represent values with a decimal point. They are implemented by classes Float and Double and the difference between them is in accuracy and range. Like small integers, floating-point arithmetic is directly implemented by hardware.

* Floating-point numbers are inaccurate binary representations of their decimal counterparts.

* Class Fraction provides uncompromised accuracy based on integers at the cost of very slow execution.

* Class FixedPoint is an alternative of Fraction intended for decimal data.

Exercises

1. List all concrete method definitions in ArithmeticValue and Number.

2. Methods fully defined in abstract classes usually depend on methods defined in concrete subclasses. These methods, left as subclass responsibility, should be listed in the class comment. Read the comment of Magnitude, list methods that must be defined in subclasses, and methods that this "buys you", in other words, methods that need only be defined in Magnitude and will work for any or almost any subclass.

3. Write a half page summary of class MetaNumeric.

4. Write a half page summary of class Complex.

5. If you are familiar with the principles of floating-point representation, examine how class Float represents floating-point numbers.

6. How many digits does 2000 factorial have? (Hint: Message size returns the number of characters in a String.)

7. To gain insight into floating-point numbers, step through the execution of the following code fragment:
   self halt.
   Transcript show: 3.1 printString

8. Write a short description of the most useful features of class PrintConverter.

9. Class Magnitude gathers shared behavior of all objects that can be compared. Most of its subclasses are numbers but another very important subclass is Character which is mainly used for the representation, conversion, and testing of characters including letters, digits, and punctuation symbols. Read the comment of Character and list the most important methods in the converting, testing, and accessing untypeable characters protocols.

10. Characters are a subclass of Magnitude because they can be compared. List all useful methods that they inherit.
11. Class ArithmeticValue disables the new message. This means that numbers cannot be created with new - except for class Complex. Examine and explain how class Complex gets around this limitation.

## 5.2 Operations on numbers

Most number operations can be performed on all types of numbers with the usual limitations such as no division by 0, logarithms and square roots of positive numbers only, and so on. We will not list all the available messages because few applications require more than basic arithmetic. Besides, number messages are quite self-explanatory and don't require any comments; as an example, if you know what `arcsin` is, you will not have any problem finding it in the browser and using it.

We must regretfully admit that Smalltalk is not ideal for large amounts of mathematical calculations (especially on floating-point numbers) because its very principle – treating everything as objects - requires overhead that slows arithmetic down. If you want to write a program to calculate the state of the Universe in the first 30 nanoseconds after the Big Bang, don't use Smalltalk beyond the first prototype or implement the extensive calculations in another language. You may be better of using C or, better still, assembly language. For extensive floating-point calculations, benchmark measurements give a wide range of comparisons but C is probably about five times faster on the average than unaided Smalltalk.

After this introduction we will now examine the most common arithmetic, mathematical, and conversion messages.

### Arithmetic messages

All numbers support all arithmetic operations including addition, subtraction, multiplication, and division.

<table><tr><td> + - *</td><td>work in the usual way on all combinations of numbers</td></tr><tr><td> / </td><td>produces a Fraction when both the receiver and the argument are integers, Float if floating-point numbers are involved</td></tr><tr><td> quo: </td><td>calculates the integer quotient of division with truncation towards zero</td></tr><tr><td> rem: </td><td>calculates the remainder of division in terms of quo:</td></tr></table>

**Examples with integers:**

<table><tr><td>3 / 5</td><td>"Returns fraction 3 / 5."</td></tr><tr><td>17 quo: 3</td><td>"Returns 5."</td></tr><tr><td>17 rem: 3</td><td>"Returns 2 because 5*3 + 2 = 17."</td></tr><tr><td>-17 quo: 3</td><td>"Returns -5."</td></tr><tr><td>-17 rem: 3</td><td>"Returns -2 because -5*3 + (-2) = -17."</td></tr></table>

**Examples with floating point numbers:**

<table><tr><td>3 / 5</td><td>"Returns 0.6."</td></tr><tr><td>1.7 quo: 0.3</td><td>"Returns 5."</td></tr><tr><td>1.7 rem: 0.3</td><td>"Returns 0.2 because 5*0.3 + 0.2 = 1.7."</td></tr><tr><td>-1.7 quo: 0.3</td><td>"Returns -5."</td></tr><tr><td>-1.7 rem: 0.3</td><td>"Returns -0.2 because -5*0.3 + (-0.2) = -1.7."</td></tr><tr><td>rounded</td><td>"Returns the integer nearest the receiver."</td></tr><tr><td>truncated</td><td>"Returns the integer nearest the receiver toward zero."</td></tr><tr><td>1.7 truncated</td><td>"Returns 1 - receiver stripped of its decimal part."</td></tr><tr><td>1.4 truncated</td><td>"Returns 1."</td></tr><tr><td>1.7 rounded</td><td>"Returns 2 - the nearest integer - compare with truncation."</td></tr><tr><td>1.4 rounded</td><td>"Returns 1."</td></tr><tr><td>1.5 rounded</td><td>"Returns 2."</td></tr><tr><td>-1.7 truncated</td><td>"Returns -1."</td></tr><tr><td>-1.4 truncated</td><td>"Returns -1."</td></tr><tr><td>-1.5 rounded</td><td>"Returns -2."</td></tr><tr><td>13 even</td><td>"Returns false - number 13 is not even."</td></tr></table>
## Mathematical messages

<table><tr><td>Float pi/2 sin</td><td>"Returns 3.45497 - not sin(π/2) = 1 as we expected. Why?"</td></tr><tr><td>(Float pi/2) sin</td><td>"Returns 1.0 - this is what we had in mind."</td></tr><tr><td>(Float pi/2) cos</td><td>"Returns -4.37114e-8 or -0.000000043711. Close to 0 but not exact."</td></tr><tr><td>(Float pi/4) tan</td><td>"Returns 1.0"</td></tr><tr><td>10 log</td><td>"Returns 1.0 because 10<sup>1</sup> = 10"</td></tr><tr><td>10 raisedTo: 0.5</td><td>"Returns 3.16228, the square root of 10"</td></tr><tr><td>10 sqrt</td><td>"Returns 3.16228 - same as the previous message, as expected."</td></tr></table>

## Conversion messages

<table><tr><td>3.14 asInteger</td><td>"Returns 3, same as message truncated."</td></tr><tr><td>17 asFloat</td><td>"Returns 17.0"</td></tr><tr><td>Float pi asRational</td><td>"Returns (918253/292289) - approximates π as a fraction."</td></tr><tr><td>Double pi asRational</td><td>"Returns (130161051938194/41431549628009)"</td></tr><tr><td>180 degreesToRadians</td><td>"Returns 3.14159 because 180 degrees is the same as π."</td></tr></table>

## Other

<table><tr><td>2 max: 7</td><td>"Returns 7, the larger of the two numbers"</td></tr><tr><td>2 min: 7</td><td>"Returns 2, the smaller of the two numbers"</td></tr></table>

## Example 1: Accuracy of conversion between floating-point numbers and fractions

Method asRational converts numbers to instances of Fraction. The message is understood by almost all numbers and defined in several classes but the only interesting definition is in class LimitedPrecisionReal; this definition is inherited by Float and Double. Its principle is conversion to continued fractions, numerical objects of the following kind:

$$ \begin{array}{c} 375 \\ 1 + \frac{43}{1 + \frac{13}{1 + \ldots}} \end{array} $$

To check how accurate the conversion is, we converted a floating-point number to a Fraction and then back to a floating-point number, and compared this with the original number as follows:

<table><tr><td>12345678.1476 asRational asFloat - 12345678.1476</td><td>"Returns 0.0"</td></tr><tr><td>12345678.76 asRational asFloat = 12345678.76</td><td>"Returns true."</td></tr><tr><td>31.76 asRational asFloat - 31.76</td><td>"Returns 1.90735e-6"</td></tr><tr><td>31.76 asRational asFloat = 31.76</td><td>"Returns false."</td></tr></table>

The calculation appears to be very accurate but we will make a more thorough test later.

## Example 2: Defining a new arithmetic method

Problem: Incrementing a number by 1 is so common that it might be useful to have a special method to implement it as a unary message. The method could be used as in

| n |
n := 15.
some calculations here
n increment

Solution: The problem is simple and the solution is to take the receiver, add 1 to it, and return the result as in
increment

"Increment receiver by 1."

^self + 1

The method should be useful for any number and we will thus define it in class Number. Executing

15 increment

returns 16 and the method thus appears to work. However, executing

| n |

n := 15.

n increment.

n

with *print it* returns 15 as the value of n and this does not appear to be correct. What is happening? The receiver of

n increment

is the object bound to n, in other words 15. The method takes the receiver, adds 1 to it, and returns 16.
However, the binding of n to 15 is not affected and the value of n thus remains 15. Our fundamental goal
thus has not been achieved but we learned an important lesson.

Main lessons learned:

* VisualWorks library includes many number classes, mainly because different kinds of numbers require different internal representation and different hardware implementation.

* Smalltalk is not ideal for problems involving large amounts of arithmetic, particularly when it involves floating-point numbers.

* Classes such as `LargeInteger` and `Fraction` provide extra range and accuracy found in few other languages. The cost is long processing time.
## Exercises

1. Test the following messages in short examples:

a. `asFloat` (in particular in class `Fraction`)

b. `asRational`

c. `fractionPart`

d. `rounded`

e. `truncated`

f. `degreesToRadians`

g. `radiansToDegrees`

h. `squared`

2. Compare the results of `Float pi` and `Double pi`.

3. The result of division of integers, is automatically reduced. Test this by executing `4/6` with `inspect`.

## 5.3 Implementation of binary arithmetic - double dispatching and primitives

Smalltalk arithmetic is based on double dispatching. We will now explain this important principle and refer you to an alternative description in method `aboutDoubleDispatching` in the class protocol documentation in class `ArithmeticValue`.

Assume that you want to execute the message `3.14 + (5/8)`. The two operands are different kinds of numbers must first be converted to the same class. Since `Fraction` arithmetic is based on integers and since `3.14` cannot be converted to an integer without loss of accuracy, the `Fraction` is converted to `Float` and the two numbers can then be added using floating-point arithmetic.

In general, `3.14 + x` with an arbitrary argument could be implemented as follows:

1. Check if the argument is a `Float`. If it is, do `Float` addition and exit.

2. Check if the argument is a `Double`. If it is, convert the receiver to `Double`, do `Double` arithmetic and exit.

3. Check if the argument is a `SmallInteger`. If it is, convert it to `Float`, do `Float` arithmetic and exit.

4. Check if the argument is a `Fraction`. If it is, convert it to `Float`, do `Float` arithmetic and exit.

5. Check if the number is a `LargePositiveInteger`. If it is, try convert it to `Float`, do `Float` arithmetic, and exit.

6. And so on and on, a long chain of tests, conversions, and operations.

If the class of the argument is somewhere at the end of this chain, it will take a long time before we even know what to do. For larger amount of arithmetic, this would be a serious drawback because each test adds overhead. The code is also too complicated. And if we add a new number class, we will have to change the definition of all arithmetic messages in all existing number classes to deal with this new type of argument. All in all, this is an unattractive approach.

We had a similar problem before when we considered drawing different kinds of geometric objects and we solved it using polymorphism. To eliminate tests, we relied on the receiver to do 'the right thing'. Unfortunately, our problem is different - the reason for testing is the argument, not the receiver. The problem is thus 'turned around the operation' and we cannot use polymorphism. But maybe the solution can be based on turning the problem around – exchanging the receiver and the argument - and this is exactly what double dispatching does.

Smalltalk implementation of `Float` addition method first checks whether it can do addition using CPU code. If it can (which happens if the argument belongs to the same or a closely related class), it does, and execution of the method is finished. If it cannot, the code *exchanges* the receiver and the argument (in our example `3.14 + (5/8)`), the receiver is now `Fraction 5/8` and sends a message to it (a `Fraction` object), indicating that the argument is a `Float`. The definition of the method in `Fraction` takes this hint, converts the receiver `5/8` to a `Float` (without any testing) and sends the `+` message (with the fraction converted to float) to the `Float` receiver. `Float` now executes `+` directly because both numbers are now `Float` objects (Figure 5.2). `Message +` is thus dispatched once to the original receiver and then, if necessary, again - to the argument. The result is that the arithmetic operation requires at most two extra message sends but no explicit checks of
the class of the argument. Since message sends require only a minimal number of CPU cycles, this approach is more efficient - and the code much neater. And if we add a new class, we only have to add new double dispatching messages and none of the existing messages is affected.

<figure><img src="image_95.png" /><figcaption>Figure 5.2. Execution of 3.14 + (5/8) uses double dispatching.</figcaption></figure>

We can now examine the definition of + in class Float which is as follows:

**+ aNumber**

"Answer a Float that is the result of adding the receiver to the argument.
The primitive fails if it cannot coerce the argument to a Float."

<primitive: 41>

^aNumber sumFromFloat: self

The code means that if <primitive: 41> fails to convert the two numbers to a common form and add them (ignore the concept of a primitive for a moment) the *argument* aNumber becomes the receiver of the message sumFromFloat:. In our example, aNumber is a Fraction, the message thus goes to class Fraction, and the definition of sumFromFloat: in class Fraction is

**sumFromFloat: aFloat**

^aFloat + self asFloat

In our case, self is 5/8, self asFloat is 0.625, and the method thus sends + 0.625 to Float. This is the same + method as above but this time, the argument is a Float and the primitive executes and returns the sum. The operation is finally completed. We suggest that you test how this works using the Debugger on

self halt.
3.14 + (5/8)

The definition above introduced the concept of a *primitive*, an expression written in a special syntax that does not indicate any message sends. A primitive is not implemented in Smalltalk but in a lower level language such as C or assembly language. In our example, primitive 41 executes a machine language program that adds two floating-point numbers if both are floating-point numbers or if the program knows how to convert the second number to float. There are many other primitives, such as primitive 1 which adds two small integers.

When a method contains a primitive, the primitive is always the first statement. If it fails to provide the desired result, execution continues to the next statement in the definition. The best way to think of a primitive is as a machine level instruction of some fictitious CPU. As an example, think of primitive 1 used in the definition of + in SmallInteger as 'machine instruction number 1' which checks whether the argument is a SmallInteger, performs addition if it is or if it can be easily converted, and exits with some special result if it is not.

You will now probably say: 'Aha, after all, Smalltalk is not all that pure. In the end, it must descend to the level of the CPU and work just like any other language'. And you are quite right! Every programming language must, in the end, be translated to machine level and the binary codes must be executed by the CPU. But this is true for every language.

One last question concerning primitives remains: Where is the code that executes primitives? The answer is that the implementation of primitives is included in the Smalltalk *Virtual Machine* (VM), a
program that provides an interface between Smalltalk and the CPU. The VM is thus essential for Smalltalk execution and an application written in Smalltalk requires two parts to run: The Virtual Machine program (called, for example, oe.exe - derived from Object Engine, another name for VM) and the image file containing data related mainly to the class library and stored in a .im file. Creating a stand-alone Smalltalk application thus requires creating an image file containing information about the application's classes, and a copy of the VM file. If you are developing the library, you also need a changes file .ch which contains all the changes that you made to the library, and the .sou file which contains the source code in textual form. For proper operation, the .im, .ch, and .sou files must be synchronized which automatically happens if you use the versions saved by the *save* or *save then exit* commands.

The concept of a Virtual Machine has recently attracted general attention with the emergence of the Java language which is also based on a virtual machine. To make Java portable (executable on different CPUs), Java programs are translated into *bytecodes* which are identical across all CPUs, and executed by virtual machines which are tailored to specific CPUs. Smalltalk uses the same principle.

### Main lessons learned:

* Smalltalk arithmetic uses the concepts of double dispatching and primitives.

* Double dispatching means re-sending (re-dispatching) a one-argument message to the argument, using the original receiver as the argument.

* Double dispatching eliminates tests because the dispatched message implies the type of the argument.

* The main use of double dispatching is in arithmetic but the principle has general validity.

* A primitive is an operation implemented at 'low level', possibly directly in machine code. Each primitive has a number and can be thought of as a machine code of a fictitious CPU.

* Primitive functions use special syntax of the form `<primitive: 1>`. If a method contains a primitive, the primitive is always the first statement; the remaining code is executed only if the primitive fails.

* Primitives are implemented via a virtual machine.

* A virtual machine (also called object engine) is a program that interfaces between Smalltalk and the CPU.

* The concept of a virtual machine makes it possible to compile code into one form shared across all platforms. The elements of this representation are called bytecodes. They can be executed on any machine that has a virtual machine for processing them.

* A completed standalone Smalltalk application requires a virtual machine and an image file.

### Exercises

1. Find and explain the `+` and `/` methods in the following classes:

a. SmallInteger

b. Double

c. Fraction

2. Extend the principle of double dispatching from one argument to two arguments.

### 5.4 Using numbers for iteration - 'repeat n times'

In some problems, we need to evaluate a block of statements a known number of times. For example, we might want to flash a message on the screen three times, or execute a block 1,000 times to get an accurate measure of its execution time. Although all forms of repetition can be implemented with `while True:`, iteration based on counting is so common that Smalltalk provides specialized messages which are more convenient to use. We will present one of them in this section and the remaining ones later.

#### Repeating a block a fixed number of times – `timesRepeat: aBlock`

If you want to flash a label in a window three times, you can use the following construct:
3 timesRepeat: ["statements to display the label"
"statements to create a short delay to keep the label displayed"
"statements to hide the label"
"statements to create a short delay to keep the label hidden"]

Method timesRepeat: is defined in the abstract class Integer because its receiver may be any kind of integer number, and its operation is described by the flowchart in Figure 5.3.

<figure><img src="image_96.png" /><figcaption>Figure 5.3. Execution of n timesRepeat: aBlock.</figcaption></figure>

### Example 1. Ringing the bell

All computers have a built-in beeper, conventionally referred to as the 'bell'. To beep the bell five times, execute

5 timesRepeat: [Screen default ringBell]

Class Screen is an interesting part of the library which knows various things about your computer, such as how many pixels its screen has, how to 'ring the bell', and how to perform interesting graphics operations. To access its single instance, send it the default message as above.

### Example 2. Testing the quality of Smalltalk's random number generator

We have already mentioned that one of the motivations for object-oriented programming was simulation of problems such as queues in a bank. Problems of this kind are not deterministic because customers arrive at unpredictable times, and simulation thus require tools for generation of random numbers. To satisfy this need, Smalltalk contains a class called Random.

Sending message new to class Random returns a new random number generator, a manufacturer of random numbers. Every time you send message next to the random number generator (Figure 5.4), it returns a floating-point number between 0 and 1. When you examine a sufficiently large collection of these random numbers, they should be distributed uniformly. In other words, if I1 and I2 are two arbitrary but equally long intervals between 0 and 1 and generate many random numbers, the number of samples falling into I1 should be about the same as the number of numbers in I2. Although most applications require random numbers distributed in some non-uniform way, any distribution can be generated from uniform distribution and a uniform random number generator is thus a sufficient basis for all probabilistic simulations.
<figure><img src="image_97.png" /><figcaption>Figure 5.4. The use of class Random.</figcaption></figure>

In this example, we will test how well Random accomplishes its purpose. We will select an interval I between 0 and 1, generate 10,000 random numbers, and count how many of them fall into I. We will then evaluate whether this number is appropriate for the width of the interval. As an example, if I is the interval from 0 to 0.1, its width is 1/10 of the 0 to 1 interval and the number of random numbers falling into I should be about 1/10 of the total number of generated samples. The test code is quite simple:

```
| count generator |
"Initialize count and create a random number generator."
count := 0.
generator := Random new.
"Run the test."
10000 timesRepeat: [ "Generate a random number and test whether it falls into our interval. If so, increment the count."
  ((generator next) between: 0 and 0.1)
  ifTrue: [count := count + 1].
Transcript clear; show: 'The number of samples falling between 0 and 0.1 is ', count printString
```

When we executed this code, we got

The number of samples falling between 0 and 0.1 is 987

This is quite nice - the perfect answer would be 1,000 but we cannot expect that it will be achieved because the numbers are random. However, what if we were just lucky? Let's modify the program to repeat the whole test 10 times as follows:

```
| count generator |
"Initialize count and create a random number generator"
count := 0.
generator := Random new.
Transcript clear.
10 timesRepeat: "Do the whole test 10 times."
  [count := 0.
  10000 timesRepeat: 'How many of the 10,000 numbers fall into our interval?.'
    ((generator next) between: 0 and: 0.1) ifTrue: [count := count + 1]].
Transcript show: 'The number of samples falling between 0 and 0.1 is ', count printString; cr]
```

The structure of this code fragment is a *nested loop* - one loop (10000 times Repat:) inside another (10 times Repeat:). When Smalltalk executes the inner loop 1000 times, it checks whether the outer loop has been executed enough times. If not, it repeats the inner loop 1000 times again, checks again, and so on until the outer loop is executed 10 times (Figure 5.5).
<figure><img src="image_98.png" /><figcaption>Figure 5.5. Nested loops.</figcaption></figure>

When we executed this program, we got the following output:

The number of samples falling between 0 and 0.1 is 1001
The number of samples falling between 0 and 0.1 is 1006
The number of samples falling between 0 and 0.1 is 993
The number of samples falling between 0 and 0.1 is 1013
The number of samples falling between 0 and 0.1 is 976
The number of samples falling between 0 and 0.1 is 993
The number of samples falling between 0 and 0.1 is 1004
The number of samples falling between 0 and 0.1 is 1023
The number of samples falling between 0 and 0.1 is 1000
The number of samples falling between 0 and 0.1 is 1006

which is quite satisfactory. By the way, note that the numbers are different in each run. This is to be expected because the numbers are random.

### Example 3. Definition of `timesRepeat`:

To conclude this section, let us examine the definition of `timesRepeat`:

**timesRepeat: aBlock**

"Evaluate the argument, aBlock, the number of times represented by the receiver."

| count |
|---|
| count := 1. |
| [count <= self] |
| whileTrue: [aBlock value. |
| [count := count + 1] |

The implementation is based on `whileTrue`: and so `timesRepeat`: is not strictly necessary because we can get the same effect by using `whileTrue`: directly. However, the solution with `repeatTimes`: is much neater. When you compare

5 timesRepeat: [Transcript show: 'Time to go home!'; cr]

with

count := 1.
[count > 5] whileTrue: [Transcript show: 'Time to go home!'; cr. count := count + 1]
you will agree that the second form is longer (requiring more typing), more difficult to understand, and more error prone because we must remember to keep track of the count. (If we forget, we will get an infinite loop). Message `timesRepeat`: thus makes programming easier and a sufficient justification why this and many other apparently redundant messages are in the Smalltalk library.

**Main lessons learned:**

* To repeat a block of statements a known number of times, use message `timesRepeat`.

* An iteration enclosed inside another iteration is called a nested iteration.

* If the Smalltalk library contains a message that does exactly what you need, use it. This will save you time re-inventing the wheel and making mistakes.

**Exercises**

1. Truly random numbers should never repeat the previously generated sequence but random number generators are based on arithmetic and produce repetitive sequences (they are thus properly called pseudo-random). The length of the sequence is called its period and a good pseudo-random number generator should thus have a large period. Is the period of *Random* large enough?

2. Class `Screen` defines various interesting methods. Explore and execute the following ones: `resolution`, `contentsFromUser`, `bounds`, `dragShape`:..., and `zoom/to:duration`. Some of them contain example code.

3. Write a code fragment to print

a. one line containing ten * symbols (simple loop)

b. five lines, each containing ten * symbols (nested loops)

4. Modify the test of *Random* as follows:

a. Allow the user to specify how many random numbers should be generated.

b. Allow the user to specify the start and end points of the interval.

c. Allow the user to specify how many times to repeat the test.

d. Calculate the average number of samples falling into the interval over all tests.

5. Convert the random generator test into a test method in class `protocol` testing in class *Random*.

6. Some people think that the `timesRepeat:` `aBlock` message is not natural and that `aBlock repeatTimes:` `anInteger` as in `aBlock repeatTimes: 17` would be better. Define such a method and test it.

7. Write a summary of the main features of class *Random* and find all references to it in the library.

## 5.5 Repeating a block for all numbers between a start and a stop value

Method `repeatTimes:` is rarely used because it does not happen very often that you want to do exactly the same thing several times. Much more often, you need to do something with a value moving over a range - such as when you want to print a table of factorials from 1 to 100. The message that performs this task is `to:do`: and its basic use is as follows:

`startNumber` to: `endNumber`: `do`: `oneArgumentBlock`

where `oneArgumentBlock` is a block with one *internal argument*. The block is repeatedly executed with all successive values of the internal argument from `startNumber` to `endNumber` in increments of 1 (Figure 5.6).
<figure><img src="image_99.png" /><figcaption>Figure 5.6. Execution of start to: end: do: aOneArgumentBlock.</figcaption></figure>

### Example 1: Print all numbers from 1 to 5 with their squares and cubes in the Transcript

**Solution:** Repeat the calculation and output for each value of the argument as it ranges through the interval:

Transcript clear.

1 to: 5 do:

[:arg | "arg is internal block argument. During the execution, it will assume values 1, 2, ..., 5."

Transcript show: arg printString; tab;

show: arg squared printString; tab;

show: (arg squared * arg) printString; cr]

The output is

1 1 1
2 4 8
3 9 27
4 16 64
5 25 125

Blocks and arguments obey the following rules:

* A block may have any number of arguments. We have seen blocks without arguments such as the block used in `ifTrue:`, a method with one argument (`to:do:`) and we will see methods with more arguments later.

* All arguments defined for a block are listed immediately behind the opening bracket, each preceded by a colon. The whole list is followed by a vertical bar. A block with three arguments, for example, would be used as follows:

[:arg1 :arg2 :arg3 | "Body of block."]

* The name of block arguments must not clash with identifiers already declared in a surrounding scope. As an example, if a one-argument block is used in a method with a local variable or keyword argument called `number`, the block argument must not be called `number`. Similarly, if the block is nested inside another block, their argument names must not clash. The same applies to a conflict with the names of instance variables of the class. If any of these scoping rules are violated, Smalltalk displays a warning message as in Figure 5.7.
<figure><img src="image_100.png" /><figcaption>Figure 5.7. Block argument value is already defined in an outer scope.</figcaption></figure>

* A block must not assign a new value to any of its arguments and any attempt to do so is caught by the compiler. (The same is true for method arguments. In fact, the concepts of a method and a block are very similar.)

* The role and nature of individual block arguments depends on the definition of the message that uses the block. In the case of `to:do:`, the block argument must be a number and its role is a counter or an index.

Before we close this section, we will now show how `to:do:` might be defined to illustrate how a method acquires a block argument. Our definition is different from the definition in the library because the library definition uses several concepts that will be covered later.

**to: end do: aOneArgumentBlock**

"For each number in the interval from the receiver to the argument, incrementing by 1, evaluate the block."

### | index |

`index := self.`

`[index <= end] whileTrue: [aOneArgumentBlock value: index. index := index + 1]`

The critical part of the definition is `message value: index` which assigns `index` as the value of the block argument and causes evaluation of the block. In other words, the `value: message` is the one-argument-block equivalent of the zero-argument-block value message

The fact that the definition of `to:do:` evaluates `aOneArgumentBlock` with the `value: message` (rather than the `value` message) is the reason why you must use a one-argument block when you send `to:do:`. The number of arguments in a block is thus dictated by the block's use in the definition. The role of the argument, of course, depends on how the argument is used. In this case, the argument is evaluated with `index` and `index` is used to do arithmetic, so the argument must be a number.

As a more direct illustration of the operation of value messages, evaluating the zero-argument block in

### [Transcript show: 'A string'] value

has the same effect as

### Transcript show: 'A string'

whereas evaluation of the one-argument block in

### [:aString |Transcript show: aString] value: 'Block argument'

has the same effect as

### Transcript show: 'Block argument'

and

### [:string1 : string2 |Transcript show: string1; show: string2] value: 'argument 1' value: 'argument2'

has the same effect as
Transcript show: 'argument 1 '; show: 'argument2'

Finally, a word of caution. If you search for all references to `value:` you will get a very long list but most of them refer to the `value:` method used with 'value holders' and have completely different meaning.

### Main lessons learned:

* To execute a block for a range of values in increments of 1, use `to: anInteger do: aOneArgumentBlock`.

* The block in message `to:do:` has one internal argument.

* The receiver of `to:do:` may be any number.

* The number of arguments required in a block used as an argument of a message depends on the definition of the method in which the block argument is used.

* Use `value` to evaluate a zero-argument block, `value:` to evaluate a one-argument block, and `value:value:` to evaluate a two-argument block. Class `BlockClosure` defines additional value messages.

### Exercises

1. List all numbers between 1 and 1,000 that are divisible by 11 and 13 in the Transcript. Use `to:do:`, `timesRepeat:`, and `whileTrue` and compare the complexity and readability of the code.

## 5.6 Repeating a block with a specified increment

Message `to:do:` lets you specify the start and end values but not the step (increment) between consecutive values of the block argument. Message `to:by:do:` allows you to specify the increment too (Figure 5.8). As an example,

1 to: 100 by: 2 do: [:number | Transcript show: number printString; cr]

prints all odd numbers from 1 and 99.

<figure><img src="image_101.png" /><figcaption>Figure 5.8. Execution of `start to: end by: increment do: oneArgumentBlock`.</figcaption></figure>

All the numeric arguments of the message (`start`, `end`, and `increment`) may be any numbers - positive, negative, integer, floating-point, fractions, and so on. Don't forget, however, that floating-point arithmetic is inaccurate<fnref n="3" /> and using floating-point numbers with `to:by:do:` may produce unexpected results. The following example illustrates this point.

<footnote n="3">³ Smalltalk comments use the word of accuracy where others use the term precision.</footnote>
**Example 1: Print a table of base-10 logarithms for arguments from 1 to 10 in increments of 0.1**

The problem is easily solve with the following expression:

Transcript clear.

1 to: 10 by: 0.1 do: [:number | Transcript show: number printString;
tab;
show: number log printString;
cr]

Unfortunately, the code stops short of outputting the logarithm of 10.0 because the accumulated inaccuracy of adding 0.1 causes the program to miss 10.0. To avoid this problem, we can use a Fraction increment as follows:

Transcript clear.

1 to: 10 by: 1/10 do: [:number | Transcript show: number asFloat printString;
tab;
show: number log printString;

This code produces the desired result but seems very slow - and so is, in fact, the original floating-point solution. This could have one of two reasons: either the calculation of logarithms is so slow, or the display is slow. In this case, the cause of the problem is the output and the solution is to delay output until the string is complete and then print it out all at once. To do this, use `nextPutAll: aString` to accumulate the individual strings in the Transcript object, and then flush to output:

Transcript clear.

"Calculate and gather the results."

1 to: 10 by: 1/10 do:[:number | Transcript nextPutAll: number asFloat printString;
tab;
nextPutAll: number log printString;
cr].

"Output the accumulated results."

Transcript flush

This version is much faster and the trick is worth remembering.

**Example 2: How accurate is asRational?**

In Section 1, we showed that `asRational` performs very accurate conversion from a floating-point number to a Fraction. We would now like to find how often the original number and the fraction converted back to a floating-point number are equal, how often they are different, and what is the maximum error when they are not different. As for the error, we are interested in the relative accuracy, the value of

`(aNumber asRational asFloat) - aNumber) / aNumber`

To find the answer, we will repeat the conversion for all numbers between 1 and 10,000 in steps of 0.1, a total of 100,000 argument values.

**Solution:** With the stepwise iteration message that we just introduced, the solution is as follows:

| count maxError |
"Initialize."
count := 0. maxError := 0.
"Perform calculation."
1 to: 10000 by: 0.1 do:
    [:number| |error| (error := number asRational asFloat - number) isZero not
        ifTrue: [count := count + 1. maxError := (maxError max: error / number)]].
"Output the results."
Transcript show: 'Number of inaccurate conversions: ', count printString; cr;
    show: 'Max error: ' maxError printString
When we executed this code, we got (after worrying for a little while whether we did not have an
infinite loop)

Number of inaccurate conversions: 9357
Max error: 2.38419e-7

We conclude that asRational is very accurate because only 9,356 out of 100,000 calculations are inexact and this corresponds to about 0.9%. In other words, the conversion produces the same result as the original in 99% cases - at least in the chosen range. Moreover, when the results are not equal, the worst relative inaccuracy is only 0.00002%.

A few points are worth mentioning about the code fragment:

* We used a *temporary variable error* inside the block. You can declare any number of temporary variables inside a block whereas the number of block arguments is *given* by the value message used to evaluate the block. The temporary variable's scope is limited to the block.

* Blocks whose body does not depend on any external context are called *clean*, other blocks are either *copying* blocks or *full* blocks. As an example, a block using only internal temporary variables is clean whereas one that depends on externally declared local variables or arguments is not. Clean blocks are much more efficient, and temporary variables should thus always be declared inside blocks if possible. See the comment in BlockClosure for more details.

### Main lessons learned:

* To iterate over a range of numbers, use `to:do`: if the step is 1, and `to:by:do`: if the step is not 1.

* For multiple output to Transcript, replace multiple `show` messages with `nextPutAll`: and `flush`.

* Blocks may include any number of internal temporary variables.

* Blocks that don't depend on external context are called *clean*. They are more efficient than blocks that depend on external context, for example external temporary variables or method arguments.

### Exercises

1. Print sin and cos values of arguments from 0 to $\pi/2$ in increments of 0.05 in the Transcript.

2. Repeat Exercise 1 but print results in reverse order of arguments.

3. Print a table of all multiples of 13 between 1 and 1,000 using `to:by:do`:

4. Run the test of asRational for a different range of values to check whether our result is representative. Repeat for Double numbers.

5. Which of the following combinations is correct?

a. `method1: [:arg1 arg2 | ....]` "Definition of method1 uses value:value:"

b. `method1: [:arg1 :arg2 | ....]` "Definition of method1 uses value:"

6. Method `to:do` is a specialization of `to:by:do` that takes 1 as increment. This kind of specialization is very common and class Dialog contains several other examples. List how many such specializations occur in its file name dialogs protocol and comment on their implementation.

## 5.7 Measuring the speed of arithmetic and other operations

After implementing the code of an application, we may want to optimize its critical parts to achieve satisfactory response time. To do this, we need some means of measuring how much time a piece of code requires to run, and where it spends most time. This activity is called *profiling* and the Advanced Tools extension of VisualWorks provides tools to perform such analysis. For simple measurements, a method in class Time gives useful answers too and this is the approach that we will use in this section.

### Example 1. Comparing addition of different kinds of numbers
When we talked about different kinds of numbers, we said that some of them perform arithmetic faster than others. We will now do a little experiment to compare the speed of addition of `SmallInteger`, `LargePositiveInteger`, `Float`, `Double`, and `Fraction`. We will do this by packing addition into a block and measuring how long the block takes to execute. This is easy because class `Time` knows what time it is and to measure how long a block of code requires to execute, we just need to record the time before we start (time `t1`), the time just when the block is finished (time `t2`), and then subtract `t2-t1` to get the result. Although this idea is correct, it would not work because measuring time in seconds is too long for calculations. For this purpose, we will thus replace `Time` now with `Time millisecondClockValue` which returns a millisecond count of the computer (not derived from `Time now`). The solution is thus

```
|startTime endTime runTime |
startTime := Time millisecondClockValue.
'Execute the code here.'
endTime := Time millisecondClockValue.
runTime := startTime - endTime
```

In fact, measuring the length of execution is so useful that class `Time` includes a method called `millisecondsToRun`: that performs this task. It takes a block as its argument and returns the number of milliseconds that it takes to execute. As an example,

```
Time millisecondsToRun: [x := 2 + 3]
```

returns the number of milliseconds required to add 2 and 3 and assign the result to variable `x`. The definition of `millisecondsToRun` is

### millisecondsToRun: timedBlock

"Answer the number of milliseconds timedBlock takes to return its value."

```
| initialMilliseconds |
initialMilliseconds := self millisecondClockValue.
timedBlock value. "Evaluate the block argument here.".
^self millisecondClockValue - initialMilliseconds
```

Now that we have the tool for measuring execution time, we must devise a strategy for getting a good answer to our question. The obvious approach is to execute addition for a pair of small integers and measure how long it takes, do this again for large integers, and so on, something like

```
| t |
Transcript clear.
"Do SmallInteger first"
t := Time millisecondsToRun: [2+3].
Transcript show: 'The time needed to add two small integers is ', t printString, ' milliseconds'; cr.
"Do LargePositiveInteger next."
t := Time millisecondsToRun: [2000000000+3000000000].
Transcript show: 'The time needed to add two large integers is ', t printString, ' milliseconds'; cr.
"And so on for other kinds of numbers."
```

Unfortunately, this will not work because addition of two integers takes only a few CPU cycles and modern CPUs running at 100 million cycles per second or more take only microseconds rather than milliseconds to execute them. To get a realistic value in milliseconds, we must do the addition many times. We should thus do something like

```
Time millisecondsToRun: [10000 timesRepeat: [2+3]]
and so on
```

This is not perfect either because it measures the time to execute 2+3 plus the time needed to execute the `repeatTimes:` message. To eliminate this effect, we will correct the obtained time by subtracting the time needed to run the `repeatTimes` message by itself as in
VisualWorks library already contains a definition of **factorial** and this definition is based on iteration since $n! = n*(n-1)*(n-2)*...*2*1$. In essence, the library definition is as follows:

**factorial**

```
| tmp |
self < 0 ifTrue: ['self warn: 'Factorials are defined only for non-negative integers'].
tmp := 1.
2 to: self do: [:i | tmp := tmp * i].
^tmp
```

However, the recursive definition can be more easily implemented as follows:

**factorialRecursive**

```
self < 0 ifTrue: ['self error: 'Negative argument for factorial'].
self = 0 ifTrue: [^1].
^self * (self - 1) factorialRecursive
```

We will now examine whether recursion is slower and if so, how much slower. We will use the technique from Example 1 as in the following code fragment:

```
| t |
Transcript clear.
t := Time millisecondsToRun: [1000 factorial].
Transcript show: 'Nonrecursive factorial. Time: ', t printString; cr.
t := Time millisecondsToRun: [1000 factorialRecursive].
Transcript show: 'Recursive factorial. Time: ', t printString; cr
```

When I executed this code, I obtained the following results

```
Nonrecursive factorial. Time: 131
Recursive factorial. Time: 190
```

and concluded that although there is a difference, it is smaller than I expected. We will thus analyze the code and try an find the explanation.

Both methods begin with the same test and the essence of the remaining calculation is multiplication of intermediate results. In the case of **factorial**, this is followed by incrementing the number which should be rather negligible with respect to multiplication, and another iteration. Could it be that multiplication is the culprit? Could it be that multiplication takes so long that it masks everything else and that our tests actually mostly measure the duration of multiplication rather than the effect of recursion? This is quite possible, especially when the numbers become **LargePositiveInteger** (which they do very quickly) - we have already seen how slow their arithmetic is.

To test this hypothesis, we will do recursion with a block that takes much less time - calculation of the sum of numbers from 1 to n using a recursive approach based on

```
sum(n) = sum(n-1) + n
```

and an iterative approach based on

```
1 to: n: do: [:number | sum := sum + number]
```

We will not use the obvious solution

```
sum(n) = n*(n+1)/2
```

because our goal is to compare recursion with iteration doing over the same operation.

When we defined a sum method corresponding to these two styles(left as an exercise) and ran the following test
| t |

Transcript clear.

t := Time millisecondsToRun: [10000 sum].

Transcript show: 'Nonrecursive sum. Time: ', t printString; cr.

t := Time millisecondsToRun: [10000 sumRecursive].

Transcript show: 'Recursive sum. Time: ', t printString; cr

the result was much more like what we expected and confirmed our hypothesis:

Nonrecursive sum. Time: 2

Recursive sum. Time: 22678

This leads to the following conclusion: Recursive programs generally execute slower than their iterative counterparts. However, when the calculation performed during each recursive step is time-consuming, the difference between recursion and iteration may be negligible. A corollary is that if the calculation is substantial, converting a natural recursive solution to a less obvious iterative solution may not be worth the trouble. The elegance of recursive solutions makes them easier to understand which contributes to the maintainability of code. This sometimes makes recursive solutions preferable in complex problems, particularly in earlier stages of development before the code is optimized for speed.

**Example 3: Observing recursion in action**

To complete this section, execute the following code fragment

self halt.

5 factorialRecursive

and follow the execution of the recursive definition of the factorial all the way from 5 to 0 by using *send* in the Debugger. When *self* decrements from the initial value of 5 to the end value of 0, the debugger window is as in Figure 5.9, showing all the stacked recursive calls. Recursion then begins to unwind, completing the messages piled up on the stack, and eventually returning to the original program fragment with the final result. This little experiment shows very nicely the nature of recursion.

<figure><img src="image_102.png" /><figcaption>Figure 5.9. The top two levels of the message stack during the execution of 5 factorialRecursive.</figcaption></figure>
## Main lessons learned:

* The first implementation of an application should not focus on efficiency. Speed should only become a concern when the running application is too slow.

* In trying to improve speed, focus on those parts of the code where the application spends most of its time.

* Determining where the application spends most of its time is called profiling.

* Profiling can also be used to check how much memory an application uses and where.

* Analyzing code for efficiency requires careful analysis because the most natural conclusions may be incorrect.

* Recursion requires overhead but this overhead may be outweighed by calculation required in each recursion step.

* Solving problems with recursion is sometimes much easier than using other approaches and recursive solutions are often preferred until final speed optimization.

## Exercises

1. Method `timesRepeat`: is implemented by the `whileTrue`: message and so `timesRepeat`: must be slower. How much slower is it?

2. Test whether our precautions in Example 1 (eliminating the effect of repetition) were justified.

3. Add `Double` arithmetic to Example 1 and compare with `Float`.

4. We noted that the duration of addition of large integers depends on their size. Obtain an experimental dependency between the duration of addition and the length of the operands, and explain it qualitatively. To do this, create some large integers such as 100 factorial, 500 factorial, and 1000 factorial, store them in variables x, y, and z, and perform `x+1` and `y + 1` and `z + 1` (without assignment) a sufficient number of times, measuring the speed. Print the results along with some indication of the size of the numbers, draw a graph of the dependency, and explain it.

5. Compare the speed of `+ - *` and `/` in the most important number classes.

6. Write recursive and non-recursive definitions of the methods used in Example 3 and test their relative speed.

7. About 2,000 years ago, the Greek mathematician Euclid invented the following algorithm for calculating the greatest common divisor `gcd(m,n)` of two positive integers `m` and `n`:
   If `m = n`, `gcd = m`
   If `m < n`, `gcd(m,n) = gcd(n,m)`
   If `m > n`, `gcd(m,n) = gcd(m-n,n)`
   Use this recursive definition to define method `gcdRecursive`: to calculate `gcd` recursively.

8. VisualWorks library contains a built-in `gcd`: method. Compare its speed with the speed of the recursive implementation. Analyze the result.

9. The Fibonacci series is defined as follows: `Fib(n) = 1` for `n = 1`, 2, `Fib(n-1)` + `Fib(n-2)` for `n > 2`, and F undefined for all other values of `n`. Write and test method `fibonacci` to calculate Fibonacci numbers.

## 5.8 A new class: Currency

In this section, we will define a new class as a simple application of numbers. In doing this, we will introduce new techniques useful for testing.

When we discussed number classes, we noted that `FixedPoint` was designed as a possible solution of the problem of representing currency. The problem is not as simple as it might seem, for example because operations such as conversion from one currency to another are very sensitive to tiny inaccuracies whose effect becomes significant when we deal with billions of dollars or convert back and forth between currencies.

We will now define an alternative simple `Currency` class for currencies whose units consist of dollars and cents. Our solution is far from perfect and we leave the fine points of currencies to experts.
Design

The behaviors that we expect of `Currency` include creation (create a new `Currency` object), arithmetic (add or subtract two `Currency` objects), comparison (equal, not equal, less than, and so on), and printing (for testing and inspecting). Each of these behaviors will be implemented as a protocol, and the notion of dollars and cents suggests the use of two instance variables called `dollars` and `cents`.

We have now decided all the major features of `Currency` except where to put it in the class hierarchy. `Currency` objects are somewhat like numbers, so they will be somewhere on the `Magnitude` branch of the class tree. Since currencies can do simple arithmetic, we must consider whether the superclass should be `ArithmeticValue` or even `Number`. However, although we want to be able to add and subtract `Currency` objects, we don't need any other arithmetic and in this sense, `Currency` objects are thus distinct from numbers. Also, the comment of `ArithmeticValue` says that its subclasses must implement certain arithmetic messages needed by some other messages, and since we don't really need most of them, this reinforces our opinion that `Currency` should not be a subclass of `ArithmeticValue`. Most importantly, however, currency objects are conceptually different from numbers and it does not make sense to think of them as specialized numbers.

We conclude that making `Currency` a subclass of `ArithmeticValue` or `Number` has too many disadvantages and few advantages and we will thus define it as a subclass of `Magnitude`, inheriting certain comparison messages. In this, we will follow in the footsteps of those who defined classes `Time` and `Date`. We will put `Currency` into the existing category `Tests` as we did with class `Name`.

We are now ready to define the new class. Start by opening the browser on category 'Tests', edit the class template as in

```
Magnitude subclass: #Currency
instanceVariableNames: 'dollars cents'
classVariableNames:"
poolDictionaries:"
category: Tests'
```

and execute *accept* from the <operate> menu of the text view.

As the next step, add a comment explaining the purpose of the class, its instance variables, and any special notable features. Our comment for `Currency` will be as follows:
I implement a decimal currency such as dollars and cents.

Instance variables:

dollars <Integer> - the dollar part of the currency

cents <Integer> - the cent part of the currency

We are now ready to implement the behaviors. Since we cannot do anything unless we can create an instance, we will start with the creation message.

## Creation

The style that we want to use for the creation message is to specify initial values for dollars and cents as in

Currency dollars: 100 cents: 45

Message `dollars:cents:` is obviously a class message because its receiver is `Currency`, and its implementation will follow Smalltalk's established pattern for creation messages:

1. Create a new `Currency` object by sending `new` to the `Currency` class. This inherited message creates an uninitialized instance of `Currency` with its `dollars` and `cents` instance variables set to `nil`.

2. Send `dollars: anInteger` to this instance, setting its instance variable `dollars` to the value of the argument. (Accessing method `dollars`: does not yet exist and we will have to define it.)

3. Send `cents: anInteger` to the `Currency` object, setting its instance variable `cents` to the value of the argument. (We will again have to define method `cents: first`.)

4. Return the new `Currency` object.

The definition written along these lines is as follows:

`dollars: dollars:anInteger cents: cents:anInteger`

“Creates a new initialized `Currency` object.”

^ self new

dollars: dollars:anInteger;

cents: cents:anInteger

Note the following points:

* The effect of `self new` is equivalent to `Currency new` but the `self new` version is preferable: If we created a subclass of `Currency` such as `NewCurrency`, the version using `self new` would create an instance of `NewCurrency` (which is what we would probably expect) whereas the version using `Currency new` would create an instance of `Currency` (probably not what we want). Conclusion: Don't refer to a class explicitly unless you must.

* Although the inherited version of `new` is defined in class `Behavior`, it creates an instance of `Currency` or whatever class sends the message.

* It is a very common mistake to forget the return operator `^` in a creation method. The method then returns the class rather than the new instance.

* Use cascading to send initialization messages to the new instance of `Currency`.

Although we could now enter the definition of `dollars:cents:` into the browser and compile it before creating `dollars:` and `cents:`, it will be better to define accessing methods `dollars:` and `cents:` first. Both are instance messages because their receiver is `self new` - an instance of `Currency` - and they simply assign new values to instance variables:

`dollars: anInteger`

dollars := anInteger
and similarly for cents:.

The methods are so trivial that they don't require a comment. Create these instance methods and
the `dollars:cents:` creation method, and test whether everything works by executing

Currency dollars: 100 cents: 47

with *inspect*. When you examine the values of instance variables, you will find that everything is OK.

## Printing

At present, the only way to see the values of instance variables of *Currency* objects is to open an
inspector or to access them. Our life would be much easier if we could display the components of *Currency*
by `printString` but this would, of course, only produce the string 'a *Currency*'. If we want `printString` to
produce useful information about instances of a new class, we must change the `printString` mechanism and to
do this, we must understand how it works.

When we browse the implementers of `printString` we find that there is essentially only one - class
*Object* - and that the definition reads as follows:

### `printString`

"Answer a String whose characters are a description of the receiver."
| aStream |
aStream := WriteStream on: (String new: 16).
self printOn: aStream.
^aStream contents

The critical message is obviously `self printOn: aStream` and to change the behavior of `printString`, we must therefore redefine `printOn:`. There are many implementors of `printOn:` because this method customizes `printString` to produce useful information. As an example, the definition in class *Contract* is as follows:

### `printOn: aStream`

`aStream nextPutAll: self class name, ' as ', self server name, ' :: ', name printString; cr`

and we will use it as a template even though we don't understand very well yet what it does. First, however,
we must decide how we want a *Currency* to display itself. We selected the following style:

Currency dollars: 100 cents: 47

executed with `print` it (thus using `printString`) should produce

a *Currency* 100 dollars, 47 cents

To produce this format, our `printOn:` message must execute the following steps:

1. Output the name of the class into `aStream` (we don't care what a `Stream` is, at this point).

2. Output the dollars part followed by 'dollars'.

3. Output the cents followed by 'cents'.

According to this algorithm and the `printOn:` template, we define `printOn:` in class *Currency* as follows:

### `printOn: aStream`

"Append to the argument, aStream, the description of a *Currency*.
aStream nextPutAll: self class name,
    self dollars printString,
    'dollars, ',
    self cents printString,
    'cents, '
To test how this method work, we execute

Transcript show: (Currency dollars: 13 cents: 27) printString

and we indeed obtain the desired output.

Note again that we did not need to understand the details, such as what a **Stream** is, in order to write a working definition. This is quite all right - don't try to understand every object that you must use; all you need is to know how to use it. A carpenter also does not need to know what is inside a drill if he wants to use one, and you don't care about the internal operation of the mail system if you want to send a letter. (On the other hand, it never hurts to understand your tools and if you don't have any pressing matters on your agenda, go ahead and learn about a new class.)

It is interesting to note that `printString` is also used by the inspector to display `self` and when you execute

Currency dollars: 13 cents: 27

with `inspect`, you will again obtain the desired information under the `self` entry in the inspector window.

## Arithmetic and comparison

We will restrict ourselves to addition and leave subtraction to you. To add two currencies, we will create a new `Currency` object and set its `dollars` part to the sum of the `dollars` parts of the receiver and the argument, and the `cents` part to the sum of the `cents` parts as follows:

### + aCurrency

^Currency dollars: (self dollars + aCurrency dollars) cents: (self cents + aCurrency cents)

We assume that you defined the accessing messages `dollars` and `cents`. Add the `+` method to the arithmetic protocol of `Currency` and test it by executing

(Currency dollars: 100 cents: 47) + (Currency dollars: 25 cents: 32)

with `inspect` or `print it`. The result shows that everything is OK<fnref n="4" />.

Finally the `comparison` protocol. We already know that some comparison methods are defined in class `Magnitude` and we will now check its comment to find which comparison methods must be defined so that we can inherit the rest. The relevant part of the comment of `Magnitude` is

Subclasses must implement the following messages:

<
=
hash

We will start with equality. Two `Currency` objects are equal if they have the same number of dollars and the same number of cents, hence

### = aCurrency

^ (self dollars = aCurrency dollars) and: [self cents = aCurrency cents]

Our next target is the `hash` method. Its purpose is to assign an integer value to an object, such that can be used as its shorthand representation, something like a student number. Just like a student number or any other id, each object should have its unique hash value to distinguish it from other similar objects. This may be difficult and so hashing follows a weaker rule, namely that equal objects should have the same hash value. Because of this, and because some very important operations in Smalltalk use hashing instead of equality, redefining equality should always be accompanied by redefining `hash`.

<footnote n="4">⁴ If you have reservations about our approach, wait for the improved implementation later.</footnote>
A hash method is already defined in class Object but since we redefined equality, we will also redefine hash. Our class has two internal variables and we will thus borrow a hash definition from another class with two variables - class Fraction - and convert it for our needs. Our definition will be

## hash

```
^dollars hash bitXor: cents hash
```

We leave the definition of `<` to you as an exercise.

## Main lessons learned:

* When constructing new classes and methods, start with creation, accessing, and printing protocols and test your definitions immediately.

* The recommended style for creating a new instance is to initialize its instance variables.

* Don't refer to a class explicitly unless you must.

* A very frequent mistake in writing a creation method is to forget the return operator. The method then returns the receiver class rather than the new object.

* When you need to define a specialized version of an existing method, check how other classes do it and follow the template. You don't have to understand the details.

## Exercises

1. Add class protocol testing and write methods to perform complete testing of `Currency`.

2. As an alternative to the previous exercise, remove testing from `Currency` and create a new class called `CurrencyTesting` containing test methods in a class protocol. The `Currency` objects used in the tests can be stored in class variables and the class variables initialized in the `class` initialization method `initialize`.

3. Write and test the `-` method for subtraction of currencies.

4. Write and test the implementation of `<`. What about `<=`, `>`, and `>=`?

5. In the definition of `+` a`Currency`, we had to access the components of a`Currency` with accessing methods `dollars` and `cents`. The `dollars` and `cents` instance variables of the `receiver`, however, could have been accessed directly. Many Smalltalk experts argue that instance variables should always be accessed by accessing methods even though it is not strictly necessary. Give one argument supporting this position and one argument against it.

6. Define a new class called `UniformRandom` that allows the user to create a random number generator for numbers uniformly distributed in any interval, not just between 0 and 1 as `Random` does. The creation message should be `UniformRandom from: startNumber to: endNumber` and the instance message for creating a new random number should be `next`. (Hint: It is tempting to make `UniformRandom` a subclass of `Random` because they are so closely related. However, `UniformRandom` would not inherit any useful functionality or components from `Random`, it would have to redefine `next`, and its creation message is different - so there is no point in subclassing. Since there is no related class in the Smalltalk hierarchy, make `UniformRandom` a subclass of `Object` and define it with instance variables `generator` - an instance of `Random` to be used to calculate random numbers in `<0,1>` - and `start` and `end` to hold the endpoints of the interval. Calculations of new random numbers will depend on getting a new random number from `generator`, and scaling it using the `start` and `end` values of the interval. As we mentioned before, this approach is called *delegation* because `UniformRandom` passes responsibility for a part of its functionality to one of its components. *Delegation is generally preferred to inheritance which should be used only in cases of pure specialization.*)

## 5.9 Another implementation of `Currency`

Our existing implementation of `Currency` is fine in terms of its protocols but unsatisfactory in implementation. As an example, expression
Currency dollars: 100 cents: 3412

creates a Currency object with 100 dollars and 3412 cents but we would prefer a Currency object with 134
dollars and 12 cents. Similarly,

Currency dollars: 100 cents: -34

creates a strange object that does not make sense, and our comparison message = returns false for

(Currency dollars: 100 cents: 3412) = (Currency dollars: 134 cents: 12)

whereas we would probably expected true.

If we had thought about the implications of our design more carefully (in other words, if we did the
design properly), we would have discovered the problem and changed the design before implementing it. At
this point, we will have to make some changes. One possible approach is to leave the protocols, and
redefine Currency in terms of cents only and eliminate dollars. Let's do this and see what implications it has
for the methods that we had defined.

## Creation

We still want to be able to create Currency objects from dollars and cents and so our creation
message must convert dollars to cents. The new version of the creation method is simply

### dollars: dollarsInteger cents: centsInteger

"Creates a new initialized Currency object."

^ self new cents: centsInteger + integer1 * dollarsInteger

## Accessing

We don't really need method `dollars:` (it was only needed for creation) but we will leave it in
because we don't want to change the message interface, in case somebody wrote another class that depends
on it. We will leave it to you to redefine it to change dollars to cents. Methods `cents` and `dollars` must also
be changed, as in

### dollars

"Return dollar part of amount."

^ cents quo: 100

and

### cents

"Return cents part of amount."

^ cents \\ 100

## Arithmetic

The old implementation is

### + aCurrency

^Currency dollars: self dollars + aCurrency dollars cents: self cents + aCurrency cents

but with the new creation method `cents:`, we can define addition much more easily as follows:

### + aCurrency

^Currency cents: self cents + aCurrency cents

The only problem is that we don't have a creation message called `cents`: but this is easy to fix:
### cents: centsInteger

"Creates a new initialized Currency object."

^ self new cents: centsInteger

Note that we now have two different cents: methods but that's OK because one is a class method and the other is an instance method. This means that Currency cannot be confused because only one cents: method exists for it, and instances cannot be confused either.

### Comparison

Comparison also becomes much simpler - and we don't have to worry about cents above 100 or below -100

### = aCurrency

^self cents = aCurrency cents

The hash method can use the hash value of integer cents as follows:

### hash

^cents hash

### Printing

We will leave this protocol to you as an exercise.

This completes our redesign. The changes that we made are very small and simplify the code substantially. Note that they don't affect any other code that may use Currency because the old message interface remains, both in form and in effect. In particular, the test methods suggested in exercises at the end of the previous section will also work and can be used to test the new implementation. The principle of information hiding thus allowed us to reimplement Currency without any effect on any applications that may already be using it. (Note, however, that if we created some Currency objects using the first implementation and stored them in a file, we could not reuse them with the new implementation without some additional conversion.)

### Main lessons learned:

* If we modify a class without changing its message interface, objects already using the class will not be affected. This is a consequence of information hiding.

### Exercises

1. Complete the new implementation of Currency. Don't forget to change the comment and to retest the new implementation.

2. Compare our implementation of Currency with FixedPoint with scaling factor 2.

3. In an article in Smalltalk Report, Kent Beck described an implementation of currency that goes beyond dollars and cents and avoids conversion inaccuracy as much as possible. His approach is based on the fact that a wallet might contain any combination of currencies such as US $3.50, Canadian $6.75, and Japanese ¥300. This combination does not automatically convert to one currency unless explicitly required. Implement a Currency class based on this idea but restricted to four currencies: Canadian dollars, US dollars, British pounds, and French francs. When an amount is added or subtracted, arithmetic is done only on equal denominations and conversion is performed only when explicitly required.
4. Currency is a class that operates on objects measured in units. Develop a class called Length to handle the metric system with millimeters, centimeters, meters and kilometers, and the British system with inches, feet, yards, and miles. Use the same approach as in the previous exercise.

5. Repeat the previous exercise for weight objects in units of grams, dekagrams, and kilograms on one side, and ounces and pounds on the other.

## 5.10 Generalized rectangles

As another example of a new class, we will now implement a new class for rectangles. One rectangle class, called Rectangle, is already in the library but it is restricted to rectangles with horizontal and vertical sides because its intended use is for windows on the screen. Our class will handle any rectangles and we will thus call it AnyRectangle. Before we start developing it, let's decide what we want to do with it and what functionality it should have.

Our reason for adding AnyRectangle is that rectangles are fairly common geometric objects and that we might want to use them in a drawing program and similar applications. The main purpose of the new class is thus to support display and graphics operations such as *move* and *rotate*. Purpose determines functionality and we thus decide on the following protocols:

* creation

* accessing - get and set selected rectangle parameters

* transformation - move and rotate

* display - drawing on the screen

* printing - for testing purposes

The next question is how to represent a rectangle. The horizontal/vertical Rectangle class uses the coordinates of the upper left and lower right corner because the orientation of the sides is known. In our case, two corners are not enough because there is an infinite number of rectangles that have the same two corners. As an example, if the two given corners are C1 and C2 in Figure 5.10, any rectangle whose third corner lies on a circle with diameter C1 and C2 is acceptable.

<figure><img src="image_103.png" /><figcaption>Figure 5.10. Two corners, such as C1 and C2, don't define a unique rectangle.</figcaption></figure>

Although two corners don't identify a rectangle, three corners do. However, three points don't necessarily define a right angle and so three points are not automatically corners of a rectangle. We will thus represent a rectangle by its two opposite corners and an angle, thinking of the rectangle as a rotated horizontal-vertical rectangle (Figure 5.11).

<figure><img src="image_104.png" /></figure>
<figure><img src="image_105.png" /></figure>

Having made this decision, we can now start implementing the methods. We will use **Rectangle** as the superclass of **AnyRectangle** because it already defines all of the protocols we need, but we will leave it to you to check whether all inherited protocols remain valid as an exercise.

**Creation.** Since a rectangle is defined by three instance variables, the creation method will have three keywords. It will create a new instance and then send instance messages to assign instance variable values:

**origin: point1 corner: point2 angle: radians**

"Create a rectangle with three corners."

^self new origin: point1; corner: point2; angle: radians

where the instance accessing methods are standard setter methods. A typical creation message would look like

AnyRectangle origin: 1@100 corner: 11@90 angle: 3.14/4

**Transformation.**

**Moving** a rectangle means shifting the x coordinate and the y coordinate of each corner without changing the angle. This means that **AnyRectangle** is moved the same way as an ordinary **Rectangle** and the inherited methods **moveTo:** and **moveBy:** should thus work without change.

**Rotation.** Before we start thinking about implementation, we must decide what kind of rotation we want. First, we will assume that we perform rotation by keeping the upper left corner (inherited instance variable origin) fixed and rotating the rectangle around it. In principle, we can see two ways of doing this: by specifying the angle of rotation, and by dragging the opposite corner interactively.

The first kind is easy – we just increment the angle as follows:

**rotateByAngle: aNumber**

angle := angle + aNumber

If we want to lay a foundation for letting the user rotate the rectangle interactively, the task gets a bit harder and we must do some trigonometry. The logic of the operation is as follows:

1. Calculate the angle of rotation from the new position of the dragged corner.

2. Change the **angle** instance variable by the calculated rotation angle.

We leave it to you to figure out the details but remember that the screen coordinate system measures x from left to right and y from top to bottom. Thanks to predefined methods for calculating distance and similar parameters, this problem is easier than you might think.

**Printing.** From the section on **Currency**, we know that if we want a new **printString** behavior, we must redefine the **printOn:** method. There is no reason to make the string for **AnyRectangle** much different from the string for **Rectangle** (the only difference is that we need add the **angle** variable) and so we will reuse **printOn:** from superclass **Rectangle**

**printOn: aStream**

"Append to the argument aStream a sequence of characters that identifies the receiver. The general format is **originPoint corner: cornerPoint**."
origin printOn: aStream.

aStream nextPutAll: ' corner: '.

corner printOn: aStream

and extend it as follows:

**printOn: aStream**

"Append to the argument aStream a sequence of characters that identifies the receiver. The general format is originPoint corner: cornerPoint angle: angle."

super printOn: aStream.

aStream nextPutAll: ' angle: '.

angle printOn: aStream

In this definition, super is a special identifier that allows us to access an identically named method defined higher up in the class hierarchy. We will have more to say about it in Chapter 6.

*Displaying*. We will draw the rectangle by drawing the individual sides one after another. The subject of drawing will not be covered until Chapter 12 and we will thus implement this method by imitating the display method in class *LineSegment* which is defined as follows:

**displayStrokedOn: aGraphicsContext**

"Stroke the receiver on the supplied GraphicsContext."

aGraphicsContext displayLineFrom: start to: end

In this context, 'stroking' means simply drawing, and we don't need to know what a GraphicsContext is at this point. The method for displaying *AnyRectangle* must calculate the corners and draw the four lines. The whole definition is

**displayStrokedOn: aGraphicsContext**

"Stroke the receiver on the supplied GraphicsContext."

| topRightCorner bottomLeftCorner bottomRightCorner |

"Calculate corners."

topRightCorner := self topRightCorner.

bottomLeftCorner := self bottomLeftCorner.

bottomRightCorner := topRightCorner + bottomLeftCorner - origin.

"Draw straight lines connecting corners."

aGraphicsContext displayLineFrom: origin to: topRightCorner.

aGraphicsContext displayLineFrom: topRightCorner to: bottomRightCorner.

aGraphicsContext displayLineFrom: bottomRightCorner to: bottomLeftCorner.

aGraphicsContext displayLineFrom: bottomLeftCorner to: origin

where method topRightCorner calculates the top right corner on the basis of simple trigonometry

**topRightCorner**

^origin + ((self width * angle cos) @ (self width * angle sin) negated)

and the remaining corner finding methods are left as an exercise. To test the new class, execute the following program to display several rectangles in the active window

| anyRectangle |

anyRectangle:= AnyRectangle origin: 10@80 corner: 50 @ 130 angle: 0.

anyRectangle displayStrokedOn: Window currentWindow graphicsContext.

anyRectangle moveBy: (100@50).

anyRectangle displayStrokedOn: Window currentWindow graphicsContext.

anyRectangle moveBy: (100@-50); rotateBy: (Float pi / 2).

anyRectangle displayStrokedOn: Window currentWindow graphicsContext.

anyRectangle moveBy: (100@50); rotateBy: (Float pi / 4).

anyRectangle displayStrokedOn: Window currentWindow graphicsContext.
## Exercises

1. Explore class **Rectangle** and write its short description, listing its major behaviors. Comment of the number of useful behaviors that **AnyRectangle** inherits from **Rectangle**.

2. Complete **AnyRectangle** and test it. Check whether defining it as a subclass of **Rectangle** is appropriate and which of its behaviors might have to be redefined.

3. Add a method for drawing a filled rectangle. (Hint: Examine **Rectangle**.)

4. Drawing editors usually allow shrinking and stretching a geometric object. Decide how this could be done and implement the appropriate methods.

## Conclusion

VisualWorks library includes a large hierarchy of number classes, mainly because hardware represents and processes different numbers differently. Another reason why there are so many number classes is that some computer applications require numbers that cannot be directly processed by hardware but are very easy to implement and provide extra programming convenience.

The most important number classes are integers and floating-point numbers. Smalltalk integers are implemented by three classes that separate the class directly implementing arithmetic in hardware from those that are added to provide unlimited integer range. Conversions from one class to another are transparent - performed automatically as needed.

Floating-point numbers are available in two implementations that differ in the number of bytes internally used to represent them and provide different accuracy and range. Conversion between high precision and ordinary floats is *not* automatic. In spite of their high precision, floating-point numbers are inherently inaccurate for decimal calculation because decimal numbers are incompatible with computer binary codes. Ignoring this principle may have serious consequences for comparison and iteration with floating-point ranges and increments. Floating-point arithmetic is also much slower than SmallInteger arithmetic and floating-point numbers require more memory. Floating-point numbers should thus be used only when necessary.

In addition to integer and floating-point numbers, Smalltalk also implements fractions with an integer numerator and denominator, fixed point numbers with accurate internal representation and a fixed number of decimal digits, complex numbers, and various kinds of special numbers representing values such as infinity. Of these, fractions and fixed-point numbers are the most important. They are inherently accurate but their arithmetic is very slow.

All Smalltalk number objects understand many messages implementing various kinds of arithmetic, mathematical, and conversion operations. Arithmetic is implemented on the basis of primitives and double dispatching. Primitives are messages translated into CPU code and implemented without further message sends. Double dispatching means re-sending (re-dispatching) a one-argument message to the argument, using the original receiver as the argument. Double dispatching eliminates tests because the dispatched message implies the type of the argument. Although the main use of double dispatching is in arithmetic, the principle has general validity.

In addition to calculations, numbers are also used for iteration - repetition of a block of statements a fixed number of times or over a range from a given starting value to a given end value, in specified or default fixed increments. The latter messages use blocks with internal arguments.

Blocks may have zero, one, or more internal arguments and the number of arguments is given by the type of value message used to evaluate the block. All value messages for block evaluation are defined in class BlockClosure. Blocks may also have internal temporary variables and their use is preferable to temporary variables declared in the surrounding context because closed blocks independent of the surrounding context are more efficient.

Profiling and timing refers to measurement of the time, message send profile, and memory required to execute a block of code. We have shown that millisecondsToRun: defined in class Time provides a simple but primitive way of timing. The Smalltalk profiler tool produces much more accurate and detailed answers.

Information hiding makes it safe to change internal implementation of an existing class. As long as the message interface does not change, changes of internal implementation don't affect existing applications that depend on the class.
When implementing a method that is an extension of an inherited behavior, we usually execute the inherited behavior and then additional code. Reference to inherited behavior (methods defined higher up in the class hierarchy) can be obtained by using identifier **super**.

**Important classes introduced in this chapter**

Classes whose names are **boldfaced** are very important, classes whose names are printed in *italics* are less important, classes whose names are printed in regular font are not of much interest.

*ArithmeticValue*, *Date*, *Double*, *FixedPoint*, *Float*, *Fraction*, *Integer*, *Number*, *LargeInteger*, *LargeNegativeInteger*, *LargePositiveInteger*, *MetaNumeric*, *Random*, *Rectangle*, *SmallInteger*, *Time*.

**Terms introduced in this chapter**

*block argument* - argument defined and used inside a block; specified using syntax [:x:y| ...]

*closed block* - one whose body does not depend on the external context

*double dispatching* - re-sending a one-argument message to the argument, with the original receiver as argument

*fixed-point number* - number with a fixed number of decimal digits

*floating-point number* - number with decimal point

*integer number* - number without decimal point

*nested block* - block within another block

*message expression* implemented directly by machine code and used instead of a message send

*profiling* - experimental analysis of program behavior with regards to its execution speed, relative frequency of message sends, and memory requirements

*random number generator* - an object that can produce an unlimited stream of numbers randomly distributed according to some probabilistic formula

*temporary block variable* - variable declared and valid inside a block; distinct from block argument
# Chapter 6 - Design of applications with graphical user interfaces

## Overview

In this chapter, we shift our attention temporarily to applications with graphical user interfaces (GUIs). Since our focus is on principles of user interfaces, our applications will be very simple and we will concentrate on implementation rather than design. More complicated examples will be presented later.

VisualWorks applications rely on a three-part structure GUI ↔ application model ↔ domain model. The GUI is what the user sees and interacts with, the domain model is the collection of classes modeling the objects in the problem world, and the application model is the link between the GUI and the domain model. The application model converts GUI events such as keyboard input to domain model calculations and communicates changes of values in the domain model back to GUI components. This initiates updates of the user interface. Since all application models have much common behavior, VisualWorks provides class ApplicationModel with the shared functionality and all applications define their application models as subclasses of ApplicationModel.

The operation of VisualWorks GUI components is based on the separation of the display (view), the user interaction (control), and the object responsible for the displayed data (model). This separation is called the model-view-controller or MVC paradigm.

The implementation of the model uses a special object called the value holder. Value holders encapsulate a value and keep track of their 'dependents'. When the value of a value holder changes, it automatically broadcasts a notification to all its dependents and they respond appropriately. This dependency provides a mechanism for linking the view part of GUI widgets to their models.

An important concept of the ApplicationModel is that it provides several 'hooks' - methods that are always executed when the application opens or closes the application. By re-defining these methods in your application model subclass, you can control the start-up and closing of your application.

### 6.1. Example of application development: An application selector

The main purpose of this chapter is to show how to develop an application with a graphical user interface (GUI). In this section, we will present the principles of VisualWorks applications, give the specification of a very simple problem, and outline the solution. Details of implementation will be presented in the following sections.

#### Principles of VisualWorks applications

Before we can start designing an application, we must understand how VisualWorks views an application. VisualWorks application architecture is based on the view that a typical application has a graphical user interface (GUI) that allows user interaction, a domain model - a collection of objects representing the entities from the problem world, and an application model that connects the GUI with the domain model (Figure 6.1). (VisualWorks also provides means to create headless applications with no user interface but in this book, we will deal only with headfull applications with a GUI.)

<figure><img src="image_106.png" /></figure>
Figure 6.2. Typical VisualWorks applications consist of a graphical user interface (GUI), an application model, and a domain model. Very simple applications don't have a domain model, headless applications don't have a GUI and an application model.

Here is how an application implemented as a GUI-Application Model-Domain Model triad works:

1. User executes a message to open the application.

2. The windows open and the following sequence is repeated until the user terminates execution:

a. The user creates an *input event*, for example clicks a mouse button over a check box widget.

b. The widget sends a message to the application model.

c. The application model informs appropriate objects in the domain model, for example, requesting recalculation of the balance of a client's account.

d. Domain model objects perform the necessary processing and inform the application model of their changes.

e. The application model notifies the appropriate GUI components of the change.

f. Affected GUI components request the new values and redisplay themselves.

### Application Selector Specification

We are to develop a program to allow the user to choose and run selected applications. The user interface will be as in Figure 6.1 - a window with a group of buttons labeled with the names of examples, a *Help* button, a *Run* button, and a *Quit* button. When the window initially opens, the Text View on the right instructs the user to select an application by clicking its button. Doing so displays a brief description of the selection. When the user then clicks *Run*, the selected application opens. Clicking *Help* opens a help window with general information, and *Quit* closes the window and ends execution.

<figure><img src="image_107.png" /><figcaption>Figure 6.1. Desired user interface of *Application Selector* program. Button *assistant* has just been clicked.</figcaption></figure>

### Design
Our application is so simple that we don't need any domain model - the applications activated by the buttons already exist, and we don't need any data beyond the string displayed in the Text View (Figure 6.1). We will thus restrict ourselves to the GUI and the application model, a class to be called `ApplicationSelector`.

What about the GUI classes themselves? Do we have to define classes to draw the buttons and the Text View, to respond to mouse clicks, to draw the window, to redraw a piece of a window when it is uncovered after having been obscured by another window, and so on? Fortunately, we don't because all these functions are included in the library. In this example, *the only class that we will have to design is class ApplicationSelector*.

Designing a class means deciding its functionality, defining the information that it holds in its instance variables, and selecting its place in the class hierarchy. The decision as to where to put `ApplicationSelector` in the class hierarchy is simple: If we want to benefit from the built in functionality of VisualWorks application support, `ApplicationSelector` must be a subclass of `ApplicationModel`. We will explain the principles of `ApplicationModel` later but for now, we will use it as a black box. The place of `ApplicationSelector` in the class hierarchy will thus be as follows:

### Object ()
*   Model ('dependents')
*   ApplicationModel ('builder')
*   **ApplicationSelector (?)?**

where the question marks represent the instance variables of `ApplicationSelector` that still remain to be determined.

What are the responsibilities of `ApplicationSelector`? It must

* open the window

* respond to example buttons by displaying explanatory text in the Text View

* know which example is currently selected so that it can be run when the user clicks the *Run* button

* respond to *Help* and *Quit* buttons

* hold information needed to display the text view and the help window.

`ApplicationSelector` thus needs an instance variable to hold a reference to the name of the currently selected example (we will call it `currentSelection`) and possibly some additional instance variables to hold information for the GUI widgets. We will see which additional variables will be needed when we learn more about the widgets. A more detailed account of the desired functionality can now be stated as follows:

* Clicking an example button sends a message to `ApplicationSelector` which stores a reference to the name of the class that will run the clicked example in variable `currentSelection`. The message then obtains the text to be displayed in the Text View, and makes sure that the Text View displays it.

* Clicking the *Run* button sends a message asking `ApplicationSelector` to open the application whose class name is stored in `currentSelection`. If no application is selected, clicking *Run* opens a notifier telling the user to select an example. (This is a reasonable extension of the original specification.)

* Clicking *Help* opens a help window with general help information.

* Clicking *Quit* asks `ApplicationSelector` to close the window and terminate.

We now have enough information to start implementing the application. If we knew more about VisualWorks GUIs, we would know which variables are required for the widgets and we could include them in our list now. As it is, we must first learn about VisualWorks' GUI.
## Main lessons learned:

* VisualWorks application architecture has three components - a graphical user interface (GUI), an application model, and a domain model.

* Common GUI components are included in the Smalltalk library.

* The domain model is a collection of classes representing the problem world.

* The application model provides the link between GUI components and domain objects, and holds the description of the layout of the user interface.

* Application models are direct or indirect subclasses of the built-in class *ApplicationModel*.

* In very simple applications, domain information may be implemented as instance variables of the application model. In such cases, there is no need for a distinct domain model.

* An input event is an action caused by an operation such as pressing a key on the keyboard or clicking a mouse button. It activates a GUI widget and sends a message to the application model.

## Exercises

1. Develop conversations for Application Selector scenarios and use them to confirm that our analysis is complete.

## 6.2 Implementing the user interface - the window

To create a graphical user interface, paint it with the UI Painter tool: The window being designed is a *canvas*, and the components of the interface (GUI widgets) are selected from a *palette* and 'painted' on the canvas. The following is a rather detailed description of the procedure and we recommend that you execute them as you read.

<figure><img src="image_108.png" /><figcaption>Figure 6.3. To paint a new window, click the *Canvas* button or use the *Tools* menu. Use the *Resources* button to find existing application model classes and other UI related classes.</figcaption></figure>

The first step is to create a new canvas by clicking the *Canvas* button (Figure 6.3) or using the *Canvas* command in the *Tools* menu. VisualWorks then opens three new windows: an unlabeled canvas, a *Palette* of widgets, and a *Canvas Tool* (Figure 6.4).
<figure><img src="image_109.png" /><figcaption>Figure 6.4. Palette with GUI widgets (left), Canvas Tool (top), and unlabeled canvas.</figcaption></figure>

### Installing the canvas on an application class

After creating an empty canvas, *install* it on an application model class by clicking *Install* in the Canvas Tool. (Like most other actions, this can be also be done from the <operate> menu of the Canvas itself.) VisualWorks will then lead you through a series of dialog windows to specify the name of the application class, the name of its category, the type of its interface, and the name of the class method that will hold the description. The first of these windows is in Figure 6.5.

<figure><img src="image_110.png" /><figcaption>Figure 6.5. The first window after clicking *Install*.</figcaption></figure>

Type the name of your application model on the first line as in Figure 6.6. If the class does not yet exist, the UI Painter will create it. Next, use the bottom line of this window to enter the name of the class method that will hold the window specification - the description of the user interface. The recommended
name for the specification method is `windowSpec` and this name is already displayed at the bottom of the window. Use this name unless your application requires several windows which must then be stored as separate specifications under different names. The advantage of using `windowSpec` is that it allows you to open and run your application simply by sending the message `open`, as in

`ApplicationSelector open`

<figure><img src="image_111.png" /><figcaption>Figure 6.6. Provide the name of the application model class and Selector of the specification method.</figcaption></figure>

After entering the selector of the window specification method, click **OK**. If the application model class does not yet exist, the UI Painter now opens another window to get more information (Figure 6.7). Much of this window is already filled-in. The name of the application model class is on the top line and the name of the category in which the class will be stored is on the second line. The suggested category is `UIApplications-New` but we will use the name `Tests` instead. If the category does not exist, the painter will create it for you.

<figure><img src="image_112.png" /></figure>
Figure 6.7. Specifying category, superclass, and type of user interface application model. We only had to click the *Application* button and change the name of the category.

The next step is to select the type of the window in the box labeled *Define As*. This determines the behavior of the window. In most cases, the desired type of interface is *Application* and we thus select the *Application* radio button. (We will explain what a *Dialog* is and how to create it later.)

Finally, we must choose the *superclass* of our application model. The window suggests *ApplicationModel* and this is usually the appropriate choice. In some cases, you may have previously created a useful application model for a related application and you may want to reuse it. If so, replace *ApplicationModel* with the name of the superclass. Note, however, that you must have *ApplicationModel* in the superclass chain or you won't be able to benefit from all features of VisualWorks GUI classes. In our case, we leave *ApplicationModel* as superclass name. After this, click *OK* and VisualWorks will create a definition of class *ApplicationSelector* with the specified superclass, and put it in the specified category. It will also create the class method *windowSpec* containing the description of the interface in its present state. You can find it on the class side of the browser and its present structure is as follows:

### windowSpec

```
"UIPainter new openOnClass: self andSelector: #windowSpec"
```

```html
<resource: #canvas>
^#(#FullSpec
#window:
#(#WindowSpec
#label: 'Unlabeled Canvas'
#bounds: #(#Rectangle 300 200 500 400 ) )
#component:
#(#SpecCollection
#collection: #() ) )
```

As you can see, the method begins with `<resource: #canvas>` which makes it special and the compiler treats it differently than regular methods. The method contains a description of the window with its label and, size and position, and when you add new widgets and re-install the window, the spec method will be updated to capture the new layout. Remember that when you change the canvas (for example by adding new widgets, changing the label, or changing the background color) you must re-install the canvas. Otherwise your changes will only be painted on the screen but not captured in the library.

The class is now compiled and the UI specification saved and you can run the application, either by executing

### ApplicationSelector open

in a Workspace or by clicking *Open* in the *Canvas Tool*. This will open an empty window looking just like the canvas that we have created.

### Defining canvas properties

After installing the raw canvas, we will now define its properties. Click *Properties* in the *Canvas Tool* and you will get the window in Figure 6.8. Since nothing but the canvas is selected, the *Properties Tool* is open on canvas properties and we will redefine its label to *Application Selector*. Type *Application Selector* on the *Label* line and click *Apply and Close*. The *Properties* window closes and the canvas displays with the new label. Note that if you now opened the application, the label would be unchanged because we have not re-installed the changed canvas. *Install* again, open the application, and check that the label of the window has changed.
<figure><img src="image_113.png" /><figcaption>Figure 6.8. Defining a new label for the window.</figcaption></figure>

We could define and install additional properties of the window such as its background color, but we will now proceed to the widgets. If you must interrupt your work at this point, close the interface and save the Smalltalk image. When you return, you can reopen the canvas editor either by

* clicking the *Resources* button (Figure 6.3) and locating you application model class in the Resource Finder window (Figure 6.9) or

* by opening the browser on your spec method `windowSpec` method and executing the Smalltalk statement in the comment at the top of the definition (see listing above).

<figure><img src="image_114.png" /><figcaption>Figure 6.9. You can access an application with the Resource Finder. *Edit* opens the canvas editor, *Start* opens the application on the selected specification, *Browse* opens a browser on the application model class.</figcaption></figure>
## Main lessons learned:

* To create a user interface and its application model

* Open a canvas with a Palette and a Canvas Tool from the launcher.

* Install the canvas on an application model class using the *Install* button. Complete the dialog windows, specifying the name of the method holding window specification, the name of the application model class and its category, and the type of the window (*Application*). The class will be automatically defined if it does not yet exist. To open the installed canvas, click *Open* in the Canvas Tool or send *open* to the application model class.

* Define window properties using *Properties* from the Canvas Tool and re-install.

* If you change the user interface, re-install the window. Failure to re-install a changed GUI is one of the most common causes of a strange looking or misbehaving interface.

* Changes to application model code do not require re-installation.

* Executing the comment at the beginning of the canvas specification method (typically `windowSpec`) opens the Canvas, Palette, and Canvas Tool on the interface.

## Exercises

1. Follow the procedure described in this section and create the canvas. Examine the `windowSpec` method.

2. Use the Properties Tool to change the background color of the window to light yellow. Re-install before opening and check the new `windowSpec`.

3. Most VisualWorks tools are implemented with the user interface painter. Test this by checking the `windowSpec` method of class `Browser` and opening it with `open`.

## 6.3 Painting widgets and defining their properties

After creating the canvas, we will now paint the widgets and define their properties. To paint a widget on the canvas, click it in the palette and drop it on the canvas, clicking the select button when the widget is positioned where you want it. Initially, you will not be able to identify palette buttons but when you click a palette button, its name is displayed at the bottom of the palette as in Figure 6.10. The Sticky Selection button allows you to make several copies of the selected component; click it on to start and click it off to disable the sticky mode.
<figure><img src="image_115.png" /><figcaption>Figure 6.10. UI Palette and its buttons.</figcaption></figure>

We will now paint the Action Buttons required in our interface. Click the Action Button button (!), move the mouse cursor over the canvas, and click. When an Action Button appears (Figure 6.11), click again to drop it in place. If you don't like the button's position or size, move it or reshape it by dragging its body or its *handles* - the small rectangles in the corners - while pressing the <select> mouse button.

<figure><img src="image_116.png" /><figcaption>Figure 6.11. Widget handles show that the widget is selected. You can now move it, reshape it, define its properties, or delete it (command *cut* in the <operate> menu).</figcaption></figure>

Position the first Action Button as in Figure 6.12 and proceed to define its properties.
<figure><img src="image_117.png" /><figcaption>Figure 6.12. Desired layout.</figcaption></figure>

To define widget properties, select the widget in the canvas and click *Properties* in the Canvas Tool. The Properties Tool window opens (Figure 6.13) and you can now define the button's *Label*, its *Action*, and other parameters.

The *label* is the text displayed inside the button - *color example* in this case - and *Action* is the name of the message that the button sends to its application model when you click it in the running application. You can use any legal identifier for the *Action* method, but the name will be easier to remember if it is similar to the label; we called it *color*. VisualWorks automatically adds the # sign in front of it, making it a *Symbol*, a special kind of string. We have now defined all the properties that we need. Click *Apply* at the bottom of the Properties Tool if you want to proceed and define the properties of another widget. Clicking *Apply & Close* applies the properties and closes the Properties Tool. The button in the canvas now shows the new label and you will probably have to reshape it because the button is too narrow. Note that you can choose a variety of other properties such as background and foreground colors on other pages of the Properties Tool.

<figure><img src="image_118.png" /><figcaption>Figure 6.13. Properties window on an Action Button.</figcaption></figure>
We leave it to you to create and position the remaining buttons and define their properties. One way to do this is to *copy* and *paste* from the canvas `<operate>` menu. With this method, the buttons will be copied with all their properties such as size, label, and action, and you will have to redefine them. Having so many buttons to paint, you might want to create all buttons in the left column first, select the whole column, *copy* it, and *paste* it to create the right column. To select a group of items, hold the `<select>` button down and move the mouse cursor to draw a rectangle around the widgets to be selected. When you release the button, the widgets' handles will be displayed and you can *copy* them.

Now that you have all the Action Buttons, you may want to change their widths, heights, or alignments using the alignment buttons in the Canvas Tool (Figure 6.14). The six buttons on the left are for alignment of a group of widgets along the top of the first selected widget, its center, bottom, and so on; the middle four buttons produce equal spacing between widgets, and the two buttons on the right are for equalizing widget width and height. Select the widget that you want to use as the template and then the remaining widgets by clicking the left mouse button while holding `<shift>` down. Then click the desired alignment button.

*Install* the canvas and click *Open*. The window opens with all the buttons, but the buttons will not do anything because we have not defined their action methods.

<figure><img src="image_119.png" /><figcaption>Figure 6.14. Canvas Tool buttons for automatic widget alignment.</figcaption></figure>

As the next step, we will add the *Text Editor* widget for displaying the help text. Click the corresponding button in the palette, position the widget on the canvas, shape it to the desired size, open the *Properties Tool* window, and specify *description* as the name of its *Aspect*. The *Aspect* of a *Text Editor* is the name of the method that supplies the displayed text, and the instance variable containing a value holder with the text. (More on value holders in a moment.)

After defining and applying the *Text View's Aspect*, open the *Details* property page, click both scroll bars off, and the *Read Only* property on (Figure 6.15). This will remove the scroll bars from the *Text Editor* (our text will be short and scrolling is unnecessary), and make the text read-only, preventing the user from changing the text. Click *Apply and Close*, and *Install* the canvas again.
<figure><img src="image_120.png" /><figcaption>Figure 6.15. *Details* page of Text Editor’s properties.</figcaption></figure>

The GUI is now completely installed and you can try to run it by clicking *Open* in the Canvas Tool. This time the application will *not* open and we will get the Exception window in Figure 6.16. It says that *binding #description* was not found. This means that when the *builder* object that builds the window from `windowSpec` tried to construct the window, it sent message description to get the text for the Text Editor - but we have not defined this method yet. Before we can open the interface, we must thus define all aspect methods. This topic is covered in the next section.

<figure><img src="image_121.png" /><figcaption>Figure 6.16. The window builder could not establish the bindings between a widget and its value holder.</figcaption></figure>
## Main lessons learned:

* To add widgets to an interface, import them from the palette or copy and paste widgets already on the canvas.

* When a widget is selected in a canvas, its handles are shown. Handles can be used to change the widget's shape. A selected widget can be moved around, edited, deleted, or copied.

* To align or resize a group of widgets, select the widgets and use alignment buttons in the Canvas Tool.

* To define widget properties, use the Properties Tool.

* Action Buttons have an *Action* property, most other widgets have an *Aspect* property.

* *Action* is the name of the method sent to the application model when the user clicks the button.

* *Aspect* is the name of a value holder holding a widget's value, and the name of its accessing method. The *Aspect* of a Text Editor is the message that returns the value holder with the text, and the name of the variable holding it.

* When choosing selectors for *Action* and *Aspect* methods, use names that match the label of the widget or its purpose.

* Before you can open an application, you must define *Aspect* variables and methods so that the user interface builder can establish and use the bindings between the widgets and their value holders.

## Exercises

1. Follow the steps listed in this section and create the widgets of Application Selector. When you are finished, read the `windowSpec` method and explain how it changed from Section 6.2.

2. Change the color of the text of the *Run* button to green and the color of the text of the *Help* button to red.

3. The box around example buttons and the label *Applications* in Figure 6.1 is a Group Box widget. Add the Group Box according to the desired layout. Change the color of its text label and frame to red, and the background to light green if possible. (Hint: Use on-line help if necessary.)

## 6.4 Defining *Action* and *Aspect* methods

To make our buttons functional and to make it possible to display the Text Editor view, we must now define their *Action* and *Aspect* methods.

The first step in creating *Action* and *Aspect* methods is easy because VisualWorks can define their skeletons (*stubs*) for you. To do this, select all widgets in the canvas for which you want to create stubs, and click *Define* in the *Canvas Tool*. This will open a window (Figure 6.17) listing the *Action* or *Aspect* names of all selected widgets. Click *OK*, VisualWorks creates the stubs, and closes the window. You can now open a browser on the application model and browse the automatically defined stub methods, or run the application and click the buttons because the messages that the buttons send now exist. Of course, clicking a button will not do anything because the messages that the buttons send don't have any meaningful body because we have not specified what they should do. To get the application to work, we must now redefine the bodies of all the *Action* and *Aspect* method stubs.
<figure><img src="image_122.png" /><figcaption>Figure 6.17. Automatic definition of stubs of widget methods. When the *Add Initialization* check box is on, VisualWorks includes lazy initialization in the definition of all selected *Aspect* methods.</figcaption></figure>

Although we could define all *Action* and *Aspect* methods in the System Browser, we will now use a smaller browser restricted to our application model class and its hierarchy. To open it, deselect all widgets in the canvas by clicking outside their perimeters, and click the *Browser* command in the Canvas Tool. This opens a *hierarchy browser* as in Figure 6.18. (When a widget is selected in the canvas, the browser opens only on methods relevant to this widget.)

Note that we now have an instance variable called *description Text*, the *Aspect* of the Text Editor; it was created by the *Define* action. For completeness, add instance variable *currentSelection* and recompile the class with *accept*.

<figure><img src="image_123.png" /><figcaption>Figure 6.18. Hierarchy browser of class *ApplicationSelector*.</figcaption></figure>

Our next task is to fill in ('flesh out') the bodies of the stub methods stored in instance protocols
*actions* and *aspects*. Protocol *actions* holds *Action* methods for Action Buttons, protocol *aspects* holds *Aspect* methods, in this case method description for the Text Editor. We will begin with the *button* method
*in the actions protocol*.
Click actions and button in the Browser to display the code in Figure 6.19 which shows that the body of the method does not do anything. Its only use is that if we run the application and click the button, the application will not crash because the message sent by the button *exists*.

<figure><img src="image_124.png" /><figcaption>Figure 6.19. Stub definition of button created by the *Define* command.</figcaption></figure>

What do we want the button method do? According to our design specification, the method should

* store a reference to the name of the example class ButtonExample in variable currentSelection,

* supply the description text, and

* tell the Text Editor view to display it.

To tell the Text Editor to display the text, we must ask variable description to change its value by sending it the value: message with the text as its argument. The desired definition is as follows:

**button**

"Make ButtonExample the current example and display its short description in the text view."

currentSelection := ButtonExample.

description value:

'Current selection: button.

This example illustrates the three types of buttons available in VisualWorks:

Action Button sends a message.

Check Box Button sets its value to true/false.

Radio Button turns itself on and other radio buttons in the same group off.'

After entering and accepting this definition, open the application and test that the *button* button now works. Note that we did not have to reinstall the canvas because we did not change the GUI - we only changed the code of the class.

We are leaving the remaining Action Button *Action* methods to you. You only need to know that the names of the example classes are ColorExample, ComboboxExample, CustomViewExample, HideExample, LineExample, List1Example, MoveExample, NotebookExample, and SizeExample. (Test the applications by sending them open to decide on the description text.) After entering and accepting these definitions, you can run the application and all example buttons will now work.

Before proceeding to the remaining methods, we will now make a small change to our canvas to show how easy it is to change your user interface – we will define the size of the window as *fixed* so that the user cannot change it. This will be useful because our Text Editor view cannot be scrolled and if the user made the window smaller, the text might not be readable. To make the size of the window fixed, click
*Layout* in the Canvas Tool and select *fixed size*. Don't forget to *Install* the new layout and test it! If you now open the application, you won't be able to change the size of the window.

### Main lessons learned:

* When you select widgets in the canvas and execute *Define*, Smalltalk creates stub definitions of their *Action* and *Aspect* methods of and defines their instance variables. The names are determined by the properties of the widgets.

* Stub definitions usually don't do anything but their existence makes it possible to open the application and click its widgets. It also saves you from having to remember the names of aspects and actions when you want to write their complete definitions.

* After creating the stubs, you usually have to edit them so that they perform their intended tasks.

* Changing the user interface requires only editing and re-installing it.

### Exercises

1. Implement the material covered in this section.

## 6.5 The remaining *Action* methods

In this section, we will define *Actions* for *Help*, *Run*, and *Quit*, the remaining Action Buttons.

### Help

The *Help* button opens a window with general help. We could create a special window for help using the UI Painter, but it is easier to use the built-in class *SimpleHelp* which opens a help window with an *OK* button at the bottom. To find how to use it, we can either read its definition in the browser, or we can look for references to *SimpleHelp* in the library and find how existing code uses it. Using the second approach, we find *SimpleHelp* in the browser, select command *class refers* in the `<operate>` menu of the class view, and examine several examples. We find that to use *SimpleHelp*, we must

1. send it the class message `helpString`: aString to create an instance with the help text aString

2. send `open` to open the window with this text<fnref n="1" />.

The whole definition of the *help* message which is sent by the *Help* button is thus as follows:

### help

“Open help window with general text on the whole application.”
(SimpleHelp helpString:
'Each of the buttons on the left provides access to an example application.
Clicking one of these buttons, displays information about the selection in the Text View.
If you then click Run, the application will open.') open

Enter and *accept* this definition and test that the *Help* button works. Note again that changing the definition of an *Action* method does not require re-installing the canvas – it's not a user interface change. Test the *Help* button now.

### Run

Clicking *Run* will open the currently selected application. Since all our example applications use `windowSpec`, they can be opened by `open`. We stored a reference to the name of the class of the selected application in instance variable `currentSelection` and the definition of run is thus as follows:

### run

<footnote n="1">¹ *SimpleHelp* is a subclass of *ApplicationModel* with its window specification in `windowSpec`.</footnote>
"Open the currently selected example application."
`currentSelection open`

This definition works fine if the user previously clicked an example button but if the user has not done so, the program will crash because `currentSelection` is `nil`, and `nil` does not understand message `open`. To deal with this possibility, run must check the value of `currentSelection` and send `open` only if it is not `nil`:

**run**

"If an example application is selected, open it."
`currentSelection isNil`
```
ifTrue: [Dialog warn: 'You must select an application first.']
ifFalse: [currentSelection open]
```

Test that everything works so far.

**Quit**

The *Quit* button should close the window and terminate the application and this can be done, for example, by sending message `closeRequest` to the application model. The definition of quit is thus

**quit**

"Close the window and terminate the application."
`self closeRequest`

**Main lessons learned:**

* To find how to use a class or a method, read its class or method comment or check existing uses.

* To run an application whose model is a subclass of `ApplicationModel` and whose interface is stored in class method `windowSpec`, send the class message `open`.

* To close an application and its window, send `closeRequest` to the application model.

**Exercises**

1. Implement and test the material covered in this section.

2. Implement *Help* using `Dialog warn: instead of SimpleHelp`.

## 6.6 Text Editor widget

The only unfinished part of our application is the Text Editor and we will now implement it starting from the stub definition of its *Aspect* method description *Text*. Its current form, automatically generated by *Define*, is as follows:

**description Text**

"This method was generated by `UIDefiner`. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an `initialize` method."

```
^description isNil
    ifTrue: [description := String new asValue]
    ifFalse: [description Text]
```

Before we explain this code and modify it for our needs, note that the comment says that if you redefine the method in the Browser and then use *Define* on this aspect, your definition will be replaced by this default version. So if you change the definition, don't use the *Define* button on it again or you will lose your work. Now back to the definition.

The code first checks whether the value of *description* is `nil`. Why? The reason is that when the application first opens, *description* is `nil` and when the builder sends *description* to obtain the text as it is
building the window, the process would fail because the builder could not build the text view from nil. The method thus assigns

### description := String new asValue

which returns an empty String, packaged as a `ValueHolder` object (to be explained shortly). The window extracts the empty string from the `ValueHolder` and displays it - no text in the description view. This technique of not initializing a variable until initialization is really needed is called lazy initialization. It is useful especially if initialization is time consuming, if it is not required immediately, and if the value may not be required during each execution of the application.
Everything now works and you can check that when you execute

### ApplicationSelector open

everything works as desired. The only blemish is that when the application opens, the Text View does not display anything - and we would like it to display the message 'Please select an example application.'. To correct this problem, we must store this string in description *before* the window opens and this can be done by defining instance method `initialize` which is automatically executed as a part of the application opening process. (We will explain how this happens in a moment.) Since the value of description must be a `ValueHolder`, the definition of `initialize` in class `ApplicationSelector` will be as follows:

### initialize

> "Assign initial text to Text Editor via its associated Aspect value holder."

> `description := 'Please select an example application.' asValue`

where message `asValue` converts the string into a value holder holding the string.

The program now works just as desired but the body of the description method that was automatically created by *Define* is now partially redundant: Variable description is now guaranteed to have a value when it is first requested by the builder (message `initialize` is sent before the builder starts creating the window), lazy initialization is no longer required, and the `ifTrue`: part of

### description

```
^description isNil
    ifTrue: [String new asValue]
    ifFalse: [description]
```

will thus never be executed. All this method will ever do is return description Text. Although the method still works, it is nicer to delete the unnecessary part:

### description

```
^description
```

Before closing this section, we must mention one additional detail about Text View widgets. As we have seen, a Text View has an *Aspect* variable to hold the value holder with its text and this variable is declared in the application model class. However, each Text View distinguishes *two* text objects. One is the text displayed in the widget, the other is the text last accepted with the *accept* command or initially assigned to the widget. Text View holds the currently displayed text in a variable associated with the widget itself, and the accepted in the *Aspect* variable in the application model (Figure 6.20). This makes it possible to restore a Text View to its original contents with *cancel* when the user changes but does not *accept* its contents. As programmers of the application, Our interest is usually restricted to the aspect variable in the application model and we can ignore the instance variable of the widget.

Text displayed in window

> Some text displayed on the screen - we have just changed it but we have not clicked *accept* yet.

Last *accepted* text, possibly different from text now displayed

> This was the text on the screen when we last clicked *accept* in the widget and before we made the changes on the left..
<figure><img src="image_125.png" /><figcaption>Figure 6.20. The text displayed in a Text Editor is stored in the widget's variable, the accepted text is stored in the *Aspect* variable in the application model.</figcaption></figure>

### Main lessons learned:

* Lazy initialization means leaving the initialization of a variable until the variable is needed.

* The stub created for *Aspect* methods by the *Define* command implements lazy initialization.

* To display a string in a Text Editor when the window first opens, initialize its *Aspect* variable to the desired string converted to a *ValueHolder* using message `asValue`. Perform this initialization in application model instance method `initialize`.

* The *Aspect* variable of a Text Editor must be a *ValueHolder* on a String. It holds the accepted text.

* The Text Editor widget holds the currently displayed value in its own instance variable. The accepted value is held in the application model.

### Exercises

1. Implement the material covered in this section.

2. We used *Define* to create the definition of *description* and then edited it to remove lazy initialization. If you don't intend to use lazy initialization, click off the check box *Add initialization* in the *Define* window and leave the body of the method empty. Test this feature.

3. Find how message `asValue` works.

## 6.7 Value holders, models, and dependents

GUI widgets fall into several categories:

* Passive widgets that organize the window but don't respond to user input or changing values of domain objects. Labels and grouping boxes belong into this category.

* Active widgets that respond to user input or changes of domain objects. This category can be further subdivided in widgets that

* invoke actions – such as action buttons

* gather input – such as text editors

* display information – such as lists.

Widgets that display or gather information need an object to hold the displayed information and this object is generally some kind of a value holder. We have already mentioned that a *ValueHolder* is a capsule containing a value (any object) and providing several accessing messages and a built-in mechanism for communication with 'dependents'. We will now explain the value-related messages and the concept of dependency.

### *ValueHolder* message interface

To put an object in a *ValueHolder*, send it the conversion message `asValue` such as
### 'A piece of text' asValue

which creates a `ValueHolder` containing the string 'A piece of text'. As another example,

`x := 3.14 asValue`

creates a `ValueHolder` containing the `Float` object 3.14.

Creating value holders with `asValue` is most common but `ValueHolder` also implements several specialized creation messages including `newBoolean`, `newFraction`, `newString` which create value holders on `True`, `0.0`, and an empty string. You can also use the class message with: `anObject` which creates a `ValueHolder` on `anObject` as in

`ValueHolder with: String new`

The accessing protocol of `ValueHolder` includes `value`, ` value: ` and `value:.` Message value returns the object in the value holder. As an example, sending value to the variable used above, as in

`x value`

returns 3.14. As another example, to obtain the value of variable description in our Text Editor, execute

description value

To *change* the value of a *holder* and to notify its *dependents* (explained below), send `value: ` as in

description value: 'New help text'

Remember that if you want to preserve the magic of widget value holders, you must not change description value by

description := 'new help text'

because this would change the nature of description (Figure 6.21) from a `ValueHolder` holding a `String` to a `String`. This would destroy the dependency between the value and its widget, and the part of the GUI that depends on description being a `ValueHolder` would now stop working. Unfortunately, assigning a value to a variable that holds a `ValueHolder` instead of using `value:` is a very common mistake!

<figure><img src="image_126.png" /><figcaption>Figure 6.21. Proper and improper ways of changing the value of a `ValueHolder`. Center: original state. Left (correct): result of description value: 'New help text', right (incorrect): result of description := 'New help text'.</figcaption></figure>

Value holders are most commonly used as *models* of widgets, as objects that hold the value of a widget and enforce *dependency* of the widget on any changes of this value caused by the application (Figure 6.22). Note, however, that the use of the principle of a model-dependent object is not restricted to widgets.

<figure><img src="image_127.png" /></figure>
<figure><img src="image_128.png" /><figcaption>Figure 6.22. The two sides of the model ↔ dependent relationship in GUI widgets.</figcaption></figure>

The dependency relationship between a value holder and a widget is established by **UIBuilder** when it constructs the user interface. VisualWorks refers to this link as a *binding* and we will now explain in more detail how the mechanism works. We will use the example of the Text Editor in our Application Selector.

When the builder builds the user interface from the `windowSpec` method, it associates a binding between the aspect variable *description* and a *ValueHolder* assigned to the Text Editor widget as its model. Once the binding is established and the window opens, it is used as follows: When the applications sends *value*: to the *ValueHolder* (Figure 6.23) as in

description value: 'New help text'

the *ValueHolder* changes its value and notifies its single dependent, the Text Editor, that it has changed. It does so by sending it the *update: #value* message. The definition of *update*: in the Text Editor widget (class `ComposedTextView`) responds by sending value back to its model, the *ValueHolder*. When it gets the result – the new text – it redisplays itself.

<figure><img src="image_129.png" /><figcaption>Figure 6.23. The chain of events resulting from sending value: 'New help text' to description. Full lines represent message sends, interrupted lines indicate returned objects.</figcaption></figure>

To keep track of its value and its dependents, *ValueHolder* has two instance variables called *value* (holds stored value) and *dependents* (holds pointers to all dependents). The following definitions show exactly how *ValueHolder* works:

**value**

`^value`

**value: newValue**

“Set the currently stored value, and *notify dependents*. Declared in superclass *ValueModel*.”
self gall: newValue.
self changed: #value "This is where the notification occurs."

where

** gall: aValue**

“Just change the value *without notifying dependents* of a change.”
value := aValue

changes the value but does not notify dependence. *Dependency* is defined by *message changed*: which triggers the broadcast of *update*: to the dependents. *Method changed*: is declared in class *Object* essentially as follows:
**changed: anAspectSymbol**

"The receiver changed. The change is denoted by anAspectSymbol. Inform all dependents."

self myDependents update: anAspectSymbol

We have not shown the additional detail involving the changed: message in Figure 6.23.

The ValueHolder thus triggers change notification via the update: message but for this mechanism to work, each dependent must understand the update: message; the way in which it defines update: then determines how it responds. We have seen that the definition of update: for the Text Editor widget, for example, asks the model for the new value of the string and redisplays itself with the new string. To take care of cases in which a dependent does not care about the update: message, the basic definition in class Object does not do anything. Every object thus understands update:.

We can now trace the full meaning of the definition of the button method from the previous section:

**button**

currentSelection := ButtonExample.

description value: 'the text for the help comes here'

After assigning a new value to currentSelection, button sends value: its ValueHolder, which then notifies its dependent (the Text View) via changed and update. The Text Editor view asks its value holder description for its value, gets the new text, and displays it.

## Creating widget - value holder bindings

We have already mentioned that the bindings between widgets and their value holders are established during the opening of the application. The process is as follows (Figure 6.24): When you send open to your application model, it creates a new instance of the application model and a user interface builder, an instance of UIBuilder. The builder object then builds the window in your computer's memory from windowSpec, creating bindings between widgets and their value holders. This is achieved by sending Aspect messages to the application model. In our example, UIBuilder sends description to ApplicationSelector which returns a ValueHolder with the initialized string. The UIBuilder then associates this value holder object with the Text Editor and makes the widget a dependent of the aspect variable; the value holder becomes the model of the widget.
<figure><img src="image_130.png" /><figcaption>Figure 6.24. Essence of the application opening process.</figcaption></figure>

## Main lessons learned:

* Value-dependent widgets hold their value in a *ValueHolder*. This value holder is accessible via the widget's *Aspect* variable and method specified as the widget's property.

*Widgets and their value holders are bound by the model ↔ dependent relationship. The value holder is the model, the widget is the dependent.

* When the application changes the value of a value holder via the *value*: message, the value holder notifies all its dependents by sending them the *update: #value* message. The reaction of each dependent depends on its definition of *update*: The definition is different for each widget.

* When the dependent is a widget with an *Aspect*, its reaction to *update: #value* is to send its *Aspect* message to its model, obtaining its new value, and redisplaying itself accordingly.

* To obtain the proper reaction of a widget to a change of its *Aspect* value, always change the value of the *Aspect* value holder by the *value*: message.

* Using assignment instead of the *value*: mechanism is the most common reason why widgets don't respond to value changes.

* Constructing the user interface from the window specification method is the responsibility of a *UIBuilder*. An application model creates its instance when it opens, and keeps it during the application's lifetime.

## Exercises

1. Implement the material covered in this section.

2. Trace how the Text Editor in our application responds to clicking an application button and summarize your findings in a diagram. (Hint: Add *self halt* before the *value*: message in the button method.)

3. Class *ValueHolder* is rather low in the class hierarchy. Examine its superclasses and explain how *ValueHolder* obtains its behavior and what new features it adds.

4. Enact the following scenarios using a simple application such as *SimpleHelp* or *ApplicationSelector* as the application model.

a. Painting of the user interface and its installation. Creates application model with its *Aspect* and *Action* methods and variables, stores window specification. Actors are the developer of the user interface and an instance of *UIPainter*, the object that animates the user interface painting tools.

b. Opening the application. Actors are the user who sends the opening message, the application model class and its instance, a *UIBuilder*, and instances of widgets and their value holders.

c. Interaction with an open application. Actors are the user, the application model, the widgets, and their value holders.

5. A model may have several dependents. As an example, an application displaying mathematical functions might display the values in graphical and textual form (using a Table widget, for example). Both displays would be dependents of a value holder with a list of function values. Enact the basic operation of the dependency mechanism along the lines of part c of the previous exercise.
6. The model-dependent relationship has many applications beyond user interfaces. As an example, consider a collection of physical particles that works as follows: When a particle changes its energy by some amount $\Delta$ greater than $\Delta_{min}$, all its neighbors change their energy by $\Delta/2$, all their neighbors change their energy by $\Delta/4$, and so on. This reaction continues until it dies down when the transmitted energy falls below the lower limit. Describe this problem in terms of models and dependencies, and enact it.

7. We used the term *model* in three contexts: application model, domain model, and model in the model-dependent sense. Define the three meanings carefully to clarify their distinct meanings.

## 6.8 Opening of an application - hook methods

In this section, we will give a more detailed description of the events that take place when an application model class receives the *open* message (Figure 6.25). Understanding this sequence is essential for initialization and for other operations related to the user interface.

<figure><img src="image_131.png" /><figcaption>Figure 6.25. The main messages executed in response to ApplicationSelector open. Boldface messages are hooks that can be redefined in your application model.</figcaption></figure>

To trace the sequence and to follow our description ‘live’, execute

self halt.
ApplicationSelector open

and note the following events:

1. Method open sends **new** which creates an instance of the application model class ApplicationSelector.

2. The application model ApplicationSelector sends itself the **initialize** message. If you defined this message in your application model, this definition is executed. If you did not, the inherited definition of **initialize** is executed. The default definition does not do anything and its only purpose is to intercept the
initialize message if it is not fielded by a subclass. This is an example of a *hook method* - a method that provides an opportunity for the developer to execute an operation at a critical place in the process.

3. ApplicationSelector now asks class UIBuilder to create a UIBuilder object. This object will eventually obtain the information about your interface from windowSpecs and 'build' it. First, however, the application model sends **preBuildWith: aBuilder** to itself; where aBuilder is the new builder object. If you defined preBuildWith: in your application model class, this method will now be executed, otherwise the 'do-nothing' default definition of preBuildWith: inherited from ApplicationModel will be executed. The method is another hook.

4. After executing preBuildWith: the builder builds the user interface in memory using windowSpec: It gathers information about the window's size and label and the widgets, and constructs their bindings and a Policy object that will help build the window. The 'policy' object determines which style will be used to draw the window, allowing a choice between the Microsoft Windows look, the Macintosh look, and the Motif look. After this, the application model sends postBuildWith: aBuilder - another hook message. Again, the repdefined version does not do anything.

5. The application model now draws the window on the screen, but before it passes control to the user, it sends **postOpenWith: aBuilder**. This is the last hook (its inherited behavior is to do nothing) and after it executes, the application opens for user input via widgets.

In your application, you can use any of the application opening hooks, all of them, or none of them. In some cases, the nature of what you want to do determines the exact hook that you must use, in other cases, the same effect can be achieved by using any one of several hooks. As an example, if you want to do something that depends on the existence of widgets, you must allow the builder to build the widgets first, which means that you cannot do this in the initialize or preBuildWith: methods.

In our application, we only needed a hook to assign a value holder with the initial text to the description variable. Although this can be done with any hook method, it is natural to do it during initialization in method initialize as we did:

**initialize**

"Create a value holder with the text in the initial Text Editor display."

description := 'Please select an example application.' asValue

**Pseudo-variable super**

Although our definition of initialize works fine, it does not follow the recommended style for hooks. The point is that our application model class might be at a low point in the application model chain (such as class E in Figure 6.26) and some of its superclasses might contain their own definitions of initialize. Since our new class should normally execute this inherited behavior and augment it with its own behavior, we should define initialize to execute the inherited behavior first and the specialized behavior next as in

**initialize**

self initialize. "Execute inherited behavior."

description := 'Please select an example application.' asValue

Unfortunately, this form would create an infinite loop, because it makes self send initialize to itself over and over, until we stop the loop with <Ctrl> <C>. Obviously, our goal was not to re-execute this definition of initialize but rather the definition higher up in the hierarchy tree. To locate this class, Smalltalk provides a special identifier called super and the correct way to define initialize using super is as follows:

**initialize**

super initialize. "Execute inherited behavior."

description := 'Please select an example application.' asValue

The concept of super is very important and we will use Figure 6.26 to explain its exact meaning.

<figure><img src="image_132.png" /></figure>
<figure><img src="image_133.png" /><figcaption>Figure 6.26. Example hierarchy illustrating the meaning of super.</figcaption></figure>

Assume that class D contains method exampleOfSuper defined as follows:

**exampleOfSuper**

"some code here"
super exampleOfSuper.
"some more code"

When you send exampleOfSuper to an instance of class E, it will pass execution to the definition of exampleOfSuper in class D. In this definition, super will refer to the nearest superclass of D which contains its own definition of exampleOfSuper, in this case class B. A very common misconception is that super refers to the superclass of the receiver, in this case D.

Note the similarities and differences between self and super. In two ways, super is similar to self:
Both are *like* a variable in that their referent may vary from one context to another, but they are *not really*
variables because we cannot assign value to them. Because of this partial but incomplete similarity to
variables, self and super are both referred to as *pseudo-variables* or *special variables*.

In another way, super and self are different: Pseudo-variable self represents an object - the receiver of the message. You can thus meaningfully write

**^self**

The purpose of super, on the other hand, is to specify a class containing the definition of a
message. Without specifying this message, super does not make any sense and if you try to use super by
itself, as in

**^super**

Smalltalk will refuse to compile the code (Figure 6.27).
<figure><img src="image_134.png" /><figcaption>Figure 6.27. Pseudo - variable *super* must be followed by a message.</figcaption></figure>

## Main lessons learned:

* A hook is a method automatically executed during a process such as the opening or closing of a window. Its inherited definition usually does not do anything but since the developer of a subclass can redefine it, a hook makes it possible to insert code at strategic places.

* The opening sequence of *ApplicationModel* includes several 'do-nothing' hook messages.

* The proper way to redefine a hook message is to execute first its inherited version with *super*, and then execute the specialized behavior.

* *self* and *super* are pseudo-variables - the object that they refer to depends on the context but it cannot be changed by the programmer.

* Unlike *self*, *super* cannot stand on its own. It must always be used as the receiver of a message.

## Exercises

1. Implement the material covered in this section.

2. Trace and record the complete sequence of message sends following the execution of *open*.

## 6.9 MVC – the Model-View-Controller triad

After opening the subject of widgets, it is time to explain the essence of GUI components in VisualWorks Smalltalk. The principle of user interface components in Smalltalk is the *model-view-controller (MVC) paradigm*. According to this principle, every UI component that represents a value of a domain object uses this value as its *model*. As an example, a text editor's model is the displayed text, a slider's model is a floating-point number, and the model of an on/off check box model is a *Boolean*. The model holds the data but knows nothing about its display and user interaction, leaving these responsibilities to the view-controller pair.

The graphical representation of the model is the responsibility of a *view* object. As an example, a text may be displayed by the view of a text editor, a floating point number may be displayed by the view of a slider, and an image may be displayed by a custom view. The view object knows how to display itself from data supplied by its model but does not hold the original of the data and is incapable of user interaction.

Finally, the object that manages user activity within the boundaries of a view is the view's *controller*. A controller is notified when an input event such as a mouse click occurs, and defines methods that process these events. As an example, when a user clicks the `<select>` button to select text inside a text editor, the editor's controller is notified and converts these events into a highlighted text selection in cooperation with its model and view. A controller knows nothing about the data and its display but it is in full control of the user interface.

Each of the three components of the MVC triad is thus in charge of one aspect of UI operation and the three cooperate to accomplish all the tasks that we expect of the user interface - display, damage repair (such as when a window is obscured by another window or collapsed and expanded), automatic response to domain changes, and response to user actions. Besides the conceptual elegance of this arrangement, this separation of responsibility enhances flexibility and reusability because any of the three components can be