Michael C. Storrie-Lombardi, M.D.
Summer 1989 – Page 90
Smalltalk, the original object oriented programming (OOP) environment, has finally arrived as a full-blown Macintosh implementation thanks to Digitalk, Inc., at the extraordinarily reasonable price of $199. Early signs point toward Smalltalk/V Mac introducing OOP and Macintosh personal programming to a large group of people currently unable to find a programming environment that combines power with a minimal learning curve.
Getting Excited About Smalltalk/V
While most of the personal computer world has considered Smalltalk an intriguing exploratory tool of the artificial intelligence community, the Smalltalk/V Mac implementation by Digitalk may turn into the lingua franca of two large groups of Macintosh users: busy professionals with quite specific application needs but limited snatches of programming time, and all of us who would love to have something lead us rationally through Inside Macintosh.
What You Get
Smalltalk/V Mac comes as two 800K disks containing almost two megabytes of compressed code. With it comes an excellent softback book that does triple duty. It introduces the basic concepts behind the Smalltalk language, describes the Smalltalk/V implementation, provides extensive step-by-step tutorials, outlines a case study in implementing a database in Smalltalk/V, and provides the cross-reference material that integrates the Smalltalk/V language and the Macintosh operating system. This last item may pay for the program all by itself. It provides an excellent way to dig into the five volumes of Inside Macintosh.
This manual will probably win the hearts and minds of most people because of the superb tutorials and examples provided. Written by Jim Salmons and Timlynn Babitsky of JFS Consulting, the first portion of the manual walks you through some 110K of tutorials that provide a first class introduction to Smalltalk. Almost all of the examples discussed in the text appear in the Smalltalk/V environment, so you can motor right along without having to stop and type in interesting pieces of code.
The text is divided into four main sections. Part one provides an overview of OOP and a brief comparison of Smalltalk/V to standard code such as Pascal. The next section provides 150 pages of tutorials introducing you both to Smalltalk/V and the techniques of OOP. You cover objects, methods, control structures, classes, inheritance, streams, collections, graphics, windows and debugging. The tutorials culminate by taking you through a complete application development cycle. Part three gives you 100 pages of reference material to the syntax, semantics, windows, and menus of Smalltalk/V. The remainder of the book Digitalk has devoted to an “Encyclopedia of Classes,” to provide structured descriptions of classes and methods, as well as Mac Toolbox information, user-defined Smalltalk/V primitives, and a discussion of extensions of Smalltalk/V in other languages such as C and Pascal.
Digitalk has designed Smalltalk/V for you to use on any Macintosh with at least 1 megabyte but preferably 2.5 megabytes of RAM, a hard disk, one diskette drive, and System 4.2 and Finder 5.0 or later. Optional items recommended include: MultiFinder, additional RAM, 68881 or 68882 floating point math co-processor, and a color monitor. The program will run on 68000, 68020, or 68030 CPUs. The floating point algorithms utilizes SANE so it will handle either the 68881 or 68882 math co-processor.
Systems Used for Evaluation
We ran Smalltalk/V on a Mac II with 8 megabytes of RAM, 80 megabyte hard disk, and 68881 math co-processor, as well as a Mac SE/30 with 4 megabytes of RAM, 80 megabyte hard disk and 68882 math co-processor. Both machines ran under Finder 6.1, System 6.0.3, and MultiFinder.
Introduction: The Power of Smalltalk/V
Digitalk spells out early in the manual the idea of a powerful language as one in which you get a lot of computer activity out of a few lines of programming code. In like fashion, they seem to consider a program development environment powerful if it provides utilities that allow an application designer to reuse as many lines of pre-written code as possible. Digitalk’s implementation of Smalltalk certainly seems to meet both criteria. In addition, Smalltalk/V protects itself so well and provides such excellent inline debugging facilities that it encourages a delightfully relaxed explore-design-prototype-refine application development cycle. In two weeks of daily usage I could not crash the system. Since an error looks to Smalltalk/V like just another object, you always get at least an “I don’t understand” message and bounce into the debugger.
Since Smalltalk/V comes as a truly pure object oriented programming language and since Digitalk has written it in Smalltalk/V (except for a small machine language kernel), essentially all of the Smalltalk/V source code is available to you. In addition you have full Mac Toolbox access, but most exciting, Digitalk made the development cycle self-documenting. The Smalltalk/V methods accessing the ROM Toolbox reference specific Inside Macintosh pages. This means that you can do with Smalltalk/V what has long frustrated most of us: memorize those five volumes in small chunks, only as you need them, and in the relaxed “incidental learning” style advocated by Piaget. (See Figure 1.)
Together, the guideposts to Inside Macintosh plus the source code solve another dilemma most of us have faced in picking an application development language: Do you pick a very high level language that hides most of the inner workings of your computer from you, but lets you get a lot done in a hurry; or do you pick a language that hides very little and consumes a great deal of development time, but lets you get down to the most fundamental elements of Mac’s control structure? With Smalltalk/V you can do both. As you will see below, the debugging tools provided let you change any of the high level code that implements the environment, hand craft the bitmap of a particular object, or add assembly language or C code for specific speed sensitive procedures. Smalltalk/V will basically hide or show you as much of its inner workings as you wish.
The World According to Objects
For us to talk about Smalltalk/V we need to speak in Smalltalk. In case you have not waded into the world of OOP yet, let’s take a few minutes to learn the basic vocabulary and syntax of the Smalltalk language. With such terms as classes, objects, inheritance, methods, private memories, and messages Smalltalk sounds much more like a dialect of human language than a programming environment. In fact, think of Smalltalk for a moment not as a programming language, but as a private universe. In this universe every manifestation of mass or energy we call an instance of a particular class.
What does all this mean? In our own universe we experience our world as a collection of disparate but discrete objects reacting to each other in a common environment (muons, photons, electrons, Disneyland). Smalltalk clusters everything in its environment into “objects.” We form our society by clustering into occupations based on our skills: physics, medicine, law, etc. Smalltalk nomenclature calls abstract concepts like physics, medicine, and law “classes.” Each of us as individual physicist, physician, and lawyer Smalltalk would call an instance of the more abstract concept. To join one of the classes we must memorize the facts and learn the particular skills or methods of that profession. (See Figure 2.)
If we had a complex social problem such as radioactivity escaping from a nuclear waste site, we would need the combined skills of physicist, physician, and lawyer. If we designed Smalltalk objects to handle the problem we would create a specific instance of the classes physics, medicine, and law. Let’s call these instances Physicist, Physician, and Lawyer. We would then give each instance two items: data (private memories) and methods (skills). Smalltalk/V calls the data structure of its objects instance variables. For our Physicist, Physician, and Lawyer to work together effectively they will request certain actions from one another. In Smalltalk they do this by sending messages. For example, the Lawyer may want to know if the radiation in Swamp Creek might have caused his client’s bone cancer. He sends a note to the Physician object asking for a medical opinion. The Physician sends a note to the Physicist asking him to estimate the amount of ionizing radiation that might have penetrated a human being in the area of the creek. To perform his calculations the Physicist needs to know what kind of waste spilled and the exact distance from the client’s home to the creek. To get that information he sends a message to the Lawyer. This message passing keeps up with every object relying on all the others to contribute private skills and memories to the problem solving task.
At no time does any object try to invade another object’s private data or tell another object which skills to use in performing their task of the moment. Smalltalk carefully protects the integrity of the data and methods of each object. Such protection allows for particularly modular program design. The modularity has three powerful effects: it eases program maintenance, encourages program revision, and allows busy professionals to program a few minutes at a time. If you need a convincing argument for the power of this approach, stop reading for a moment and imagine how easily you could modify the above Physicist, Physician, and Lawyer objects by letting them inherit methods and data from a superclass called Human Being that runs parallel to the Occupation superclass. This convergence of lines of inheritance provides Smalltalk with strengths similar to the advantages we see in genetic inheritance from diverse genetic trees.
The Smalltalk/V Macintosh Programming Environment
Those of you familiar with Smalltalk 80 will be pleasantly surprised during your first few moments with Smalltalk/V. Smalltalk 80 presented Macintosh users with the classical Smalltalk windowing and menu environment, but cut you off completely from the rest of your Macintosh world. Smalltalk/V implements the full Macintosh environment. In short, everything works the way you expect. You cut and paste to your word processor, pass data back and forth to your database or spreadsheet, bounce around in MultiFinder, and run off code to the LaserWriter.
Smalltalk/V provides numerous special windows and uses multiple pane windows extensively. The environment provides convenient, selectable, scrolling lists of objects, classes, methods, debugging information, and graphics output through these panes.
The System Transcript window always remains present providing you with system messages and a work space to try out short pieces of code. In general, you will file code into its own Workspace window and save it as a file of its own. In the Inspector window you can examine (and modify) the state of any object in the Smalltalk/V environment. In the windows shown in Figure 3, we have opened up a global variable called GraphDictionary that holds a series of animation images we drew to make Saturn and five moons spin across the screen. Within the dictionary we opened up one of the images called Saturn1 and verified that we have stored the image as an instance of Smalltalk/V graphics class called “a Form.” If we then double-click on an item other than “self,” e.g. “bits,” we can take a look at the actual bitmap that describes our image and manipulate the contents of the map if we wish. As you can imagine, the Inspector serves as an excellent low-level debugging device.
The majority of the programming activity in Smalltalk/V goes on in the multipaned window known as the Class Hierarchy Browser. The three panes of this window provide a list of classes in the upper left-hand corner, a work space for writing new class or instance methods below, and a pane in the upper right-hand corner that toggles between a scrolling list of either instance or class methods. As soon as you define a new class, instance method, or class method it appears in the appropriate listing and, if selected, its methods appear in the bottom pane. The vast majority of programming actually utilizes simple cut, paste, and save procedures. To demonstrate, let’s look at the OOP concepts of inheritance and polymorphism: two of the major reasons behind Smalltalk’s power as a rapid prototyping development environment.
Look at Figure 2 again. Inheritance in Smalltalk operates much like inheritance in biological realms. Just as a rose inherits certain attributes and weaknesses as part of its membership in the larger class of all plants, and all plants exhibit certain characteristics fundamental to living matter, so superclasses in Smalltalk pass their characteristics on down the line to subclasses. In the OOP programming style you learn to think of solving a specific problem by systematically refining a more general solution for steadily more specific tasks. Smalltalk/V objects inherit both the instance variables and the methods of their superclasses. Once instantiated, we can modify these variables and methods to suit their particular behavioral requirements as well as add new ones.
For example, we might create a class called Matter and give it such instance variables as mass, position, and velocity. We might then give it a method called gravitationalAttraction. Next we create a subclass called Electron, give it an instance variable, charge, and a method named electrostaticAttraction. An Electron object would then possess the variables mass, position, velocity, and charge, as well as a two methods, gravitational and electrostatic attraction. We can then modify the particular values and characteristics of each of these variables and methods to fit the real world behavior we associate with an electron. You can see from a programming efficiency standpoint that we can now quickly create the methods and instance variables of our next subclass, say, Proton, by simply cutting, pasting, inheriting, and modifying the methods and variables instantiated in Matter and Electron.
Now, just as the physicist or psychologist simplifies a theoretical calculation by treating an object as a “black box,” Smalltalk/V lets us simplify programming as we attend primarily to the outer behavior (message passing) of each object while protecting its inner activity. This protection sets the stage for the polymorphic nature of Smalltalk/V. Polymorphism means that various objects can provide non-identical reactions to the same message. In fact, they will react according to their own internal variables and methods. The programmer simply needs to make sure he or she sends a message that makes sense.
Smalltalk/V Safety and Efficiency
From your first few moments of experimentation you will find Smalltalk/V an extraordinarily safe environment. An error simply looks like another object to Smalltalk/V and you will always get some kind of message back even if the environment simply says “I do not understand your message.” If you really want to see a crash you will have to work at it, like creating an infinite loop, and Smalltalk/V will even catch most of those. Otherwise you can experiment to your heart’s content.
When you do get an error message you will first see something like the window displayed in Figure 4. In this case, Smalltalk/V did not understand a message we sent from the System Transcript window and opened what Digitalk calls the Walkback window. The Walkback gives you a quick preliminary review of Smalltalk’s current state. If we immediately understand the problem we cancel the Walkback and proceed. Otherwise, we can invoke the Debugger window.
From the Debugger we can look at all the objects concerned with our code, evaluate predefined methods, set breakpoints, and hop, skip, or jump through our program. In Figure 5 we can see that an object called the SystemDictionary does not understand the current message selector. We simply have to go back and see if we had defined our message selector before proceeding. The four-paned window and five-button control system make the debugging cycle as painless as possible. Clicking the Walkback button produces a list of objects identical to the Walkback Window. Toggling with the Breakpoints button replaces the Walkback List with a list of the class name and method selector for all the methods with breakpoints set. Selecting a specific method brings up the source code for that method in the lower pane. Think of the two panes at top right as the inspector for the receiver object, the argument(s), and the instance variables of the method you want to dissect.
If you wish to Browse through all the methods sending or implementing a specific message selector, you can invoke Sender and/or Implementer Browser windows to find context-sensitive cross references for related methods and objects.
The Implementer and Sender windows have a scrolling upper pane that provides the list of choices. Once selected, the code for that object will appear in the lower pane. In Figure 6 you can see that we have summoned up the Implementer and Sender windows for all the messages invoking openOn: and then selected the BitEditor implementer and the grafPort sender as sample messages. Using this tool you can wander through any object you choose and evaluate the internal structure of code that defines or activates a specific message.
Do You Like Typing?
If you care about how much time you actually spend typing your code, the efficiency of Smalltalk/V really hits home quickly. A few readable lines of code go a long way. Let’s take a look at a short demonstration program provided by Digitalk comparing Pascal and Smalltalk/V. (See Listing 1.) The program in either version makes it possible for the user to enter a line of text from the keyboard and then find the frequency distribution for each of the 26 characters of the alphabet. In the first column you will see the Pascal version, in the second the Smalltalk/V translation.
If any of you wish to count the total number of keystrokes you’ll determine that Smalltalk/V takes about 30 percent less typing activity to produce the same amount of computer activity even in this literal translation. If we had written the program using some of Smalltalk/V’s built-in building blocks (see the Collection class description) we could have cut our programmer typing time by another 50 percent.
This brief program also demonstrates a particularly pleasant characteristic of the Smalltalk/V tutorial. With only minor extensions you can turn most of the examples into quite useful tools for your own application development. This one could easily turn into a frequency counter to monitor your excess usage of particular words or phrases in a thesis.
In fact, the gurus at Digitalk and JFS have already provided you with such a tool:
“Compute occurrences of a phrase in a file” | s pattern count input word | count := 0. s := Prompter prompt: ‘enter line’ default: ‘’. (pattern := Pattern new: #( s )) matchBlock: [count := count + 1]. input := File pathName: ‘:Genetics:Radiation:IMMORTALITY’. [(word := input nextWord) isNil] whileFalse: [pattern match: word asLowerCase]. ^count
Incorporate this into your Smalltalk/V environment and use it to evaluate any textual data.
Objects and Messages ∆ Objects can themselves contain objects of dissimilar size and type. Smalltalk/V uses “#” to designate the object array. #(‘Warning:’ ‘radiation’ ‘dosage’ > 3.5 ‘’rads’ ‘per’ 1 ‘hour’) denotes an array containing six objects of type string, one of type Boolean, one of type integer, and one of type floating point. To find out the size of this array you simply send it the message “size” like this:
#(‘Warning:’ ‘radiation’ ‘dosage’ > 3.5 ‘’rads’ ‘per’ 1 ‘hour’) size
and Smalltalk/V responds with “9”. If you replaced the message “size” with “at: 2” Smalltalk/V would return the string ‘radiation’ and if you sent the message “reverse” you would get back:
(‘hour’ 1 ‘per’ ‘rads’ 3.5 > ‘damage’ ‘radiation’ ‘Warning:’)
Notice Smalltalk/V takes care of all data typing problems for you because objects always know what messages they can receive. If an object expects to receive only string messages and another object sends an integer message, the receiver object will send out an “I don’t understand” message. This example also illustrates that Smalltalk/V has many of the list handling powers of Lisp, while still utilizing dynamic arrays as its fundamental way of organizing chunks of data.
Messages in Smalltalk/V operate in a way that is similar to function calls in other programming languages. Each message has three parts: a message receiver, a message selector, and zero or more arguments. In the arithmetic message 1 + 2, the message selector “+” sends the argument “2” to the message receiver “1.” The message ends when it returns the object “3.” Smalltalk/V evaluates all arithmetic messages from left to right with no other precedence rules. You simply enforce a particular message order using parentheses. Smalltalk/V also utilizes rational arithmetic. It does not round off fractions, but stores them as exact values by storing both the numerator and denominator.
If you wish to send more than one message to an object, you do not need to repeatedly name the receiver object. Instead, Smalltalk/V allows you to just separate the messages by a semicolon:
Turtle newWindow: ‘Turtle Graphics’; defaultNib: 2; darkGray; home; go: 100; turn: 120; go: 100; turn: 120; go: 100; turn: 120
Here the receiver object, Turtle, receives a series of messages to first create a new window. Then name it “Turtle Graphics,” set the graphics pen size and color, go to the center of the window, and then start drawing in classical Turtle Graphics style. Each of the messages changes the current state of the object. And no state change occurs unless the object receives a message it understands.
Smalltalk/V allows the assignment of Global and temporary variables. Global variables, such as “Turtle,” have a name that starts with a capital letter, contain only one object, and remain a part of the Smalltalk/V environment even after you finish a particular operation. In contrast, Smalltalk/V disposes of temporary variables as soon as they have served their immediate purpose. You identify variables as temporary by declaring them between vertical bars and starting their name with a lower case letter. The symbol := assigns a value to either a Global or temporary variable. (See Listing 2.)
If you have not declared a variable at the beginning of your expression, you can set up a type of temporary variable that Smalltalk/V calls a block argument. For example:
[:character | character isDigit]
would let you to test in the middle of an expression to make sure you had a digit in hand. A colon, :, precedes the block argument, character, and a vertical bar, |, separates the block argument from the statements.
Smalltalk/V also has an extensive set of control structures. We could have drawn the equilateral triangle above with a simple loop:
Turtle newWindow: ‘Turtle Graphics’; defaultNib: 2; gray; home. 3 timesRepeat: [Turtle go: 100; turn: 120]
Basic looping messages available include timesRepeat, atEnd, whileTrue, and whileFalse constructs. These operate much like looping structures in the more common procedural languages. The following simple example copies a file:
“Copy a disk file” | input output | input := File pathName: ‘Radiation’. output := File pathName: ‘Statistics’. [input atEnd] whileFalse: [output nextPut: input next]. input close. output close “Copy a disk file” | input output | input := File pathName: ‘Radiation’. output := File pathName: ‘Statistics’. [input atEnd] whileFalse: [output nextPut: input next]. input close. output close
The atEnd message keeps sending false as long as the input stream has characters. The next message reads the input file stream and nextPut writes the output stream. When atEnd sees no more characters it sends true and the receiver closes the input and output files.
Smalltalk/V comes with a full complement of the normal comparison messages such as <, <=, >=, >, ~=. But instead of using if statements for conditional execution, Smalltalk/V utilizes the messages ifTrue:, ifFalse:, ifFalse:ifTrue; and Boolean and/or messages. Listing 3 tests a series of three calculations and identifies the maximum value using ifFalse and ifTrue conditionals.
In addition, Smalltalk/V comes with a variety of built in testing messages like isVowel, isUpperCase, isLowerCase, isMacFont, isMenu, isMemberOf, isScreen, isThereInput, isShift, and more than thirty others. Notice that these implement a rich diversity of classes including Character, Font, Menu, Object, GrafPort, CursorManager, and InputEvent.
Smalltalk/V contains the iterators to:do and to:by:do. The latter allows you to set the incremental value instead of assuming an increment of 1.
If you wish to compute the sum of integers from 1 to 10:
| sum | “Declaring a temporary variable.” sum := 0. “Setting the variable to 0.” 1 to: 10 do: [ :i | sum := sum + i]. ^sum
returns the value 55.
Now suppose we want to compute the sum of .10, .11, .12…. to .20. Just remember to use rational fractions, set your interval to hundredths using the by: message selector, and:
| sum | sum := 0. 10/100 to:20/100 by: 1/100 do: [ :i | sum := sum + i]. ^sum
will return a sum of 33/20.
Let’s look at the more generalized and powerful iterative messages such as do:, count:, select:, reject:, and collect:. If we wanted to count the vowels in a string with what we have available so far we might write code that looked like this:
“Count the vowels in a sentence.” | vowels string index | vowels := 0. index := 1. string := ‘The radiation induced genetic changes helped.’. [index <= string size] whileTrue: [(string at: index) isVowel ifTrue: [vowels := vowels + 1]. index := index + 1]. ^vowels
Using the more generalized message do: we can condense the code to:
| vowels | vowels := 0. ‘The radiation induced genetic changes helped.’ do: [ :char | char isVowel ifTrue: [vowels := vowels + 1]]. ^vowels
The do: message tells the string to iterate across itself and pass each character to the block for evaluation by isVowel. If we utilize the more powerful message select: we can condense to:
( ‘The radiation induced genetic changes helped.’ select: [:c | c isVowel]) size
and get a result of 16.
Here select: not only cause the iterative sequence, but also returns the vowels it identifies. The message size produce the numeric computation, but you could have as easily manipulated the string of vowels with any other appropriate message. For example, if you suddenly found yourself interested in the phonetics of the consonants in that same string:
( ‘The radiation induced genetic changes helped.’ reject: [:c | c isVowel])
gives us ‘Th rdtn ndcd gntc chngs hlpd.’ or
(‘The radiation induced genetic changes helped.’ reject: [:c | c isVowel]) size
tells us we have 29 consonants.
Digitalk provides an excellent example of the utility of these operators for any of us needing to co-exist with MS-DOS files. Macintosh owners take it for granted that we can make our file names as long and meaningful as we like. If you need to compress down to the bare essentials of an abbreviated name like the poor folks at Big Blue, you might like to do it automatically. The following code reverses your Mac file name, takes out the vowels, then starts chopping off characters from the end until it gets you under an 8 character limit. The ^ tells you that the whole last half of the code will simply return a single result: your new file name.
“Abbreviate a long Macintosh file name to 8 characters for a PC” | name length | name := ‘Mac Big File Name’. length := name size. ^( name reversed reject: [ :c | c isSeparator or: [ c isVowel and: [ c isLowerCase and: [ ( length := length - 1 ) >= 8 ] ] ] ] ) reversed, ‘ ‘ copyFrom: 1 to: 8
In this case you can call your file ‘McBgFlNm.’ Sounds awful, but works.
The generalized iterators also work well with arrays. Suppose you need to collect a data set and then need to perform a transform on each element of the array by a series of functions. You simply need to define your functions and then use the message collect: We’ll use a built in function, factorial, and write:
#(1 3 5 7) collect: [:i| i factorial]
to have Smalltalk/V give us the factorials of the first four prime numbers, (1 6 120 5040). Digitalk has provided a variety of scientific and financial messages. You can easily cut, paste, copy, and mold the methods in these messages to craft your own user-defined math packages.
The messages select:, reject:, and collect: all work with Strings, Arrays, Sets, and Bags. Smalltalk/V contains only a single sequence of code for each of these messages. It does not need a separate code for each object to work with each collection. Instead, Smalltalk/V’s polymorphic character lets you write generic code independent of data type and structure. Look at the code for the message collect:
collect: aBlock “For each element in the receiver, evaluate aBlock with that element as the argument. Answer a new collection containing the results as its elements from the aBlock evaluations.” | answer | answer := self species new. self do: [ :element | answer add: (aBlock value: element)]. ^ answer
As a part of class Collection, all the subclasses of Collection inherit the message collect: including Bags, Sets, Dictionaries, Sorted Collections, and Ordered Collections. You notice the method depends only on the behavior of an object, not its data type or structure. Different types of objects will respond to the same message according to their own characteristics.
How About Fun?
You guessed it. Smalltalk’s pivotal role in the development of windows and bit-mapped graphics makes it an instant fit for any of us addicted to graphics, pictures, and animation. Run right out, beg, borrow, or buy Smalltalk/V and plug in the code in Listing 4.
You will simply get a blacked out screen with an image of Saturn and five of its moons spinning across space. But when you realize that you can put the code for such images together in a few minutes, can build multiple animators, and make the images out of either the little drawing program already implemented in Smalltalk/V or use your favorite graphics program, you’ll find yourself hooked. Enjoy.
Mac II vs Mac SE/30
We got a new SE/30 just as this article went to press, but we did have a few minutes to try out Smalltalk/V. As advertised, the environment runs just fine on either the 68020/68881 or the 68030/68882 combinations. The SE/30 seemed a bit snappier so we ran a couple of simple but practical benchmarks: how long does it take to open files of various size and how quickly can you run a frequency distribution for the 26 letters of the alphabet. (See Table 1 for results.)
The SE/30 handles the opening task a bit better for large files but it really shows performance gains of about 10 to 15 percent on the parsing and array handling demands.
Application Development in Smalltalk/V
Within the framework of their tutorials Digitalk has implemented two applications: a simple phone book and a more complex corporate communication tool that relies on state-transition models. In the development of these applications you quickly acclimate to the development and learning cycle outlined in Figure 1 at the start of this review. You create multipaned windows that give you combined text and graphics capabilities. You implement windows, menus, and special effects with minimal coding.
Most of all you learn to experiment, make code do double and triple duty by recycling it in multiple methods, and really think in terms of inheritance and libraries of objects and methods. The application case studies soon give you a real sense of creating dozens of tiny helpers waiting in the wings. This attitude moves much closer to the native operating style of the Macintosh than any of the standard linear flow procedural languages currently in use.
You will also realize that the concept of an application seems a bit foreign to the original Smalltalk metaphor. Smalltalk really does feel more like an environment than a cluster of applications, but I think Digitalk has realized that style will seem foreign to most users. Their emphasis in the tutorials on creating specific applications will come more naturally to professionals looking for discrete techniques to manipulate scientific, medical, or financial data.
If you wish to create standalone applications Digitalk has included a tool called “Cloner.” This will create for you a snapshot of a current Smalltalk/V environment. It will then let you strip that environment of all the classes and objects you do not need to simply implement one single application. While Smalltalk/V compiles to a byte-code set, no separate compiler or runtime interpreter package for developing standalone applications exists at this time. Digitalk has implemented both for the MS-DOS versions of Smalltalk and plan to proceed in that direction for the Mac implementation. If you wish to create extensions of Smalltalk/V in C, remember that C expects a static memory management system instead of the dynamic memory environment of Smalltalk/V. When your C routine starts, Smalltalk/V freezes in place until the C procedure terminates. When Smalltalk/V starts up again C will lose its pointers.
|File Size (kilobytes):||8||22.7||44.7||67.7||103.4|
|Mac II Time (seconds):||1.7||3.7||5.8||8.6||13.0|
|Mac SE/30 Time (seconds):||1.7||3.1||4.7||6.8||10.2|
|Alphabet Frequency Distribution|
|File Size (kilobytes):||8||22.7||44.7||67.7||103.4|
|Mac II Time (seconds):||8.6||22.4||42.1||62.0||94.3|
|Mac SE/30 Time (seconds):||10.6||18.2||34.6||50.1||77.2|
Digitalk’s staff has seemed most accessible for technical support. The fact that you have most of the source code available means that most bugs can easily respond to phone instructions or bulletin board postings of methods revisions. Currently active Smalltalk/V interchange occurs on BIX in Digitalk, Smalltalk, and Object Oriented Design online conferences. You can also reach Digitalk on AppleLink. They provide free general customer support, may implement a bulletin board service of their own, and have started considering a developer program.
Like most reviewers enthusiastic over a new tool, I cannot resist putting in my vote for more goodies. I would certainly like to see both a compiler and a high speed board appear for the Macintosh implementation similar to Digitalk’s strategy with our MS-DOS brethren. At present it appears that the latter may occur, since International Meta Systems will probably produce an accelerater board soon. Rumor has it that it speeds up Smalltalk/V 4-10x current Mac II performance. This language would make a superb development platform for real-time imaging requirements in physics, engineering, radiology, neurology, and cardiology.
In a similar vein, increased attention to support for a variety of Macintosh-based parallel processing systems would make this an excellent candidate for investigating neural network paradigms.
For Smalltalk/V to really capture everyone’s attention we will need to see an extension of Digitalk’s excellent tutorials into a series of practical application shells for specific disciplines emphasizing the environment’s prototyping, graphics, and data organization strengths.
In a Nutshell
Two items really won my applause in Smalltalk/V. First, the object MTraps in the Class Hierarchy Browser handed me immediate access to over 150 calls to the Mac Toolbox AND a cross-reference to Inside Macintosh seemed (after five years) to finally make Mac understandable.
Secondly, I learned Smalltalk/V and wrote this review in the same way any busy professional would: programming and writing time gets crammed into a few minutes up to an hour or two between patients, research projects, and letting the kitty in or out. I found it extraordinarily easy to slip back into my train of thought about a program in Smalltalk/V unlike my experience with C, Pascal, LISP, or even HyperCard. After a few days I even felt a bit a part of that environment myself. If Digitalk can introduce more professionals to that kind of programming experience, I think Smalltalk/V will make a substantial contribution to the personal computer revolution.
A. Goldberg, and D. Robson, Smalltalk-80: The Language and Its Implementation. Addison-Wesley, 1983.
A. Goldberg, Smalltalk-80: The Interactive Programming Environment. Addison-Wesley, 1984.
T. Kaehler & D. Patterson, A Taste of Smalltalk. W. W. Norton & Company, 1986.
M. C. & L. J. Storrie-Lombardi, “Smalltalk: Object
Oriented Programming.” MacA.P.P.L.E., Vol 4, No 1,1987, pp. 36-39.
Michael Storrie-Lombardi serves as Vice-President of Chrysalis Technologies, Inc., and has special interests in neural net pattern recognition, magnetic resonance spectroscopy, and the use of personal computers in physics and medicine.
Listing 1-A (Pascal)
program frequency; const size = 80; var s: string[size]; i: integer; c: char; f: array [1..26] of integer; k: integer; begin writeln (‘enter line’); readln(s); for i := 1 to 26 do f[i] := 0; for i := 1 to size do begin c := asLowerCase (s[i]); if isLetter(c) then begin k := ord(c) - ord(‘a’) + 1; f[k] := f[k] + 1 end end; for i := 1 to 26 do write(f[i], ‘ ‘) end.
Listing 1-B (Smalltalk/V)
|s c f k| f := Array new: 26. s := Prompter prompt:‘enter line’ default: ‘’. 1 to 26 do: [:i | f at: i put: 0]. 1 to: s size do: [ :i | c := (s at: i) asLower Case. c isLetter ifTrue: [ k:= c asciiValue - $a asciiValue + 1. f at: k put: (f at: k)+ 1 ] ]. ^f
| temp index factorials | “Defining temporary variables.” factorials := #( 3 4 5 6 ). “Initializing Variables.” index := 1. factorials size timesRepeat: [ temp := factorials at: index. factorials at: index put: temp factorial. index := index + 1]. ^factorials “Identifying the variable holding the result.” (6 24 120 720) “Result”
| tempMax max a b c| “Defining temporary variables.” a := 5 squared. “Initializing Variables.” b := 4 factorial. c := 67/2. a < b ifTrue: [tempMax := b] “Testing” ifFalse: [tempMax := a]. tempMax < c ifTrue: [max := c] ifFalse: [max := tempMax]. ^max “Requesting the result.” 67/2 “Result”
| saturnImages | saturnImages := “Identifying the variable holding the result.” “Result” “Defining temporary variables.” “InitializingVariables.” “Testing” “Requesting the result.” “Result” Smalltalk/V Mac Array “build an Array of pictures of a walking dog” with: (GraphDictionary at: ‘Saturn1’) with: (GraphDictionary at: ‘Saturn2’) with: (GraphDictionary at: ‘Saturn3’) with: (GraphDictionary at: ‘Saturn4’). Animator := Animation new initialize: Display boundingBox. “init clipping rectangle” Animator add: saturnImages name: ‘Saturn’ color: #lightGray. “Zoom the window to full screen and then evaluate with do it” Display black. “make whole screen black” Animator speed: 4; “each picture is displayed 8 pixels apart” shiftRate: 2; “same picture is displayed twice” setBackground; “use current screen as background” tell: ‘Saturn’ place: 0 @ 0; tell: ‘Saturn’ direction: 45; tell: ‘Saturn’ go: 350. Menu message: ‘continue’. Scheduler redraw