• Aucun résultat trouvé

An ExM1ple: Testing for Primes

Dans le document til Smalltalk (Page 53-56)

Sma/ltalk Fundamentals

2.4 CONTROL STRUCTURES WITH MESSAGE-PASSING

2.4.4 An ExM1ple: Testing for Primes

To illustrate the equivalent of Pascal's nested control structures in Smalltalk and to discuss a larger example, we will consider the development of a Smalltalk fragment to test whether or not a given integer is prime. For our purposes, a number is defined as primeifit is positive and evenly divisible by itself and 1.The algorithm used initially rejects all even numbers greater than 2. For odd numbers greater than 3, the integer is divided by a series of odd trial divisors, until either the number divides evenly into one of the trial divisors in which case it is not prime, or alternatively until the divisor becomes larger than the square root of the number, in which case the number is prime. Pascal and Smalltalk versions of code to solve this problem are shown below.

Chapter 2 Smalltalk Fundamentals

FUNCTION isPrime (candidate: integer): boolean;

VAH divisor: integer; prime: boolean;

BEGIN

prime:=true;

IF candidate<=0 THEN prime:=false ELSE IF candidate> 3 THEN

IF candidate MOD 2=0 THEN prime :=false

ELSE BEGIN

divisor:=3;

WHILE (divisor*divisor)<=candidate) AND prime DO IF candidate MOD divisor=0 THEN

prime:=false ELSE

divisor:=divisor +2 END;

isPrime:=prime END;

Sma/hale isPrime

Icandidate divisorI candidatef-self.

candidate<=0 ifTrue: [ifalseJ.

(candidate>=1& (candidate<=3)) ifTrue: [itrue].

(candidate \\2)

=

0 ifTrue: [ifalseJ.

divisorf-3.

[divisor • divisor<=candidateJ whileTrue: [ (candidate \\divisor)=0

ifTrue: [ifalseJ

ifFelse: [divisorf-divisor+211.

itrue

Several explanatory comments are required to understand the Smalltalk code. But first note that the Smalltalk code is more concise than the Pascal code - primarily because of Pascal's inability to terminate evaluation of a function before the end. In Smalltalk, an expression preceded by an up arrow (i) is termed a return expression. A return expression indicates that the result of evaluating the expression following the up arrow is the result tobereturned and evaluation of the code is to terminate.

Two unfamiliar binary selectors are introduced: &and \\ Selector& denotes the and operation - its result is true ifboththe receiver and argument are true. Selector \\ defined on integers returns the integer remainder when the receiver is divided by the argument.

As in Pascal, variables must be declared before they can be used. But as explained earlier, variables are untyped - hence no type declaration is necessary. The form

Icandidate divisorI

declares candidate and divisor to be temporary variables. These variables exist only

while the code fragment is being evaluated. All temporary variables are initially bound to the special object nil.

In Smalltalk, the receiver of the isPrime message is called self. Explicitly assigning self to a local variable, as we did via assignment candidate ~self, is actually superfluous because self can be referenced anywhere in the method. However, it serves to make the Pascal and Smalltalk versions easier to compare.

2.4.5 User-Defined Control Structures

No analog of the Pascal repeat ••• until or case statements is provided in the Smalltalk system. However, since control structures are implemented by sending messages to objects, it is possible for the programmer to add new control structures to the system. We will show examples of how this may be done in later chapters. To whet your appetite, we will introduce a few examples of advanced control structures that may be created in Smalltalk.

However, we will not yet discuss the details of their implementation.

Very often we want to apply a function to each element of a data structure such as an array, a list, or a tree. For example, itis traditional to sum the elements of an array by extracting successive elements and adding them to a running sum. Alternatively, we might want to print out the values stored in a binary tree by traversing the nodes of the tree in some specified order such as post-order.

Each of thesetasksrequire us to successively generate elements from a data type and apply a function to each generated element. Such control forms are often called generators.

Lisp programmers will recognize them as mapping functions. The do: aBlock message, when sent to an array receiver, successively supplies the objects in the array as the argument to the single argument block provided after keyword do:. For example, the code

sum~O.

table do: [:element I sum~sum+ element]

sums the elements in array table. As each object from the array is generated, it is bound to the block argument element and the message expression sum ~ sum + element is evaluated.

Many other useful variations of this form are possible. We will give just one further example. Rather than simply applying a function to each object of an array, we often want to select only those objects that satisfy some constraint Perhaps we want to collect into a new array only the nonzero elements of an existing array. This requires us to generate each element from the original array, test whether the element is zero or not, and, if it is nonzero, add it to the new array. The expression

#(030420 01 ••Iect: [:element I element -'"0)

would perform this task and return the array #(3 4 2) as the result; Le., it collects the nonzero elements into an object of the same class as the receiver. A final example is

#(1234SI collect: [:element I element.quared]

which returns #(1 4 9 16 25).

Chapter 2 Smalltalk Fundamentals 39

2.5 CLASSES

The class is the fundamental abstraction mechanism in Smalltalk. It groups together objects with similar characteristics. Classes allow the programmer to abstract out the common attributes and behaviors of a set of objects. A class describes the common protocol followed by each object in the set; individual objects following that description are termed instances.

One class description serves to describe all instances of that class, and every object in the Smalltalk system is an instance of some class.

Class Instance

A description of a set of objects with similar characteristics and attributes.

An individual object described by a particular class.

In previous sections, we have been exposed to some of the basic Smalltalk system classes: integers, characters, strings, booleans, blocks, arrays, and so on. We have seen examples of instances of each of these classes: 3 is an instance of class Integer, 'hello' is an instance of class String, [xf - 4 factorial] is an instance of class Block. We have also examined some of the protocol that instances of these classes follow. For example, the class Integer supports the following protocol: factorial, +, .,*,I,to:do:, to:by:do:, gcd:, and so on. The class Array supports the protocol at: and at:put:. In later chapters, we will examine the complete protocol supported by each of these classes.

Up to this point, we have seen how messages can be sent to instances of predefined classes. The Smalltalk environment provides an enormously rich set of such classes, but the essence of programming in Smalltalk is identifying, creating, and manipulating new classes of objects. To illustrate the description of classes and the creation of instances, we will define a new class Complex to perform calculations in complex arithmetic. Note: Class names in Smalltalk must begin with an uppercase letter.

Dans le document til Smalltalk (Page 53-56)