<?xml version="1.0"?>

<st-source>
<!-- 
Name: Non-Commercialization
Notice: Copyright © 2005-1999 Cincom Systems, Inc.  All Rights Reserved.
Comment: This parcel is what is loaded into the commercial image to create the non-commercial image.
DbIdentifier: bear73
DbTrace: 55543
DevelopmentPrerequisites: #(#(#any 'UIPainter' '') #(#any 'SLesson Intro Content' '') #(#any 'StoreForPostgreSQL' '') #(#any 'Tools-Workspace' ''))
GettingStartedWorkspace: Text for 'Getting Started with VisualWorks
A wealth of information and aids are available to help you get started with VisualWorks:
	• Cincom Smalltalk Website
	• VisualWorks Documentation
	• Lesson Browser and Web-based Tutorials
	• Online Help
	• UIUC Wiki
	• Usenet''s comp.lang.smalltalk

1. The Cincom Smalltalk Website has many resources for both new and seasoned users, including Web-based tutorials, a Smalltalk glossary, and links to other Smalltalk sites. Visit us at:

	http://www.cincom.com/smalltalk

At the site, you may also request the Cincom Smalltalk Digest, an e-mail newsletter for VisualWorks users. It''s an easy way to stay up-to-date with news about Cincom Smalltalk, developer and education programs, and upcoming events in the VisualWorks community.


2. VisualWorks documentation is provided on-line in Adobe Acrobat PDF format, and via an interactive Help system in VisualWorks. To read the PDF documentation, you''ll need Adobe Acrobat Reader, available for free at www.adobe.com. To discover the documentation set, we suggest starting with the following:

	• Welcome.pdf -  an overview of the VisualWorks documentation set, and generally a good place to start. This can be found in the root directory of your VisualWorks installation.

	• Installation Guide (Install.pdf) -  a guide for both new and experienced users to install VisualWorks and its add-on components.

	• VisualWorks FAQ (/doc/VisualWorksFAQ.pdf) -  answers to many frequently-asked questions. A good place to start when troubleshooting.

For new users who are starting with VisualWorks, we especially suggest:

	• VisualWorks Walk-Through (/doc/WalkThrough.pdf) -  a short, step-by-step introduction to the VisualWorks environment that teaches you how to build a GUI-based application.

	• Application Developer''s Guide (/doc/AppDevGuide.pdf) -  a comprehensive guide to the VisualWorks environment, tools, base libraries, and their usage.  This is appropriate for developers at all levels, since it covers the fundamentals of the base system.


3. Several VisualWorks tutorials are available, designed especially for new users:

	• The Lesson Browser provides an interactive introduction to the Smalltalk language and some of the VisualWorks class library. It is pre-loaded with VisualWorks non-commercial.
To open it, select Help -> Lesson Browser in the Launcher window. 

	• Online tutorials are available for users who know nothing about Smalltalk but a little something about programming. The tutorials lead you step-by-step in building an actual Smalltalk application. For details, see:

	http://www.cincom.com/smalltalk/tutorial/


4. VisualWorks Help includes detailed information about the Smalltalk language, the VisualWorks tools, class library, code examples, a glossary of terms, and details about building applications.

	• To open the VisualWorks Help Browser, use the Help menu in the VisualWorks Launcher window. The Help Browser loads when you select Load Help. Thereafter, you may select Topics to open the Help Browser.


5. The University of Illinois at Urbana-Champaign (UIUC) very kindly provides several Web resources on VisualWorks and Smalltalk:

	• A Wiki (a user-editable web site) for discussing any and all things VisualWorks-related:

	http://wiki.cs.uiuc.edu/VisualWorks

UIUC hosts a variety of tutorials and other materials for learning on VisualWorks:

	http://wiki.cs.uiuc.edu/VisualWorks+Tutorials+and+courses

	• A mailing list dedicated to the users of VisualWorks Non-Commercial. To (un)subscribe, send a message to:

	vwnc-request@cs.uiuc.edu

The SUBJECT of the message should be "subscribe" or "unsubscribe". Sending an email with the SUBJECT of "help" or "archive-help" will return a list of useful commands for searching the mailing list''s archive.

	• Faculty and students at UIUC, who are long-time Smalltalk users and leading lights in the Smalltalk community, maintain a Smalltalk archive at:

	http://st-www.cs.uiuc.edu/


6. The Usenet Smalltalk news group, comp.lang.smalltalk, hosts active discussions about Smalltalk and VisualWorks, and is a great source for advice.


7. The community site Why Smalltalk provides articles, Smalltalk industry news and up-to-date information about all dialects of Smalltalk, including VisualWorks:

	http://www.whysmalltalk.com/


8. Many good books on Smalltalk and VisualWorks are available from commercial book sellers.  Two books which concentrate on VisualWorks (version 2.5) are:

	Smalltalk: An introduction to application development using VisualWorks
	Trevor Hopkins and Bernard Horan
	Prentice-Hall, ISBN 0-13-318387-4

	Smalltalk by Example. The developer''s guide.
	Alec Sharp
	McGraw-Hill, ISBN 0-07-913036-4

'
HideSource: false
IvanWorkspace: Text for 'Introduction to VisualWorks Smalltalk
Copyright © May 2003, Ivan Tomek
(Please send comments, suggestions, and corrections to ivan.tomek@acadiau.ca, www.). 
Disclaimer: This is an unsolicited contribution and not an official component of the environment. All errors and inconsistencies are mine and I do not assume any legal responsibility for them.

Preface

This Workspace introduces the main concepts of Smalltalk in general, and VisualWorks Smalltalk in particular. It explains the language,  the environment, its essential components, and the principles of developing a complete Smalltalk application. The text is interactive and you can edit it, execute all examples, modify them, and add and execute your own code.

I use the following colors to emphasize different types of information:

Blue for executable code and program-related information.
Red for environment commands appearing, for example, in popup menus.
Black for all other text.

This Introduction has the following parts:

- Part 1: Why Smalltalk?
- Part 2: Objects and Messages
- Part 3: Objects and Classes
- Part 4: Creating and Editing Methods and Classes
- Part 5: Essential Classes and methods
- Part 6: Other Important Classes
- Part 7: Creating Graphical User Interfaces
- Part 8: Developing a Smalltalk Application
- Part 9: What Next
- References


Part 1: Why Smalltalk?

- The rules of the language are very simple.
- The underlying concepts are simple and uniformly applied across the language.
- Smalltalk remains one of the very few ''pure'' object-oriented languages.
- There is no separation between the language and the programming environment - the environment itself is a live universe of objects.
- Code written by a knowledgable Smalltalk programmer is very compact and readable. This improves readability and development.
- The source code is a part of the environment and is thus constantly available for study, extension, and modification. It explains functionality better and more accurately than any other documentation and access to it speeds up development. 
- The development environment is very powerful.
- The language and the development environment are reflective, which means that your program can access information about its structure, implementation, and even run-time operation, and extend or modify them as you wish even at run-time.
- Compilation is incremental so that any code and even a piece of a program can be executed instantaneously at any time. This makes for very fast development and testing, and encourages experimentation and improvement.
- Because of the nature of the compilation and execution process, you can interrupt any application at any point, inspect the code and the objects, modify them, and continue running the application without recompiling it even after changing code.
- Smalltalk is strongly typed, meaning that you cannot make an object execute a message that it was not programmed to understand.
- Smalltalk is dynamically typed, which means that when your program needs to evaluate a message, it finds its definition at run-time rather than at compilation time. This makes the language very flexible and Smalltalk applications very extendible.
- VisualWorks Smalltalk is very portable and allows well-written applications to run without any change on more than ten different platforms.
- The language and the environment are very mature. They have been initially developed over a period of ten years between 1970 and 1980 in a research setting isolated from commercial pressure and evolved into a very well thought-out structure before being made available for commercial use. VisualWorks - a direct descendent of the original Smalltalk - keeps up to date with technology evolution by regular releases for both commercial and non-commercial users.
- Finally, there is an enthusiastic group of users of both VisualWorks Smalltalk and other Smalltalk dialects. Find them in the comp.lang.smalltalk newsgroup. 

In the following sections, I will introduce enough Smalltalk so that you can start developing simple applications and, more importantly, explore further easily. For more information, read the on-line help (accessible from the Launcher window) or the extensive documentation (especially the documents called WalkThrough.pdf and AppDevGuide.pdf) that is a part of each VisualWorks release. 


Part 2: Objects and Messages

1. Everything in Smalltalk is an object, and all work is done by sending messages to objects

Everything in Smalltalk, including numbers, strings of letters, windows, the compiler, and the whole interactive development environment  is an object. Objects communicate by sending messages to one another and everything in Smalltalk happens by sending a message to an object. Writing Smalltalk programs consists of defining new kinds of objects and extending and reusing objects already available.

The basic part of a Smalltalk program is an expression, such as

''abc'' asUppercase

An expression consists of a receiver object that executes the message (here the string ''abc'') and a message (here asUppercase). The receiver always comes first, the  message follows. Think of a Smalltalk expression as an order to the receiver to execute a message. Just as you might say in English

dog bark!

or

car go!

the expression ''abc'' asUppercase is an order to the ''abc'' to convert itself to uppercase letters. I will tell you in a moment how to execute an expression, but firts a few commented additional examples of Smalltalk expressions (the text surrounded by double quotes " is an explanatory comment).

3 squared			"Receiver is integer object 3, message is squared. It is an order to object 3 to calculate and return the integer object representing its square."
''abc'' reverse			"Receiver is string object ''abc'', message is reverse. It is an order to object ''abc'' to calculate and return its reverse."
200 factorial			"Receiver is integer object 200, message is factorial. Read it as an order to 200 to calculate and return its factorial: 200*199*198*..*1."

To execute these examples one-line-at-a-time and see the results, proceed as follows:

- Select (highlight) the text using the left mouse button as in a word processor, or double-click at the beginning of the line.
- Evaluate the selection with the Print it command in the right mouse-button menu (the <operate> menu).

Do not try to execute the three lines together - Smalltalk would treat them as one big but inconsistent expression. More on this later.

By the way, you can type and evaluate Smalltalk expressions in any VisualWorks text space, not just the Workspace. However, I recommend that you open a new workspace for your additional experiments by executing the command sequence Tools -> Workspace in the main Launcher window (select command Tool in the menu and then click the Workspace command). Or click the notebook button on the launcher for the same result.

2. Smalltalk has three kinds of messages: unary, binary, and keyword

Smalltalk allows three kinds of messages: unary, binary, and keyword messages. The difference between them is 
- in the structure of the name of the message (its selector) and 
- the number of arguments that that the message expects.

Unary messages consist of a single ''word'' (properly called an identifier); they don''t have any arguments. Evaluate the following three examples line-by-line with Print it.

3 negated						"Receiver is 3, message selector is negated"
27 squared						"Receiver is 27, selector is squared"
''black fox'' dropFinalVowels		"Receiver is ''black fox'', selector is dropFinalVowels"

By the way, don''t puzzle about these and the following example messages - we will soon explain where they come from and how you can browse them.

Binary messages use one or two special characters such as + - / \ @ , & | and @  for selector, and the selector is followed by one argument. Examples are

3 + 5		"Receiver is 3, selector is +, argument is ''small integer'' object 5. Note that all arithmetic operations are implemented by messages."
''abc'' , ''xyz''	"Receiver is ''abc'', selector is , and argument is string object ''xyz''"
17 // 5		"Receiver is 17, selector is //, argument is small integer 5"

Keyword messages may have any number of arguments and each of them is preceded by an identifying keyword. The selector consists of one or more keywords (a keyword is an identifier followed by a colon), and each keyword is followed by argument. Read and evaluate the following examples:

3 between: 5 and: 10	"Receiver is 3, message selector is between:and:, keywords are between: and and:, and arguments are 5 and 10"
$d between: $a and:$r	"Receiver is character d, message selector is between:and: and arguments are characters a and r"
3 raisedTo: 17			"Receiver 3, message selector is raisedTo: and argument is 17"
Dialog request: ''Your name, please'' initialAnswer: ''John''	"Receiver is ''class'' object Dialog (more later), selector is request:initialAnswer:"
''aLongWord'' chopTo: 5	"Receiver is string ''aLongWord'', selector is chopTo:"

The message in the following expression is unusually long - it has six keywords. Its selector is choose:fromList:values:lines:cancel:for: I show it using multi-line formatting commonly used for keyword messages with multiple arguments but you can type it all on one line or in any other style because Smalltalk does not pay attention to ''white space''. Evaluate the expression by selecting all seven lines together and executing Print it

Dialog 
		choose: ''Which line do you want?'' 
		fromList: #(''first'' ''second'' ''third'' ''fourth'') 
		values: #(1 2 3 4) 
		lines: 8 
		cancel: [#noChoice]
		for: Dialog defaultParentWindow

Note that identifiers (names of unary messages and keywords) start with a lowercase letter and contain only letters and digits. They have unlimited length and are case sensitive, so that asUppercase and asUpperCase are different. To verify this, try evaluating the following message. It will fail  and Smalltalk will open a selection dialog because there is no message called asUpperCase. You can respond by clicking cancel to terminate execution and correct the code, or with correct it. In this case, VisualWorks will offer one or more similarly spelled selectors and if you select one, it will correct the mistake and continue evaluation. The correction mechanism usually succeeds when you make a small typing mistake but larger mistakes must be corrected by hand.

''abc'' asUpperCase

In closing, the definitions of all of the messages listed above are available as a part of the environment and I will explain shortly how you can access them, modify them, and define your own messages.

3. Every message returns an object and messages can thus be combined

Every expression returns an object to its sender and you can thus use an expression as the receiver of another message. Evaluate the following lines one by one with Print it.

5 factorial squared				"Integer 120 - the result of 5 factorial - is the receiver of message squared"
''abc'' asUppercase reverse		"The result of ''abc'' asUppercase is the receiver of message reverse"
13 factorial sqrt truncated even	"Interpretation: Calculate 13 factorial, then its square root, truncate the result an integer, and tell me whether it is even"

Note that you can even select and evaluate parts of the above ''chained'' expressions. As an example, you can execute only the 5 factorial or the 13 factorial sqrt parts of the lines above if you wish. This is sometimes very useful. 

Because messages return objects, expressions can also be used as arguments as in

3 raisedTo: 5 squared			"The result of 5 squared is the argument of the keyword message raisedTo: so this is equivalent to 3 raisedTo: 25"
''the number is: '', 5 printString	"The result of 5 printString is the argument of the binary concatenation message , and equivalent to ''the number is: '', ''5'' "
ComposedTextView open: ''abc'' asText allBold asValue	"The argument of open: is the result of sending three consecutive messages to ''abc'' "

Expression

5 factorial between: 3 squared and: 3 * 5 * 9

is also valid but the following formulation in which parentheses group parts that belong together is more readable and thus preferable:

(5 factorial) between: (3 squared) and: (3 * 5 * 9)

Smalltalk programmers routinely chain messages, but the facility should not be overused at the expense of readability. In fact, one of the essential rules of object-oriented programming called Demeter''s rule (search the Web for details) strongly advises against it.

Evaluation of combined messages obeys the following simple rule:

4. Messages are executed from left to right; parenthesized expressions first, unary messages next, binary next, keyword last

This is the only rule you need to learn to read and write Smalltalk code. As an example, 

3 + 2 raisedTo: 2 squared + 7		"squared first (unary), + next (binary), raisedTo: last (keyword)"

is equivalent to

(3+2) raisedTo: ((2 squared) + 7)		"Parentheses first, unary messages next, binary then, keyword last."

as you can check by evaluating both expressions. 

These simple rules apply to everything and there are no other precedences that can be found in most other programming languages - even where you might expect them. So, for example,

5 + 3 * 4

is a sequence of binary messages and is evaluated left-to-right. It is thus equivalent to

(5 + 3) * 4

which is not what you might have expected. To avoid unpleasant surprises, use parentheses for more complicated expressions, even when they are not necessary. Adding them does not affect evaluation speed but improves readability. I would thus write

(5 * 3) + 4

instead of

5 * 3 + 4

even though both expressions produce the same result.

5. Statements

Smalltalk code usually consists of more than a single expression. I will call a sequence of expressions a code fragment (some people call it a script) and its components are called statements. Consecutive Smalltalk statements are separated by periods, just as English sentences. As an example,

3 squared.
5 factorial

is a small (and meaningless) code fragment consisting of two statements, each evaluated separately. If you execute it by selecting both lines and using Print it, you will get the result returned by the last expression. As another example, the following two lines clear the ''Transcript'' - the bottom part of the main Launcher window - and display ''Hello world''

Transcript clear.					"Note the period separating this statement from the next."
Transcript show: ''Hello world!''	"Transcript is a word know to the environment and represents essentially the text-display object in the Launcher."
 
Execute this code fragment with Do it and then examine the Launcher window. (Do it is like Print it but it does not print the result. You can execute the fragment with Print it as well, but here we are interested in the effect of the two lines rather than the object returned by the last expression. To see the difference, try both.) 

6. Shortcut: A sequence of messages to the same receiver can be cascaded

If a sequence of consecutive statements has the same receiver, you can use cascading instead of retyping the receiver. As an example,

Transcript clear.					"Note that this and the following statements have the same receiver Transcript."
Transcript show: ''Hello world!''.
Transcript cr.
Transcript show: ''How are you?''

has the same effect as the ''cascaded'' form

Transcript clear;				"Note the semicolon separating the ''cascaded'' messages instead of a period separating statements."
	show: ''Hello world!'';		"Receiver is not repeated."
	cr;
	show: ''How are you?''

The semicolon that ends each cascaded expression indicates that the next message is sent to the same receiver as the current message. In this case, all the messages are sent to Transcript. Note that although each consecutive message in a cascade goes to the same object, the state of that object may be changing as the messages are evaluated. In this example, the receiver of all messages is Transcript. The original Transcript may have contained text, but after the clear message, it is empty - its state has changed.

You can always write code without using cascading - cascading is just a shorthand to save typing and possibly make code easier to read. Some people think that code is easier to read without cascading and avoid it. I think that cascading with proper indenting improves readability.

7. Variables

After evaluating a message, Smalltalk automatically discards the returned object unless you assign it to a variable, or unless the object is referenced by another object that still exists. (This automatic removal of unneeded objects is called automatic garbage collection.) So if you need to keep the result of an expression later, assign it to a variable. All variables in Smalltalk must be ''declared'' before the first statement and the declaration lists the names of all required variables but does not specify their type. Here is an example:

| price tax total |		"Declaration: Variable names separated by spaces."
price := (Dialog request: ''Please enter price'' initialAnswer: ''100'') asNumber.
tax := (Dialog request: ''Please enter price %''  initialAnswer: ''10'') asNumber.
total := price + (price * tax / 100).
Transcript clear;
	show: ''price: '', price printString; cr;
	show: ''tax: '', tax printString; cr;
	show: ''total: '', total printString

Evaluate this code fragment with Do it and examine the Transcript to see the result. (If you are using a Workspace, you don''t need to declare variables - the Workspace does it for you and you can examine all your variables under the tab Variables. In every other place, such as the Transcript, variables must be declared.)

The reason why Smalltalk variables (unlike variables in most other languages) don''t require type declaration is that they are just pointers to objects, essentially addresses of memory locations holding the representation of the object to which they are ''bound''. As a consequence, a variable can point to one object in one part of a fragment and another in another part of the same fragment. Doing this is, however, considered poor programming style.

The variables introduced in this code fragment are called temporary variables and their scope (range in which they can be used by the program) and lifetime are limited to the code fragment: When the code fragment is fully evaluated, they cease to exist and the objects that they point to are discarded - unless they are referenced by other objects. I will introduce other types of variables later.

Symbol := is the assignment operator and it binds the result of the right hand side of the assignment statement to the variable on the left hand side. If you are in a hurry (or lazy), you can get := by pressing <Ctrl> and letter g. (Presumably because assignment stands for ''variable gets value''.) By the way, the assignment operator is not a message but a part of Smalltalk''s definition.


Part 3: Objects and Classes

1. Objects have properties

Real objects have properties: A person has a height, weight, name, address, and age, and many of these properties change during a person''s lifetime. A car has a licence plate, manufacturer, color, and mileage, different cars usually have different values of these parameters, and some of these parameters change as during the car''s lifetime. A major reason why object-oriented languages such as Smalltalk were invented was to model real-world objects and concepts. As a result,  Smalltalk objects may also have properties and their values may also change during their lifetimes. As an example, the Transcript object obviously needs to know the text that it displays and this property changes as the text does. In a library program, borrowers may be represented by Borrower objects and every Borrower object probably has a first and a last name, an ID, and a list of borrowed books, and different Borrower objects probably have different values of these properties. Every Book object may have an author, a title, a publisher, a library number, and a borrower, sometimes collectively referred to as the state of the state of the object. Different Book objects probably have different states, in other words, different values of their defining properties. Similarly every Fraction object is naturally characterized by its numerator and denominator and different fractions have different numerators and denominators.

To examine the properties of a Smalltalk object, use the Inspector: Evaluate each of the following lines separately with Inspect it from the <operate> menu:

3 @ 5										"Returns a Point object as indicated in the label at the top of the Inspector window. Its components are shown below."
Rectangle origin: (3 @ 5) corner: (25@30)	"Returns a Rectangle object."
3 / 5										"Returns a Fraction."

Command Inspect it first executes Do it and then opens an Inspector on the object returned by the last message. You can also inspect an object by sending it the inspect message as in

(3 @ 5) inspect		"Evaluate with Do it"

As you might guess, the inspect message is the essence of the Inspect it command.

If an object has properties they are, of course, again objects because everything is an object. As an example, the rectangle returned by the second line is a composite object with components called origin and corner and these components are objects (points) with their own properties. To see their structure, select the line with the name and execute Dive in the <operate> menu of the list. To return to the previous Inspector level, execute Back in the <operate> menu or use the arrow button at the top of the Inspector. Play with the Inspector to discover its basic functionality and read the documentation or on-line help to learn more about it.

2. Every object is an instance of a class

All fractions are objects of the same kind and share the same definition, which says that a fraction has a numerator and a denominator and that it understands certain messages. The only difference between individual fractions is that they may have different numerators and denominators. Similarly all rectangle objects share the same definition and so do all text objects. The definition of all objects of the same kind is gathered in a special kind of object called a class. Fractions are defined in class Fraction, rectangles in class Rectangle, and text objects in class Text. You can think of a class as a ''blueprint'' kind of object that is used mainly to create instances of the objects that it defines. Class Fraction can create objects such as 3 / 5 and 4 / 7 and these two fractions are two instances of class Fraction. (Note that Smalltalk class names always begin with a capital letter.)

A class thus defines the properties and the functionality (''behavior'') of its instances. The properties of an object are stored in its internal slots called instance variables and a class defines which instance variables its instances have; each instance of a given class thus has the same own instance variables with its own private values. As an example, every instance of Rectangle has instance variables origin and corner, and every fraction has its own numerator and a denominator as prescribed by the definition in class Fraction. The value of an instance variable of a given object may or may not change during its lifetime. As an example, when a window object is moved on the screen or resized, the instance variable that defines its bounding rectangle changes its value. The questions related to the fact that classes are objects are related to the very interesting but more advanced topic of metaprogramming that is not covered it in this introduction.
 
If you ever need to find the class of and object, send it the class message as in

3 class			"Execute with Print it or with Inspect it."
(3 @ 5) class
(Rectangle origin: (3 @ 5) corner: (25@30)) class

Exercise:
Note: When an exercise requires writing and evaluating code, I recommend using a separate Workspace.
1. What is the class of 3/5; the class of ''abc''? (Note: If you are not careful with your expression to determine the class of 3/5, you may get an ''exception'' and Smalltalk will open an Exception window. If this happens, close the Exception window, think about evaluation rules, correct your expression, and try again. We will deal with exceptions in more detail later.)

3. Use the Browser to view class definitions

Smalltalk''s tool for viewing, editing, creating, and destroying class definitions is called the Browser. VisualWorks provides several kinds of browsers and you can open them from the Launcher: Browse -> System or clicking the button with a baloon and glasses opens the most common Refactoring Browser. You can also open a browser by sending a message such as

SmalltalkWorkbench browseClass: Fraction

When you execute this expression with Do it, you will get a ''hierarchy'' Browser on class Fraction and its superclasses (to be explained shortly). However, using the Launcher button to open the System Browser is by far the most common technique because the browser is the most frequently used Smalltalk tool. The Browser is a very powerful tool that allows you to see and edit all code including, for example, the code that defines the Browser itself and this Workspace. The Browser is the tool that Smalltalk programmers use to create new applications. We will see how later.

Exercises:
1. Open the Browser window from the Launcher and look at the definition of class Fraction. To find it, execute Find in the <operate> menu of the upper left view/pane of the Browser.
2. Find all classes containing the word Integer. (Hint: Use the Find command with the pattern *Integer*.)

4. Understanding the Browser window

The System Browser is the most commonly used browser but other types of browsers have a similar structure. Its detailed description is given in On-line help and I will summarize its main features briefly in this section.

A Browser window has four list panes at the top and a text view at the bottom. The main roles and uses of these views are as follows:

The leftmost list pane at the top can be used to display either ''packages'' or ''parcels'' or ''categories''. Packages and parcels are mostly used to group together code related to a particular application or project. As an example, numerous extensions of the basic VisualWorks product are stored in your VisualWorks directory as parcels (and the easiest way to explore and load or unload them is via the Parcel Manager, which can be opened from the Launcher. I leave the concepts and uses of parcels and packages as an exercise. For our purpose, the most appropriate mode is to view categories and to display them, execute the Browser -> Category command from the menu at the top of the Browser.

The Category list displays all currently loaded classes grouped into disjoing categories. All classes are grouped into categories, each category contains related classes, such as classes defining geometric objects or classes defining numbers, and every class is in exactly one category. Categories are only a convenience feature, they help to make the class library which contains thousands of classes easier to understand. They don''t have any effect on program behavior.

In the rest of this section, I will assume that you have selected the Category view.

The second list from the left is the Class list. When you select a category, such as Magnitude-Numbers, this list displays all classes in this category. (It also displays namespaces - more about this later.) When you select a class, the contents of the rightmost two lists depend on the choice of tabs in the middle of the window. If you choose Source, you will see the definition of the class, and if you choose Comment you will see the description of the class (if one was written by the designers). The Hierarchy Diagram tab displays the hierarchical relationship between classes (more in a moment), Rewrite provides access to powerful facilities that perform certain automatic transformations of code (I will not cover this advanced feature), and Code Critic lets you perform numerous automatic checks for possible bugs, violations of certain stylistic conventions, and so on. I will not cover this feature but recommend that you explore it on your own.

The third list is the Protocol list. When you select a class, the contents of this list depends on the tabs above: Under Instance or Class it show shows method protocols defined for the instances of the class or for the class itself, under Shared Variable, it shows the class''s shared variables (more on this later). Protocols are groups of related methods and a method is the definition of a message. 

The purpose of method protocols is similar to that of class categories - they organize the potentially numerous methods defined in a class. As an example, a protocol might gather all methods that define arithmetic operations or all methods used for comparison of instances of the class. Protocols have no other purpose besides classification. To make class organization more readable, Smalltalk programmers use sevral conventional protocol names for uniformity and so should you, but you are free to choose any protocol name you wish. I will talk about common protocols later when presenting the most common classes.

The rightmost list is the Method list. When you select a protocol, this view shows the selectors (names) of all methods defined in this protocol.

The text (''code'') view at the bottom displays information that depends on the context. If you selected the Source tab, the possibilities are as follows:
- If you select a category but nothing else, the text view displays the template of a message that can be used to create a new class. I will explain how to use it in a moment.
- When you select a class, the text view shows the message that created the class. You can edit it to change the definition, for example, by adding new instance variables.
- When you select a method protocol, the text view displays a template to help you write a new method. I will show how later.
- When you select a method, the code view displays its Smalltalk definition; you can change it if you wish. Note: If all your source code does not show up in your Browser, you probably don''t have the correct ''home'' setting. The home setting is the file directory in which VisualWorks starts looking for files. To check the setting and correct it if necessary, go to the Launcher, open the File command in the menu bar, and click Set VisualWorks Home. The dialog explains that you should set this to the main directory containing your VisualWorks files, such as C:\vwnc5i.1\

Finally, each of the views discussed above has its own <operate> menu with its specific commnds. I will explain some of them as we need them and you can explore the rest on your own with the help of the general documentation.

Exercises: 
1. Which classes are defined in category Magnitude-Numbers?
2. What are the categories of Rectangle, Date, String? (Hint: Use Find method... in the category view to find the class.)
3. Which instance variables are defined in class Rectangle and what is the comment of the class?
4. Which protocols are defined on the instance side of class Rectangle? Which ones on the class side?
5. What is the definition of method corner: in class Rectangle and which protocol is it in? (Hint: Use command Find method... in the protocol view to find a method in the selected class if you don''t know its protocol.)
6. Smalltalk developers sometimes create class-side messages to give examples of class uses. These examples are usually gathered in a class protocol called examples. Find and evaluate the example methods in class Spline. The complete expression to evaluate the example message is given in the comment at the beginning of the method. (As an example, you will see that the expression evaluating example method demoFlatness is Spline demoFlatness.) Select it and evaluate with Do it.
7. To see all classes that contain protocol examples, evaluate the following with Print it or Inspect it:
Object allSubclasses select: [:aClass| aClass class organization categories includes: #examples]
Use this information to find and evaluate other example methods. 
(The expression above is an example of the use of Smalltalk''s reflectivity. One of its most important uses is the implementation of tools such as the Browser, the Inspector, and the Debugger (later).)

5. Class messages

As you know, classes are templates that define instance variables and messages understood by their instances; these messages are called instance messages. Because classes are themselves objects, they too understand messages. These messages are listed on the ''class side'' of the class definition in the Browser and are called class messages.To view them in the Browser select the Class tab above the protocol list.

Because classes are used mainly to create instances, most class messages are instance creation messages. Almost every class inherits (to be explained) and can execute message new to create an uninitialized instance of itself, where ''uninitialized'' means that the value of its instance variables is nil. (Object nil is the single instance of class UndefinedObject and represents an object that ''does not have a value''.)  As an example, evaluate the following with Inspect it and examine the instance variables of the returned object:

Rectangle new	"Message new is a class message because its receiver is class Rectangle."

In addition to understanding new, many classes define their own specialized instance creation messages that create initialized instances. As an example, inspect individually the following lines:

Circle center: 23 @ 12 radius: 15		"center:radius: is a class message - its receiver is class Circle. It returns an instance of Circle."
Time now							"now is a class message - its receiver is class Time. The result is an instance of Time in the current time zone. You can change the time zone via the File -> Settings command sequence in the Launcher."
Rectangle fromUser					"Lets you draw a Rectangle on the screen and returns the resulting Rectangle object."
Date today							"Read the comment of class Date to understand the meaning of its instance variables."

How can you recognize that center:radius:, now, fromUser, and today are class messages? If you are looking at an expression, the answer is that the type of a message can be determined from the nature of its receiver. Receivers of class messages are classes and class names start with a capital letter and this gives a strong hint. There are a few exceptions to this rule - as an example, Transcript is not a class although it begins with a capital letter. This is because capitalized names denote ''shared objects'' and classes are only one of several kinds of shared objects. More on this later. A sure way to determine whether a message is a class message or an instance message is to look it up in the Browser. You can also browse the definition from the  Launcher (Browse -> Implementors of Selector ...) - if the list is listed as class it is a class message, otherwise it is an instance message.

Exercise 
1. Find the definitions of the above instance creation messages. What is the name of their protocol?

Here is an example that combines a class message with an instance message:

Date today previous:	 #Monday	"today is a class message (receiver is class Date) and returns an instance of Date; previous: is thus an instance message because its receiver is the object Date today, an instance of Date."

It is not uncommon for a class message and an instance message to have the same name. As an example, message initialize is defined on both class and instance sides of several classes. This does not create any problems because the nature of the receiver determines which definition should be used - when the receiver is a class, the class-side method is evaluated, when the receiver is an instance, the instance-side definition is used.

Some class messages do not create instances but return information related to the class. As an example, use the Inspector to check the result of

Time millisecondClockValue		"Does not return a Time object - returns a SmallInteger."
Window platformName			"Does not return a Window object - returns a String."
Filename volumes				"Does not return a Filename object - returns a collection of strings."

Still other class messages initialize the class itself or perform various other functions such as execute examples.

Note that although most objects are created by sending an instance creation message to a class, some of the most common objects can be created as ''literal'' objects without sending a creation message. Several examples are

32		"An integer number literal."
41.3	"A floating-point number literal."
''abc''	"A String literal."
$x		"A Character literal - letter x."
true		"The single instance of class True."
false	"The single instance of class False."
nil		"The single instance of class UndefinedObject."

Exercise:
1. Many useful class messages are defined in class Dialog. Browse the definitions and execute the example code enclosed in comment brackets at the beginning of each of them with Print it.
2. There are expressions that one might mistake for literals. As an example, 4/3 is not a literal but an expression that sends message / to 4 and creates an instance of a Fraction. Similarly, 13@15 is an expression that creates a Point.

6. Class hierarchy - inheritance

Smalltalk classes are related to one another in many ways and one of the most important ones is inheritance - every class (except one, as you will see) has exactly one superclass and inherits its class and instance methods and variables from it. In other words, a class has all instance variables of its superclass (plus its own) and understands all its messages (plus its own). As an example, the definition of class Fraction extends the definition of its superclass - class Number. Fraction thus understands all methods defined in Number (plus its own) and its instances have all its instance variables (plus its own). (In fact, class Number does not have any instance variables so Fraction does not inherit any.) When you draw a diagram of classes and their superclasses in the form of a family tree, you will get Smalltalk''s class tree. The class on the top is class Object and this class is the only one that does not have a superclass. (When you examine its definition in the Browser, you will see that its superclass is nil).

If A is the superclass of B, and B is the superclass of C, C inherits from B and this includes everything that B inherited from A. C thus inherits everything from B and A. Inheritance is thus transitive and all classes ultimately inherit all behavior defined in the whole inheritance path ending in class Object. As a consequence, if you want to define a message that every object should understand, define it in class Object. Modifying ''base clases'' such as Object is not very common but it is possible.

To find the superclass of a class and its complete class hierarchy with all superclasses and subclasses, select the class in the Browser and click the Hierarchy tab above the category list. Note that you must not select a method protocol if you want to see the hierarchy. You can also ask a class what is its superclass as in

Fraction superclass

Message superclass is another example of Smalltalk''s reflectivity, and the reason why the Browser can display the class hierarchy.

Exercises:
1. List all superclasses of SmallInteger, Date, Rectangle, Object.
2. Message subclasses returns the collection of all immediate subclasses of the receiver, message allSubclasses returns the collection of all subclasses of the receiver down the class tree. Test these messages on class Number. (Note: These and related methods are defined in class Behavior.)
3. Evaluate Object allSubclasses size to find how many subclasses class Object has. The result depends on how many parcels you loaded and how many classes you added or deleted.

7. Classes can override inherited methods

An ostrich is a bird but it does not fly. In other words, ostrich ''redefines'' one of the behaviors that it inherits from its ''bird superclass''. A similar feat can be achieved in Smalltalk by overriding an inherited method definition by simply writing a new definition of the method in the class that should execute the message differently. Any class may redefine any of its inherited methods but cannot remove any inherited method or any of its inherited instance variables.

As an example of overriding, class Fraction inherits the definition of = but redefines it because equality has a special meaning for fractions. (Two fractions are equal if they satisfy a certain arithmetic formula relating their numerators and denominators.) This definition overrides the inherited definition and when you ask a fraction whether it is equal to another fraction, it executes its own definition of equality rather than the inherited one. This is because when you send a message to an object, its evaluation starts with a search for its definition in its class. If the class contains the definition, the definition is evaluated, otherwise the search for the definition continues in the superclass, and so on, until a definition is found and executed, or the top of the hierarchy is reached and the definition is not found. If the definition of the method is not found, Smalltalk sends message doesNotUnderstand to the original receiver, and this creates an ''exception'' object an, by default, opens an Exception window. (The default behavior can be overridden.) To see an example of an exception created when a message sent to an object is not found in the path from the class of the receiver to the top of the hierarchy in class Object, evaluate

13 asUppercase

with Do it. You will get an Exception window because neither the class of the receiver (SmallInteger) nor any of its superclasses understand asUppercase, which is defined in class Character on a branch from Object that does not lead to integers. Click Terminate in the Exception window to terminate evaluation. We will see later how you can handle exceptions programmatically.

Finally, the Browser puts an up- or down-pointing triangle in front of methods with other definitions above or below the current class. The method view''s <operate> menu allows you to open a special browser on their definitions.

Exercises:
1. Which class defines the = method that Fraction inherits?
2. Find all implementers of methods  asUppercase, fromUser, <, and printOn: using the Browse -> Implementors of .. command in the Launcher. Which of these definitions override inherited methods?
3. When Smalltalk programmers want to make it impossible for an object to execute an inherited message, they define its body as shouldNotImplement. Use the Launcher to find all references to this message to see how this is done. Try what happens when you send a ''forbidden'' message as in

Fraction new	"Clas Fraction ''forbids'' message new"

8. Abstract classes

Inheritance is great for avoding duplication of code. (Duplication is bad not only because it means extra work, but because it is dangerous - if you change something and forget to change even one of the copies, your application may fail to work.) As an example, if you need classes such as SavingAccount, CheckingAccount, and SpecialSavingAccount, many of the methods (such as deposit and withdraw) and many of the instance varibales (such as accountNumber, owner, balance) are probably needed in all three classes. To avoid duplication, define  Account as a superclass of these three classes, and include all the shared instance variables and methods in it. The three subclasses will not have to redefine them, unless they require different behavior.

Our banking application will never instantiate Account because Account is just a general concept with no real counterpar - only instances of the three subclasses are meaningful. Because Account is never instantiated, it is called abstract whereas SavingAccount, CheckingAccount, and SpecialSavingAccount are concerete because they are designed to be instantiated. VisualWorks class hierarchy contains many abstract classes and class Object at the top of the hierarchy is itself abstract.

Note that there is nothing in Smalltalk that marks a class as abstract - the distinction is only a design feature in the mind of the designer and there is nothing to prevent the user from treating an ''abstract'' class as concrete. As an example, although Object is abstract you can instantiate it - inspect

Object new

It does create an instance even though you would rpobably never want to do that.

Some abstract classes take precautions against creating instances as a protection from misuse. As an example, class ArithmeticValue redefines new as

new
	"Numbers should be created only through arithmetic operations."
	^self shouldNotImplement	"The special word self refers to the receiver of the message, in this case class ArithmeticValue or one of its subclasses."

(Don''t attempt to evaluate this code, it''s not a code fragment but a method definition.) As a consequence of this definition, executing

ArithmeticValue new

produces an exception. Because ArithmeticValue is the superclass of all number classes, they all inherit this definition and refuse to execute the new message. As an example,

Fraction new

also opens an Exception window.

One of the typical features of abstract classes is that they contain methods that are redefined in all their subclasses. The abstract class defines these methods essentially as markers that serve as reminders that the concrete subclass must define them. As an example, all numbers are supposed to understand multiplication, but most number classes implement it in a special way. Class ArithmeticValue thus ''implements'' multiplication as

* aNumber 
	^self subclassResponsibility

If you defined a new subclass of ArithmeticValue,  forgot to define message *, and tried to multiply your new number, you would get an Exception window telling you that the class was supposed to implement this message but didn''t. This is the result of message subclassResponsibility.

Besides serving as a marker, ''abstract'' methods also make it possible to define additional methods that can be inherited without redefinition. As an example,  abstract class Magnitude is the superclass of all classes whose instances require comparison. It defines <  as an abstract method (subclass responsibility) and then defines all other comparisons (such as <=)  in terms of < and other methods. As a consequence, subclasses need not redefine < and <= still works, as long as the class defines its own version of < (or inherits it).

Exercises
1. Find all references to subclassResponsibility and explain why they are needed.
2. Explain in detail when you execute 3 <= 4.


Part 4. Creating and Editing Methods and Classes

1. Defining a new method or editing an existing one

Smalltalk programs consist of classes with methods and this part shows how to create and edit them. This section shows how to create a method. Because we start with methods, my example will use an existing class and add a new method to it.

To define a new imethod

- select the class in which the methods will be defined,
- select instance or class view in the Browser as appropriate,
- select a method protocol or create a new one using New... in the <operate> menu of the protocol view,
- write the method in the code view at the bottom of the browser , and Accept it.

To modify an existing method, use the same procedure but edit and Accept the existing text instead of retyping it.

As an example, assume that we want to define method to calculate the cube of a number. The method will be used as in

15 cubed

or

1.5 cubed

The method is an instance method because we send it to concrete numbers, instances of various number classes. Clearly, the message should be understood by all types of numbers, just like method squared. The logical class to put it in is thus where the squared method is defined, instance protocol mathematical functions in class ArithmeticValue. (To find this, I browsed implemetors of squared from the Launcher.) The definition (explained below) will be as follows:

cubed
	^self * self * self

Type (or copy and past) the text into the code view on the instance side and mathematical functions protocol of class ArithmeticValue and click Accept in the <operate> menu. If you have not made any mistakes, this will compile the code and the protocol list will now display the selector cubed and the method will be added to the library. (To make sure that the new method is saved in the ''image file'' when you quit VisualWorks, use File -> Save in the launcher either now or later, or save on exit. If you exit VisualWorks without saving, all work done since the last save is lost because the image file doesn''t change automatically.) 

Test that the method works, for example by evaluating

3 cubed

- 3 cubed

and

(3.55) cubed

Notes:
- Method cubed is now available to all numbers because it is defined in the abstract supeclass ArithmeticValue, the superclass of all number classes. This is what abstract classes are for.
- The word self in the body of the method refers to the receiver. As an example, in 3 cubed, self is 3, and 3.14  is self in the execution of 3.14 cubed.
- The return operator ^ in the definition means ''execute the following expression and exit from this method returning the result of the expression''. If a method does not contain the return operator, it returns the receiver, which is OK if you want to return the receiver or don''t care about the returned object. To see the effect of not including the return operator, remove the ^ from the definition of cubed and run the tests again. Forgetting the return operator is a very common mistake.
- If the code does not work quite as you expected or if you want to make cosmetic changes, open the method, edit the text, and Accept again. You can also make corrections at run-time with the Debugger (below).
-  Some people like to format (indent, etc.) their code manually as they type. I prefer to ignore formatting as I type and use the Format <operate> menu command in the method''s text view to format the code automatically before trying Accept. Format first checks the syntax of the code and formats it if there are no syntax errors. In summary, my technique is

-  type or edit the code
-  Format and correct if necessary
-  Accept
-  test

Developers using Extreme Programming''s ''test-driven design'' write tests before they implement the method.

Exercises:
1.  Define unary method inc that returns its receiver incremented by 1. As an example, 34 inc should return 35.
2. Define unary method isPalindrome that returns true if its receiver string spells the same in reverse. As an example, ''aba'' isPalindrome should return true, but  ''abs'' isPalindrome should return false. (Hints: Use method reverse and don''t forget the return operator. Define the method in the most abstract class defining reverse.)
2. Define binary method +* that returns the sum of the receiver and the argument, all multiplied by the argument. As an example 3 +* 5 should return (3 + 5) * 5 or 40.
3. Define keyword method smallerThan:orGreaterThan: that returns true or false under obvious circumstances. (Hint: This method is the logical negation of message between:and: and the negation message is not.)
4. Define keyword method implies: that returns true for any combination of receiver true and false, except when the receiver is true and the argument is false. As an example true implies: true should return true, but true implies: false should return false. (Hints: Write a subclassResponsibility definition in class Boolean, and override it in class False and in class True. Don''t forget the return operator.)
5. Is there a method that inverts a number? If not, define one in the most appropriate class.

2. Debugging

Sooner or later, you will write code that compiles but does not work. The problem may have several causes. The two typical reasons are that you are sending a message to the wrong receiver, and making a mistake in the ''logic'' of your program. I both cases, when the problem is not obvious, you may want to use the Debugger, a very powerfull development environment described briefly below and in much more detail in On-line help. We will now look at the two possibilities.

If your mistake is that you are sending a message to the wrong object, for example asUppercase to a number as in

3 asUppercase	"Try it"

Smalltalk opens an Exception window that can be used to open the Debugger to see what is wrong. You can then correct the code and accept it in the Debugger as you would in the Browser (using the Accept command), possibly edit the data, and continue execution. Or you can terminate execution and correct your code in the Browser.

The most important part of the Debugger are as follows:

- The execution stack is the list at the top. It shows the methods waiting for completion (waiting for a returned object). The currently invoked method is at the top, the method that called it is below, and so on. The expression at which execution paused is highlighted. You can select any method in the list and continue with its execution inside the Debugger or proceed normally outside the Debugger, or terminate execution completely. There are several ways to continue in the Debugger and the two most important ones are to step ''into'' the current message sned which is pushed on top of the stack, or just step, in other words, let the message execute (invisibly) and proceed to the next message. These two actions are invoked by the two leftmost buttons above the list.
- The code view below the list shows the code of the selected method and highlights the current place of execution. Besides continuing execution as explained above, you can also modify the code, accept it as in a  Browser, and continue with execution from the start of the current method. There are many other possibilities and they are explained in On-line help.
- The bottom part of the Debugger contains two abbreviated inspectors. The one on the left shows the instance variables of the receiver, the one on the right shows the temporary variables and arguments of the method. If you wish, you can change their values (by selecting the item, typing in the new value, and accepting - or even by typing in and evaluating an expression to calculate the new value and accepting) and proceed without exiting or recompiling.

If your program is executing but the behavior is not as expected, the error is in the logic of the code. The first thing that you might want to do is to read your code and see if you can correct it. If you don''t see the problem but think that you know its approximate location, or a place where you might start searching for the problem, you can insert a breakpoint (usually a self halt statement). When execution reaches this point, Smalltalk will open an Exception window saying ''Halt encountered''and from here you can go to the Debugger. You can then continue executing the code step by step and find and correct the problem. As an example of the use of a breakpoint, evaluate the following faulty program and then correct the mistake iby uncommenting the self halt statement.

| price tax total |
price := (Dialog request: ''Please enter price'' initialAnswer: ''100'') asNumber.
tax := (Dialog request: ''Please enter price %''  initialAnswer: ''10'') asNumber.
"Insert self halt here to open an exception window."
total := price + (price * tax / 10).
Transcript clear;
	show: ''price: '', price printString; cr;
	show: ''tax: '', tax printString; cr;
	show: ''total: '', total printString

When you add the breakpoint and open the Debugger, select ''unbound method'' in the execution stack (it refers to the code from this workspace), and continue executing it using some combination of the methods explained above. When you find the problem, correct it directly in the Debugger and Accept the change.

Instead of using self halt statements as explained above, you can also create breakpoints more easily directly from the Debugger. The details are explained in On-line help.

Smalltalk programmers depend on the Debugger so much that some actually develop code with it and the Debugger provides means to make this easier.

3. Namespaces

Before you can start creating your own classes, you must first understand the concept of a namespace. As you already know, classes are grouped into categories. In a similar but completely independent perspective, classes are also collected in namespaces. Whereas a category is just an organizing principle with no effect on run-time behavior, namespaces have profound effect on execution.

To understand why VisualWorks has namespaces, consider a familiar analogy. My office phone number is 585-1467. If you call me from within my area, that''s all you need. However, if you are outside, for example in Toronto or in San Francisco, this number is either unassigned or belongs to another person; to reach me, you must put my area prefix 902 in front of the seven-digit code. And if you want to call me from Europe, you must put even more digits in front of that to select North America. The ''area code'' prefix of a phone number thus partitions phone numbers into unambiguous sets - one or more for Ontario, one or more for Montana, etc. - and allows the basic seven-digit codes to be assigned to many different people across North America with no confusion. The idea of namespaces implements exactly the same principle for Smalltalk classes.

A namespace is simply a way to get around the serious limitation of earlier versions of VisualWorks that required that every class have a unique name. This meant that code from different sources could only be combined if the sources did not define clases with the same class. If I wrote, for example, a library catalog program with a class called Book and loaded my program and the On-line Help parcel, my Book class would clash with the Book class that VisualWorks uses in On-line Help. In fact, one of the Book classes would overwrite and destroy the other and one application would stop working.

Namespaces partition class names and make it possible to name classes in one namespace without any regard for class names in other namespaces. Within one namespace, class names must be unique, but two different namespaces may contain classes with identical names without any conflict. As a consequence, if I put my Book class into my own namespace, called for example LibraryCatalog, VisualWorks doesn''t mind that there is another Book class in the VWHelp namespace and will not confuse one for the other because the other class is invisible to my namespace - unless I ''import'' the other namespace into it.

Namespaces are organized in a tree-like structure with namespace Root at the very top, namespace Smalltalk underneath, and other namespaces below Smalltalk. The structure of the namespace tree is relevant mainly for accessing a name in a different namespace and for defining your own namespaces: Should you need to access class Y in namespace X contained in namespace Smalltalk, you can use the dot notation as in Smalltalk.X.Y. (The mechanism is designed so that you can leave namespace Root out of these expressions.) Better still, you can import the required namespace or class by specifying it in the import: argument of the namespace definition message in the browser. We will use this feature in a moment.

As you see, the concept of namespaces is very important, but I am not going to explore it further except for giving a simple example of class creation, and refer you to On-line Help for details. An example showing how to create a new namespace is given in the next section.

Exercises:
1. Draw the whole namespace hierarchy of your class library. Note that its elements depend on the parcels that you loaded because parcels may add new namespaces. (Hint: There is probably a message that returns all subnamespaces of a given namespace. To find it, I used Find Implementors of Selector .. in the Launcher''s Browse command and specified *namespace* as the selector pattern. Among the many displayed options, I found message withAllNamespaces. I then tried Root withAllNamespaces and obtained a list of all namespaces of Root expressed in the dot notation explained above.
2. Namespaces form a namespace tree in the same way that classes form a class tree. Is the class concept of inheritance valid in the namespace tree? (Hint: See On-line Help or documentation.)

4. Creating a new class

To define a new class, you must know into which namespace and category to put it. If the namespace or the category do not yet exist, you can create them using the Browser. The next decision is to select the superclass of the new class. Because a subclass specializes (extends) the properties and functionality of its superclass, the superclass should be a class that serves a similar but more general purpose than the new class. As an example, Vehicle would be a reasonable superclass for Car if your application deals with several kinds of vehicles and each of them requires its own class, and Account is a good superclass of SavingsAccount if you have several kinds of accounts. If you can''t think of a suitable existing superclass , make your class a subclass of Object. This is the most common case. 

After deciding these basics, you must decide on instance variables and write and Accept the definition of the class in a browser. You should then add a comment to the class by selecting the Comment tab in the Browser, editing the comment template, and clicking Accept. Finally, create the necessary instance and class protocols and define methods. I will now demonstrate the procedure on a simple example.

Example: I want to create class Name with superclass Object in namespace Smalltalk.Test and category Examples. The class will have instance variables firstName (a String), middleName (a Character), and lastName (a String). Its protocols will include instance creation and instance variable accessing. The class is a simple ''data holder'' class, not a very good example from the point of view of class design, but almost the simplest example of class definition.

There is no namespace called Test within namespace Smalltalk so I must create it. In the Browser, select Class -> new -> Name Space from the menu bar and edit the code view template

Smalltalk defineNameSpace: #NameOfPool
	private: false
	imports: ''
			OtherNameSpace.*
			private Smalltalk.*
			''
	category: ''As yet unclassified''

s follows (note that I deleted the underlined word above)

Smalltalk defineNameSpace: #Tests
	private: false
	imports: ''
			private Smalltalk.*
			''
	category: ''As yet unclassified''

The imports: keyword gives my namespace access to all classes in namespace Smalltalk which, in turn, provides access to other very important namespaces and their classes.

I can now create the new class in the new namespace. To do this, select Class -> new -> Class from the menu bar and edit the template

Smalltalk.Test defineClass: #NameOfClass
	superclass: #{NameOfSuperclass}
	indexedType: #none
	private: false
	instanceVariableNames: ''instVarName1 instVarName2''
	classInstanceVariableNames: ''''
	imports: ''''
	category: ''As yet unclassified''

I again underlined the parts that you must edit. Note that the text is, in fact, a message to your selected namespace - you can read it as a command to the namespace Smalltalk.Test to create a new class called Name. (Because it is an ordinary message, you could use it even inside a program, thus creating a new class from a running program. The same, of course, holds for the creation of a namespace and even for categories, protocols, methods, and other items.) Edit the text as follows

Smalltalk.Tests defineClass: #Name
	superclass: #{Core.Object}
	indexedType: #none
	private: false
	instanceVariableNames: ''firstName middleInitial lastName ''
	classInstanceVariableNames: ''''
	imports: ''''
	category: ''Examples''

and click Accept in the <operate> menu. Smalltalk adds the Core. part in front of Object, creates the class, adds it to the library, and displays it in the Browser. It also creates the Examples category that I specified in the last line.

The next step is to write the class comment. With the new class selected, select Comment in the menu bar View command and edit the template, for example as follows:

Instances of this class represent simple person names.

Instance Variables:
	firstName		<String>
	middleInitial		<Character>
	lastName		<String>

The comment is, of course, only for documentation and has no run-time effect. It is, however, poor programming practice to neglect it because comments are very useful for understanding an unfamiliar class. Unfortunately, many of the classes in the library are not commented.

It is now time to write the methods. I will start with instance creation because I want to test everything as soon as possible and I can''t test any instance methods without reasonable instances. I could create instances with the new message and then assign values to instance variables by a sequence of cascaded ''setter messages'' as in

Tests.Name new firstName: ''John''; middleInitial: $C; lastName: ''LeCarre''	

asssuming that I have already defined firstName:, middleInitial:, and lastName:. However, I will assume that when my (fictitious) application runs, it gets names from a dialog window and so a Name will always be created with known components. I thus decided that my instance creation message should have the following pattern:

Tests.Name firstName: ''John'' middleInitial: $C lastName: ''LeCarre''

The new message firstName:middleInitial:lastName: is a class message because it creates an instance and its receiver is class Name. What should the message do? It must create a new instance of Name, send it an instance message to initialize the instance variables, and return the resulting initialized object. The definition is thus

firstName: string1 middleInitial: aCharacter lastName: string2 
	^self new
		firstName: string1		"This is the instance message to be written."
		middleInitial: aCharacter
		lastName: string2

Note the argument names: Smalltalk programmers prefer to use names that suggest the type (class) of the argument (such as aCharacter - indicating an instance of Character) because the keyword clearly identifies its role. This style helps future users of the method to use proper arguments when sending the message.

To define the method, create a new class-side protocol instance creation and define this message in this protocol by typing (or pasting) it over the method template text. There is no need for a comment because the purpose and logic of the method are obvious. (Smalltalk programmers generally avoid comments and try to write very clear code instead.) Click Format and Accept and the method appears in the protocol list. If you now tried to evaluate the Name-creation expression above, you would get an exception because you have not defined the instance message used inside our definition (try it). To define the instance-side method, go to the instance side of the Browser. Method firstName:middleInitial:lastName: simply assigns argument values to the instance variables and its definition is

firstName: string1 middleInitial: aCharacter lastName: string2 
	firstName := string1.
	middleInitial := aCharacter.
	lastName := string2

Put this code into instance-side initialize-release protocol, click Format and Accept, and test the new code by evaluating

Tests.Name firstName: ''John'' middleInitial: $C lastName: ''LeCarre''

with Inspect it to check that the new methods produce the expected result. (Print it does not produce anything interesting  until I redefine the operation of printString as Iexplained in Exercise 2 Try it.) 

Exercises:
1. Extend class Name by adding ''getters'' such as firstName (returns the value of firstName). Test them by creating a Name object and using the getters to print a description of the object in the Transcript.
2. Write a printOn: aStream message to make it possible to get printString to produce Name descriptions such as
a Name first name: ''John'' middle name: $C last name: ''LeCarre''
Test it by evaluating the above instance creation expression with Print it. (Hint: Look at the definition of other printOn: methods, for example in class Rectangle, and follow the same style. This kind of ''black box'' reuse of existing code is common.)
3. Create class Book in namespace Tests and category Examples. Book will have instance variables title (a String), author (a Name), and year (an Integer). It will have an initializing instance creation message and getters for all instance variables.

5. Shared and class instance variables

To complete this overview of foundations, I will now explain two new types of variables, less common in simple applications. They are class instance variables and shared variables.

Because classes are objects, they can have their own instance variables and although they are not really special, they have a special name. They are called class instance variables. There is really nothing unusual about them and they follow all rules of instance variables except that they are attached to classes rather than instances. In particular, if a class defines its class instance variables, they are inherited by its subclasses, and each of these subclasses has its own private values independent of other classes. As an example, if class Animal defines a class instance variable called Sound, then its subclasses Dog and Cat inherit Sound, but its value in Dog may be ''bark'', while the value in Cat may be ''meow''. As this example shows, class instance variables are used mainly for various constants. Note that instances of a class cannot access class instance variables directly just as a class cannot directly access instance variables of their instances; in both cases, access requires accessor methods. Class instance variables are relatively rare.

Whereas class instance variables are private to a class, it is sometimes useful to create objects that can be shared by several classes. As an example, many classes use various ''text constants'' such as the backspace character, the italic style of text, or the ''centered paragraph'' style of paragraphs. The kinds of variables discussed so far do not allow this sharing because their scope is limited. This is why VisualWorks has shared variables. These can be defined in a class (see the Shared Variable tag in a Browser) and accessed by the class and its subclasses or their instances, or even in a separate namespace. Two examples of class-based shared variables are Pi and RadiansPerDegree, both defined in classes Double and Float. An example of shared a namespace defined to hold shared variables is Graphics.TextConstants, which includes numerous constants divided into several categories such as Characters and Emphases. Shared variables are more common than class instance variables and they replace the concepts of  pools and class variables (not to be confused with class instance variables) used in earlier versions of VisualWorks.

Exercises:
1. Class SmallInteger defines class instance variables. Examine their definition, values, and accessors. 
2. Examine 20 randomly selected class definitions and count how many of them include class instance variables.
3. Study the Graphics.TextConstants namespace, its categories, and some of its shared variables. Browse references to shared variable CR and explain why only a shared variable can provide this scope of access.

This completes the introduction to Smalltalk principles. In the next part, I will introduce the essential Smalltalk classes and explain some additional principles.


Part 5: Essential Classes and Methods

Although learning Smalltalk certainly does not require knowing all classes in the library, you cannot write Smalltalk code without knowing about the fundamental classes such as those implementing numbers and strings. Introducing these base classes is the subject of this part of the Introduction. Additional important classes are described later in this tutorial and On-line help and the official documentation provide much additional information. Once you start using Smalltalk, you will quickly learn the other classes that you need most often. 

1. Class Object

Because Object is the superclass of all classes, all classes inherit all its methods. Some of the most common ones and their protocols are introduced below.

printing
- printString - converts its receiver to a string object using the printOn: method. Use it when you need a string representing an object, for example, to print in the Transcript with the show: message as in

Transcript show: (5 * 3) printString

or in dialogs as in

| price |
price := 100.
Dialog warn: ''The price is '', price printString

The basic definition in Object is not very useful because it essentially only returns the name of the class. If you define a new class and want printString to produce more specific information, you must define your own printOn: method. To do this, follow one of the many examples in the class library.

comparing for equality and equivalence (identity) - returns true or false
= checks whether the receiver and the argument are equal in some programmer-defined way
== checks whether the receiver and the argument are equivalent - one and the same object.

To see the difference between equality and equivalence, consider two Book objects defined by the programmer to be equal when they have the same author and title. Two books with the same author and title but a different publisher will then be equal but not equivalent (identical). As another example, evaluate

| p1 p2 | 
p1 := (Point x: 10 y: 20). 
p2 := (Point x: 10 y: 20). 
Transcript clear; show: (p1 = p2) printString.	"true - two points whose x and y are equal because Point defines = that way." 
Transcript cr; show: (p1 == p2) printString	"false - these are two equal but distinct objects." 

For many objects = and == give the same result because Object defines = to be the same as == and many classes don''t override this definition. But don''t take = and == for granted because sometimes they don''t give intuitively obvious results. As an example

''abc'' = ''abc''		"true"
''abc'' == ''abc''	"false"

Finally,

~= means not equal
~~ means not equivalent

Conclusion: If you define a new class and are not satisfied with the inherited definition of =, redefine it.

copying methods make copies of the receiver and create a new object of the same kind as the receiver. The exact relation between the receiver and the copy depends on how certain methods are defined (''copying semantics'') as I will show next.

The two main methods in this protocol are copy and postCopy. Method copy first makes a ''shallow copy'' of its receiver and then sends a postCopy message to it to perform any other desired copy operations. The definition of postCopy in Object does not do anything, but many classes redefine postCopy to perform their customized copying operations. Misunderstanding the copy operation is a frequent cause of strange program behaviors and I will now explain it in more detail.

Assume the following classes:

Book
- has some instance variables including borrower, an instance of Person

Person
- has some instance variables including homeAddress

Assume that Book does not redefine postCopy. If you take a Book object and make a copy, you will get a ''shallow copy'', a new Book object whose instance variables have the values of the instance variables of the original. In particular, the borrower of both books will be the same Person object. If you now change the address of the borrower of the copy of the original book, the original book''s borrower''s address will also change, because the borrower objects of the original and the copy are one and the same object and you have just changed this object''s address. The same thing, of course, happens if you change the original''s address - the copy''s address will also change. If you do not desire this behavior, redefine postCopy in class Book accordingly. For examples, browse some implementors of postCopy. In essence, a ''deeper'' copy will require that you define postCopy to create copies of instance variables to the desired depth.

We will see several other Object methods later. As a rule, whenever I say that you can use a message with any object, the implication is that its definition is in class Object. Three examples of such messages universally understood messages that we have already encountered are class, halt, and inspect.

Exercises:
1. Read the definition of method = in class Object.
2. Find all classes that reimplement =.
3. An interesting method defined in Object is isMemberOf: It takes a class name as its argument and returns true if the receiver is an instance of the argument class. Try 3/5 isMemberOf: Number,  3/5 isMemberOf: Fraction and comment on the result.
4. Message isKindOf: is related to isMemberOf:. Read its definition in the Browser and try 3/5 isKindOf: Number,  3/5 isKindOf: Fraction. Explain the commonalities and differences between the two messages.
5. Message respondsTo: aSymbol answers true if the receiver understands the message whose selector is aSymbol. Try 3 respondsTo: #squared, 3 respondsTo: #asUppercase, 3 respondsTo: #blaBlaBla, and ''abc'' respondsTo: #+. Find at least three references to this message in the library.
6. Read the definition of copy and postCopy in Object. Then read the definition of postCopy in Rectangle and explain its effect. Draw a diagram showing the original and its copy.
7. Find the definition of method browse and give an example of its use.
8. Class Object defines many messages. To see how many instance, evaluate Object selectors size with Print it.

2. Number classes

Smalltalk''s number classes include integers, floating-point numbers, fractions, fixed-point numbers (fixed number of decimal digits), complex numbers (extension of the basic library in parcel ATMetaNumerics), metanumbers (same parcel including infinity and other unusual but useful kinds of numbers), and others. Numbers define the obvious protocols for arithmetic and mathematical functions. Check them out, for example, in class ArithmeticValue and try the following examples with Print it, carefully considering the effect of evaluation rules on the order of calculation:

3 + 7 / 3					"A message from the arithmetic protocol."
(3 + 7 / 3) asFloat			"asFloat is in the converting protocol."
(3 + 7 / 3) asFixedPoint: 2	"asFixedPoint: is also in the converting protocol."
Float pi asRational			"Also in the converting protocol."
15 log						"log is in mathematical functions."
0.3 sin						"sin is in mathematical functions."
1000 factorial				"Protocol factorization and divisibility."
37 raisedTo: 22				"raisedTo: is in mathematical functions."

Some of the interesting aspects of number classes include the fact that all numbers are instances of classes (unlike most other languages where they are special data types and thus subject to different rules than objects), that they perform automatic conversions between ''large'' and ''small'' integers, and that you can extend their protocols - because they are objects (you did define the cubed method in an earlier example).

Exercises: 
1. What are the classes of the results of the above expressions?
2. What do you consider to be the three most important instance protocols of number classes?
3. What are the differences between Float, Double, Fraction, and FixedPoint?
4. What are some possible uses of FixedPoint? (Hint: Read the class comment.)
5. Create an instance of FixedPoint with two decimal digits. (Hint: See the class comment.)
6. What do you consider the most useful class message in class Float? How is its implementation in Double different?
7. Are there any senders of message factorial? What about the other messages in the same protocol?
8. Define methods calculating the following in the appropriate number classes: test for primality, Fibonacci numbers, radius and angle for complex numbers, testing for perfect square, testing for primality.
9. Draw the complete class tree of number classes.

3. Strings, characters, symbols, text, dialogs

A string is an indexed collection of characters and understands numerous messages for concatenation, substring insertion, searching, and other useful operations.  Most of the methods commonly used with strings are defined in String and its superclass CharacterArray, but many are inherited from the collection superclasses of String. Class String itself is an abstract class and factors out shared behaviors of several different implementations of strings.

As an example of string messages, evaluate each of the following lines with Print it:

''abc'' < ''xyz''
''abcdefg'' findString: ''de'' startingAt: 1	"Elements of String and other indexed collections begin at index 1."
''abcdefg'' size

To see the nature of string objects, evaluate the following with Do it and examine ''elements''

''abc'' inspect		"What is the class of this string?"

Exercises:
1. List three useful string processing messages defined in the superclasses of CharacterArray and write an expression using each of them.
2. Write an expression to convert ''a big bear'' to ''a big black bear''. (Hint: Check protocol ''accessing'' in String.)
3. A String is often created as a literal (such as ''abc''), or with the new: message as in
String new: 16
This creates a String with no characters in it but room for 16 characters. Inspect this object and note its class and explain.
4. Read the definition of method withCRs and use it to print a multi-line message in the Transcript.
5. What is the difference between = and match:?

Individual elements of strings are instances of class Character. Characters are usually created as literals as in (Inspect it)

$a
$3

or by a class-side instance creation message such as

Character cr
Character esc

You can also create a character from its numeric code as in

80 asCharacter		"Character from its ASCII code."

Class Character is a subclass of the abstract class Magnitude (as are Date, Time and other ''comparable'' objects including all number classes) and as such its instances can be compared as in

$a < $d

Exercises: 
1. Explore character creation messages.
2. Explore the testing, converting, and comparing protocols of class Character.
3. Class Magnitude is an abstract class gathering all behaviors meaningful for comparable objects. All its methods are derived from three methods left as subclass responsibility. What are these three methods and how are the other methods derived from them? Note that due to inheritance, subclasses of Magnitude only have to define these three methods and inherit all the other functionality, thus saving many redefinitions and enforcing consistency.
4. Use <= with strings, dates, time objects, and numbers (all instances of Magnitude subclasses).
5. Define method asString that returns a String with the receiver character as its only element. As an example, $a asString should return ''a''. Use the with: instance instance creation message.
6. Define method dayToday such that Date dayToday returns the name of the day today as a String. As an example, Date dayToday might return ''Monday''. (Note: The method that you will need returns a Symbol such as #Monday. Convert it to a String via asString. Symbols are covered in the next section.)
7. Define method hourNow such that Time hourNow returns the integer hour of the current time. As an example, Time hourNow might return 7 or 15 for a.m. and p.m. time respectively.

Symbols (instances of class Symbol, a subclass of String) are just like strings but their instances are unique whereas strings are not. To see the difference, try

''abc'' = ''abc''
''abc'' == ''abc''	"These are two different String objects that happen to have the same value."

and

#abc = #abc
#abc == #abc	"Because symbols are unique, this returns true."

Some messages require Symbols as arguments, usually when the arguments are names of methods. Because of this, Symbol system primitives protocol includes selector-related messages such as

#+ isKeyword				"Tests whether + is a keyword message."
#between:and: keywords		"Extracts keywords from selector between:and:"

and others. An interesting message that requires a Symbol as its argument is perform: and its relatives. This message is defined in Object and thus understood by all objects and it tells its receiver to evaluate the Symbol argument as a message. As an example,

3 perform: #factorial

tells 3 to evaluate factorial; it is thus equivalent to 

3 factorial

A typical use of perform: is to execute a message associated with a button in a window: The programmer can associate any message with a button (by naming it as a Symbol), and when the button is clicked, the action message is ''performed''.

Exercises:
1. Symbols are related to strings. Give the messages that convert one to the other.
2. Message isInfix checks whether a selector is a binary selector. Try this and other messages from protocol system primitives.
3. Evaluate expressions 3 perform: #+ with: 5 and 3 perform: #between:and: with: 7 with: 15. What does it do? Find the protocol defining perform: methods and comment on it.

Class Dialog contains many useful messages for obtaining data (mostly strings) from the user. All are class messages. Try the following with Print it.

Dialog request: ''What is your age?'' initialAnswer: ''20''				"Returns a string - no arithmetic possible!"
(Dialog request: ''What is your age?'' initialAnswer: ''20'') asNumber	"Returns a number - can do arithmetic."
Dialog 															"Returns selection given by the values: argument"
		choose: ''Which one do you want?'' 
		fromList: #(''first'' ''second'' ''third'' ''fourth'') 					"Prompt labels."
		values: #(1 2 3 4) 										"Corresponding return values."
		lines: 8 													"Number of lines displayed."
		cancel: [#noChoice]										"Value returned when user clicks Cancel."
Dialog confirm: ''Are you sure you want to delete the file?''			"Returns true or false"
Dialog warn: ''This is a warning''									"Returns nil - the UndefinedObject"

All these messages are derived from class SimpleDialog that defines some additional dialogs as instance messages. As an example,

SimpleDialog new
		chooseMultiple: ''Select all desired values''
		fromList: #(''first'' ''second'' ''third'' ''fourth'') values: #(10 20 30 40)
		buttons: #() 
		values: #()
		lines: 8
		cancel: [#noChoice]
		for: Dialog defaultParentWindow

returns multiple selections in the list.

Exercises
1. Message choose:... is in the ''multiple choice dialog'' protocol of Dialog and uses a list widget. Find and test two other messages defined in this protocol that use buttons. What are the advantages and disadvantages of each of these messages?
2. Examine dialog messages defined in class SimpleDialog.

A String is a relatively primitive object - a sequence of characters with no ''rendering'' information (font, color, size, etc.). Consequently, a String prints itself in the default font and default color. If you want to control the rendering of a piece of text, you must convert the string to a Text object and specify the emphasis of its characters. As an example,

ComposedTextView open: ''abc'' asText allBold asValue

opens a window with the specified text in bold. To display the text italicized, you can use

ComposedTextView open: (''abc'' asText emphasizeAllWith: #italic) asValue

You can also emphasize individual characters as in

ComposedTextView open: (''abcd'' asText emphasizeFrom: 1 to: 2 with: #underline) asValue

To combine several emphases, you must use an array (to be explained later) of emphasis values as in

| emphasis |
emphasis := #(#underline #italic).
ComposedTextView open: (''abcd'' asText emphasizeFrom: 1 to: 2 with: emphasis) asValue

The variable emphasis used above is not really necessary and I used it only to make the code more readable.

If you want to use color, you must specify it using an Association (created with the -> message and to be introduced shortly) as in

| emphasis |
emphasis := #color -> ColorValue red.
ComposedTextView open: (''abcd'' asText emphasizeFrom: 1 to: 2 with: emphasis) asValue

Exercises:
1. Examine some existing uses of Text and emphasis in the class library. (Hint: To find references to class Text, select the class and execute command References in its <operate> menu.)
2. Find references to text emphasizing methods.
3. Class ColorValue lets you create objects describing colors in various mixtures of red, green, and blue, or using other specification mechanisms. Many common color combinations such as red, salmon, yellow, and blue are predefined via class messages. Find these class messages and count how many different colors are predefined. Browse references to ColorValue and note that most of them refer to ''resources'' - definitions of user interface objects such as icons and windows.
4. Write an expression that opens a window with the following text: ABCDEFGhijklmnop.
5. Define methods allItalic and allUnderlined to emphasize all characters in the receiver Text as indicated. (Hint: Look at the definition of allBold.)

4. Class Boolean

Class Boolean is abstract and classes True and False are its concrete subclasses, each with a single instance: true and false respectively. Booleans are used mainly for control of flow of execution including conditional execution of a block of statements and conditional repetition. Try

(4 < 5) ifTrue: [Transcript clear; show: ''4 is less than 5'']			"The ifTrue: message. You can ge ''ifTrue:'' by pressing <Ctrl> t"
(4 < 5) ifFalse: [Transcript clear; show: ''4 is less than 5'']			"The ifFalse: message. Shortcut <Ctrl> f"
(14 < 5) ifTrue: [Transcript clear; show: ''14 is less than 5'']
(4 < 5) ifTrue: [Transcript clear; show: ''4 is less than 5'']			"The ifTrue:ifFalse: message - this and the following line constitute a single message."
		ifFalse: [Transcript clear; show: ''4 is NOT less than 5'']
(14 < 5) ifTrue: [Transcript clear; show: ''14 is less than 5'']
		ifFalse: [Transcript clear; show: ''14 is NOT less than 5'']

The square bracket construct containing statements is a block closure or simply a block. I will talk about blocks in a moment but for now, it is enough to know that evaluation of the statements in a block is delayed until it is explicitly requested by the definition of the message. As an example, the block following ifTrue: in the first example is evaluated only if 4 < 5 is true - because that''s how method ifTrue: is defined.

As in all programming languages, Smalltalk Booleans can be combined, as in

(3 < 4) & (5 < 6)		"logical AND"
(3 < 4) | (5 < 6)		"logical OR"
(3 < 4) not			"logical negation"

The & and | binary messages are ''fully evaluating'', which means that the argument is evaluated under all circumstances. (This is, of course, necessary because a message cannot be executed unless its arguments are known). The and and or operators also have ''partially evaluating'' versions in which the argument is only evaluated if necessary - because it is defined by a block:

(3 < 4) and: [5 < 6]		"The argument block is evaluated because the receiver is true, and the expression''s value thus depends on the value of the argument."
(3 > 4) and: [5 < 6]		"The argument block is not evaluated because the receiver is false, and the expression''s value is thus false no matter what is the value of the argument."
(3 < 4) or: [5 < 6]		"Argument must be evaluated."
(3 > 4) or: [5 < 6]		"Argument is not evaluated."
(3 factorial > 15) and: [3 squared > 50 or: [44 > 150 log]]	"Combines several logical operations."

The partially evaluating messages require a block argument because only a block argument gives the option to be evaluated or not.

Although the fully evaluating version may be easier to read, the partially evaluating versions with block arguments are generally preferred for two reasons: they may be faster because the argument does not have to be always evaluated, and they allow us to avoid evaluating an inappropriate or possibly even illegal operation as in

| x |
x := (Dialog request: ''Enter a number'' initialAnswer: ''10'') asNumber.
x > 0 and: [x log > 5]

If the user entered a negative number, attempting to evaluate the statement inside the block would cause an exception, but this does not happen because  the block will not be evaluated when x > 0. On the other hand,

| x |
x := (Dialog request: ''Enter a number'' initialAnswer: ''10'') asNumber.
x > 0 & (x log > 5)

will cause an exception for x <= 0 because the argument of & must be calculated before the message is sent, in other words, always.

Exercises: 
1. Construct an expression writing text to the Transcript to demonstrate that the ''partially evaluating'' version does not evaluate the block when not necessary.
2. Write an expression to determine whether a message selector is unary and print an appropriate message to the Transcript.
3. Read and explain the definition of ifTrue: in classes Boolean, True, and False.
4. What does an ifTrue: message return when its receiver is true? What does it return if the receiver is false?
5. Write a code fragment to read two numbers and test whether the first number is smaller than 5 and the second number''s square root is greater than 10.
6. Rewrite the previous exercise using only ifTrue:, ifFalse:, and ifTrue:ifFalse: messages, possibly nested.

5. Blocks

Blocks are instances of class BlockClosure. They are generally defined as literals using the square brackets syntax as in

[30 squared]
[Transcript clear. Transcript show: ''Hello'']

A block represents ''delayed execution'' of a sequence of zero or more statements, which means that the statements inside the block are evaluated only if the program explicitly requests it. To validate this, evaluate the above statements with Print it and Inspect it. 

To evaluate a block, in other words to execute the statements surrounded by the brackets, send it the value messages, as in

[30 squared]  value
[30 squared. 2 + 5]  value
[Transcript clear. Transcript show: ''Hello''] value
[:x | 3 + x] value: 5		"To be explained shortly."

Evaluate each of these three expressions with Print it and note that a block returns the object calculated by its last statement.

Blocks are very important and one of their most common uses is in iteration - repeated evaluation of a sequence of statements while a condition holds, does not hold, etc. To see iteration at work, study and evaluate the following code fragment:

| count |
count := 0.
[count < 100] whileTrue: [count := count + 1].					"Repeat iteration until the first block evaluates to false."
Transcript clear; show: count printString

The evaluation of the block argument in this example is triggered by a value statement inside the definition of the whileTrue: message. This definition is, of course, in class BlockClosure because the code shows that the block is its receiver. Study and evaluate also the following code fragments using different iteration messages:

| count |
count := 0.
[count squared > 100] whileFalse: [count := count + 1]. 		"Repeat iteration until the first block evaluates to true."
Transcript clear; show: count printString

| count |
count := 0.
[count := count + 1. count < 100] whileTrue.					"Note that this is a unary message."
Transcript clear; show: count printString

The following two forms of iteration do not use blocks as receivers (they are not defined in class BlockClosure), but I include them here because they are very common:

Transcript clear.
3 timesRepeat: [Transcript cr; show: ''Testing!'']

3 timesRepeat: [(Delay forSeconds: 1) wait. Screen default ringBell]	"Make sure to turn up your speaker first!"

Transcript clear.
1 to: 3 do: [:n | Transcript cr; show: n printString; tab; show: n squared printString]

The last block contains a block argument n. In this case, the argument assumes consecutive values of 1, 2, and 3 during the repeated evaluation of the block. That''s because the definition of to:do: uses the argument this way, not because of some magic. Some messages use blocks that require one or more arguments, others don''t have an argument - it all depends on what is needed and how the message is defined. 
Blocks may also contain internal temporary variables as in

Transcript clear.
1 to: 3 do: [:n| | square cube | square := n squared. cube := square * n.
			Transcript cr; show: n printString; tab; show: square printString; tab; show: cube printString]

The ''lexical scope'' (visibility) of block arguments and block temporary variables is limited to the block itself and identifiers n, square, and cube are thus undefined outside the block. If you have a choice, define your temporary variables inside your block rather than outside - this makes evaluation faster.

Exercises: 
1. Write a code fragment that repeatedly asks the user for a number and prints its square root in the Transcript. When the user enters a negative number, the program stops.
2. Message to:do: steps through its block argument values in increments of 1. Is there a method that allows you to specify the step? (Hint: The method is defined in the same class and protocol as to:do:)
3. Use the message from the previous exercise to write a code fragment that prints a table of x, sin(x), and cos(x) values in the interval 0 to pi in increments of 0.1.
4. Write a code fragment that displays a dialog with two choices - continue and stop. The program keeps redisplaying the dialog until the user selects stop.
5. Find, read, and explain the definition of message timesRepeat:
6. An interesting use of blocks is in the message millisecondsToRun: which takes a block as its argument. Read its definition, and use it to determine how long it takes to evaluate 10000 factorial on your computer. (Note: Be careful with interpreting the result because Smalltalk may perform garbage collection while executing the block and this will distort the measured time. Better ways to measure performance are available in the AT Advanced Tools parcels.)
7. The feature that determines whether a block argument has zero arguments (as in ifTrue:), one argument (as in to:do: above), or more than one argument is the kind of value message used to evaluate the block: if the block is evaluated with value, it must not have any block arguments; if it is evaluated with value:, it must have exactly one block argument, etc. Check the definition of ifTrue: and to:do: to see the difference

6. Collections

Classes defining various kinds of collections of objects are one Smalltalk''s greatest strengths. They include collections with indexed elements (array, ordered collection, sorted collection, string, and others), and unordered collections whose elements are not accessed by index (such as sets, bags, and dictionaries). Most collections are dynamic in that their size can change at run-time, but a few (Array and its subclasses) have fixed size. All indexed collections are indexed starting from 1. Almost all collections are heterogenous (can accept any objects as their instances) but a few are homogeneous (accept only certain kinds of objects). The following is a brief overview of essential collection classes followed by their main protocols:

Collection is the abstract superclass of all collections. It has no instances and its only purpose is to define everything that most collections share. For an abstract class, it defines quite a few methods that are essential for all collections. Its most important concrete subclasses are the following:
Array - indexed (as in all indexable collections, the first index is 1), fixed size (elements cannot be added or removed, only their values can change), very efficient in operation, automatically checks that index is within bounds and raises an exception if not. Often created as a literal as in (inspect)

#(10 20 30 $a $b $c ''abc'' 3.14 #symbol true)

The elements of a literal array may be any literal objects, including other literal arrays.

All the following collections are dynamic in size - elements can be added and removed at any time and without limits, and the amount of allocated space automatically grows when the current capacity is filled. The mechanism that allows growing makes them less efficient for accessing than arrays.

OrderedCollection - similar to Array but variable in size. The protocols are somewhat different.

SortedCollection - subclass of OrderedCollection that automatically sorts its elements using a sort block. By default uses sort block

[:element1 :element2 | element1 < element2]

to decide whether element1 should be located before element2 or not and elements are thus sorted in ascending order by default. But the program can define any sort block, even during the lifetime of the collection, thus resorting the collection automatically:

#(1 2 3 4 5 6 7 8) asSortedCollection: [:x :y| (x rem: 4) < (y rem: 4)]	"What is this? Predict and try."

Set - unordered collection, no index, automatically eliminates duplicates on the basis of equality. Try

#(1 1 1 2 2 2 3 3 3) asSet

IdentitySet - same as Set, but uses identity instead of equality to test for duplication; faster, because identity check is faster than equality check. Preferable to Set unless equality is required.

Dictionary - a Set of ''associations'', where an Association is a key-value pair usually created with the -> binary message as in

''maison'' -> ''house''	"Entry in an French - English dictionary. Evaluate with Inspect it."
''ADD'' -> 2r00001101	"Possibly a translation of an assembly language mnemonic to its binary equivalent. Note the syntax of the binary value."

Strictly speaking, elements of Dictionary do not have to be associations but must understand the Association protocol; in reality, they are practically always associations. To see the internals of a Dictionary,  Inspect 

Dictionary new add: ''CRT'' -> ''Cathode Ray Tube''; add: ''SSI'' -> ''Small Scale Integration''; yourself

Inspect the following example to see that duplication is eliminated on the basis of equality of keys - the first entry is overwritten by the second:

Dictionary new add: ''key1'' -> ''old value''; add: ''key1'' -> ''new value''; yourself		"key1 now has new value."

I will explain the purpose of yourself in a moment.

Both the key and the value may be any objects, including collections such as arrays or other dictionaries. Since dictionaries are collections with special elements (associations) their protocol is somewhat different from that of other collections.

IdentityDictionary - similar to Dictionary but uses identity to test duplication. More efficient than Dictionary because identity testing is faster. To see the difference between Dictionary and  IdentityDictionary inspect

IdentityDictionary new add: ''key1'' -> ''old value''; add: ''key1'' -> ''new value''; yourself		"Two entries with ''key1'' "

and compare with the expression above.

Bag - like Set, but knows how many occurrences of an element are present. Inspect It and explain

#(1 1 1 2 2 2 3 3 3) asBag

Interval - is a compact representation of an arithmetic progression, a sequence of equally spaced numbers:

Interval from: 3 to: 9				"Represents sequence 3, 4, 5, 6, 7, 8, 9"
Interval from: 3 to: 9 by: 1 / 2		"Represents what?"

The main protocols shared by all collections are

creation: typically use new, new:, and various forms of with: as in

Array new: 5
OrderedCollection new
Array with: 3 factorial with: 5 factorial with: 23 factorial

accessing: different kinds of collections use different accessors and only the following two methods are shared:
capacity - returns the number of ''slots'' in the collection.
size - returns the number of filled slots - the number of elements in the collection.
To see the difference, evaluate the following with Do it and explain the result:

| oc |
oc := OrderedCollection new: 10.
oc add: 10; add: 20.
Transcript clear;
	show: ''capacity: '', oc capacity printString; cr;
	show: ''size: '', oc size printString

Accessing of arrays uses getter at: and setter at:put: as in

| array |
array := Array with: 11 with: 22 with: 33.
Transcript clear;
	show: ''element at index 2 is '', (array at: 2) printString; cr.
array at: 2 put: 20.
Transcript show: ''new element at index 2 is '', (array at: 2) printString

OrderedCollection often uses first and last, and removeFirst and removeLast for accessing. The second pair of messages returns the same object as the first pair, but removes the object at the same time. Methods in adding and removing protocols (explained below) are frequently used to fill an OrderedCollection.

Dictionaries are special and use their own accessors. Check them out in the Browser.

converting: Converting one kind of collection into another - examine the result of

#(''abc'' ''AAA'' ''xyz'' ''123'' ''def'') asSortedCollection					"Use Inspect It or Print It. The receiver is a literal array."
#(1 1 1 3 5 6 6 2 2) asSet
#(''abc'' ''AAA'' ''xyz'' ''123'' ''def'') asSet asSortedCollection asArray		"Eliminates duplication and sorts an array."

adding and removing: These messages only apply to collections that can grow; as a consequence, they cause an exception for arrays. The main messages are add: anObject, remove: anObject, and remove: anObject ifAbsent: aBlock (used if you are not sure that anObject really is in the collection). A peculiarity of all these messages is that they return the argument, not the collection itself. So

| names result |
names := OrderedCollection with: ''John''.
result := names add: ''Wayne''.
Transcript clear; show: result

adds ''Wayne'' to names, but the add: message returns ''Wayne'', not the changed collection - so that the fragment prints only the name. To obtain the collection, cascade add: with message yourself as in

| names result |
names := OrderedCollection with: ''John''.
result :=  names add: ''Wayne''; yourself.
Transcript clear; show: result printString

The remove: messages also return the argument to be removed. To see the difference, evaluate the following two fragments with Do It

| names |
names := OrderedCollection with: ''John''.
names add: ''Wayne''; add: ''James''.
names remove: ''Wayne''

and

| names |
names := OrderedCollection with: ''John''.
names add: ''Wayne''; add: ''James''.
names remove: ''Wayne''; yourself

This peculiarity of adding and removing messages applies to other collection accessors as well and is a source of frequent mistakes, even by experienced Smalltalk programmers. 

Finally, read, predict, and test the following code fragment:

| names |
names := OrderedCollection new.
names 	add: ''John'';
		add: ''Robert'';
		add: ''Wayne'';
		add: ''James''.		"We don''t need yourself here because our goal is to update names, which the cascade does."
Transcript clear; show: ''Full collection: '', names printString.
names remove: ''Wayne''.
Transcript cr; show: ''After removing Wayne: '', names printString

OrderedCollection can also use addLast:, which is equivalent to add:, and addFirst:

In Dictionaries the argument of add: is an Association, and remove: and remove:ifAbsent: are illegal - use removeKey: and removeKey:ifAbsent: instead. Inspect

| dictionary |
dictionary := Dictionary new
	add: ''overdo'' -> ''do to death, go to extremes'';
	add: ''overheated'' -> ''agitated, excited'';
	add: ''playmate'' -> ''buddy, companion'';
	yourself.
dictionary removeKey: ''overdo''.
dictionary

enumeration: Methods in this very useful protocol access individual elements of the collection and do something with each of them. This is perhaps the most interesting of all collection protocols and its methods work with all types of collections, although dictionaries require some attention, as usual. To explore the main enumeration methods, all of them regularly used by all good Smalltalk programmers, explain the following and evaluate with Do it

Transcript clear.
#(1 2 3 4) do: [:element| Transcript show: element squared printString; cr]

and the following (line-by-line) with Inspect or Print it

#(1 5 2 89 34 53) select: [:element| element > 28]
#(1 5 2 89 34 53) reject: [:element| element > 28]
#(1 5 2 89 34 53) collect: [:element| element > 28]
#(1 5 2 89 34 53) detect: [:element| element > 28]		"Returns the first element satisfying the condition."
#(1 5 2 89 34 53) detect: [:element| (element rem: 3) = 0]	ifNone: [Dialog warn: ''No such element'']

I suggest that you read the definitions of these and other enumeration messages in class Transcript.

For dictionaries, enumeration messages work on association values rather than associations themselves and additional enumeration messages work on keys and associations.

testing: Mainly test whether a collection contains an element and return true or false. Try

#(1 2 3 4 5) includes: 4									"Test for presence of a specific object."
#(-2 3 4 -5) contains: [:number| number squared > 50]	"Test for presence of an element satisfying a test."

Two very frequently used testing messages are isEmpty and isNotEmpty.

Exercises: 
1. Write an expression to sort an array of numbers in descending order of magnitude. Repeat to sort an array of strings in reverse alphabetical order.
2. Write an expression to convert a string so that its characters are arranged in alphabetical order. As an example, ''cat'' should become ''tca''. (Hint: You may find it useful to use message withAll:)
3. Examine, explore existing uses, and test messages in the conversion protocols of collections.
4. Examine the enumeration protocol of Collection and its subclasses and list and explain additional enumeration methods.
5. Read and explain the definition of yourself. Find several of its uses in the library.
6. Examine the protocols of Dictionary and IdentityDictionary paying special attention to adding, removing, and enumeration - these protocols are somewhat different from those of other collections.
7. Find all senders of isEmpty and explore a few uses.
8. Write an expression to return all integers between 3 and 51 that are divisible by both 3 and 7. Use the most suitable enumeration message. (Hint: Use Interval.)
9. Repeat the previous exercise but return integers that are not divisible by both 3 and 7.
10. Write an expression to return the squares of all integers between 3 and 51 that are divisible by 3 and 7. 
5. Define method allButFirst that returns the collection of all elements of the receiver except the first one. As an example, #(1 2 3) allButFirst should return #(2 3).
6. Define method sameSizeAs: aCollection to return true if the receiver and the argument collections have the same size.
7. Define method equalElementsAs: aCollection to return true if the receiver and argument collections'' elements are equal. It should work for all sequenceable collections.
8. Write an expression to compare the speed and the differences in operation of = and equalElementsAs:.
9. Define method + to add together pairs of elements of two sequenceable collections of equal size. As an example, #(1 2 3) + #(10 20 30) should return #(11 22 33). Ignore possible error conditions.


Part 6. Other Important Classes

This part of the introduction covers the fundamentals of the following additional classes

- ExternalStream and Filename - used with files and directories.
- BinaryObjectStorage (BOSS) - save objects in files and retrieve them.
- Exception and its subclasses - deal with exceptional behavior such as division by 0 or out-of-bounds access of arrays.

1. External streams, files, and binary object streaming service (BOSS)

The following presentation focuses on the use of files to store your application''s objects in files and read them back. It presents basic storage-related classes in the following order: Class Filename provides the interface between VisualWorks and the file system of your computer. External stream classes implement mechanisms to open files, read or write them byte-by-byte, and perform other file operations. The BOSS group of classes can store objects in files and read them back using external streams created over filenames. You will see that basic object storage and retrieval requires only a few messages and is very simple.

Class Filename provides unified platform-independent access to files and directories. Because file systems are platform-dependent, Filename is an abstract class and the real work is implemented by its concrete subclasses. This dependency is hidden because when you send a message to create a Filename object, the method creates an instance of the default concrete class for the current platform. The following are the essential Filename protocols and methods and a few examples of their use:

instance creation

A Filename (a file or a directory) is created with message named: aString where aString is the name of the file as in

Filename named: ''notes.txt''	"Refers to an existing or non-existent file in the current directory but does not create it."

You can also create a Filename object from a String with asFilename as in

''C:\VW5i.4\help\notes.txt'' asFilename	"Example with complete file access path."

Class-side utilities protocol provides a number of useful methods such as

Filename filesMatching: ''*.st''		"Return the names of all files in the current directory matching the argument."

Filename volumes	"Return the names of all reachable disk volumes (disk drives)."

Class-side constants protocol provides access to platform-dependent conventions as in

Filename separator	"Return this platform''s separator in file path. Frees code from the platform-dependent syntax."

This and related methods make it possible to write code that can run on any platform.

Protocol defaults provides access to the current directory, as in

Filename currentDirectory	"Return the Filename representing the current directory."

and other information. The following are Filename instance-side protocols:

Protocol utilities provides access to file creation and other dates, its contents (without having to open or close the file), and so on, as in

contentsOfEntireFile		- return the contents of the file as a String. Does not require opening and closing the file.
dates	- return Dictionary with file access dates; contents depend on the platform.

file utilities contains numerous useful methods for operations on the underlying file including

fileSize					- answer the integer size of the receiver file in bytes
directoryContents		- return the contents of the receiver, presumably a directory
copyTo: aFilename		- copy receiver''s contents to aFilename without affecting the receiver
delete					- delete receiver Filename (a file or a directory)
makeDirectory			- create a subdirectory of the current directory 
moveTo: aFilename		- copy receiver to destination aFilename and delete receiver
renameTo: aFilename	- rename receiver, possibly resulting in a move to another directory 
makeWriteable			- make receiver a writeable file
makeUnwriteable		- make receiver a read-only file

converting

asString	- answer the file''s or directory''s name

testing

exists		- does the receiver file or directory exist?
isWriteable	- is the receiver file or directory writeable?
isDirectory	- is the receiver a directory (rather than a file)?

parsing parses the filename path of the receiver; note that the file described by the path does not have to exist

''C:\VW5i.4\mydirectory\test.txt''  asFilename head		- return the directory prefix of the receiver - here  ''C:\VW5i.4\mydirectory''
''C:\VW5i.4\mydirectory\test.txt''  asFilename tail			- return name of receiver without path, here  ''test.txt''
''C:\VW5i.4\mydirectory\test.txt''  asFilename extension	- return receiver''s extension, here ''.txt''
''C:\VW5i.4\mydirectory\test.txt''  asFilename directory		- return the Filename representing the receiver''s directory or the receiver itself if it denotes a directory; similar to message head except that it returns a Filename object rather than a String.

Exercises
1. Print the names of all directories in the root directory of the current disk drive.
2. Print the names of all files in the root directory.
3. Print the names of all read-only files in the root directory.
4. Open the File Browser tool from the Launcher (under the File command or using the button) and use it to create a short text file in the root directory.
5. Display the contents of the text file from the previous exercise in the Transcript.

Filename provides an interface to the file system but no messages to operate on the contents of the file except contentsOfEntireFile. Access to the bytes stored in a file is provided by various external stream classes that are covered next.

External streams are subclasses of Stream and form one of the branches of its subtree. The other very important branch contains internal streams that are used mainly for efficient manipulation of strings and other sequenceable collections. Internal streams are very important but I will not cover them due to lack of space. I recommend that you study the subject in On-line and application documents and the Browser. Many of the messages described below are inherited from abstract superclasses common to both internal and external streams but their description is written in the context of external streams.

Streams in general can perhaps be best visualized as providing a window that can be moved back and forth over an indexable collection. For internal streams, this collection is usually a string (an indexable collection of characters). For files, the underlying collection is a file of bytes. The role of the esential stream messages is to move this window back and forth and read or write the elements in the position currently ''visible'' through the window. The branch leading to external streams forms a rather large hierarchy of mostly abstract classes and the following instance variables are essential for basic use:

position		- 	current position of the ''window'' within the file treated as a stream of bytes, an integer with initial value 0; next read or write access will occur at position + 1
readLimit	-	integer size of the collection beyond which the stream cannot be read
writeLimit	-	position of the last byte written to the file

The following are the essential behaviors required for use of streams with files:

stream creation

External streams are created over Filename objects by messages in the stream creation instance protocol in class Filename. Several types of streams can be created and they differ in how they access the underlying file. The basic types are read stream, write stream, and read-write stream but other types of access can also be prescribed. The following are examples of the essential messages:

aFilename readStream.		"Opens the file associated with aFilename and returns a stream on it allowing sequential and random read-only byte-oriented access. No writing is possible."
aFilename writeStream		"Opens/creates the file; returns a stream allowing sequential or random write-only byte-oriented access. No reading."
aFilename readWriteStream	"Opens/creates the file; returns a stream allowing sequential or random read-write byte-oriented access."

testing

atEnd		- is stream positioned at end of file?

positioning - enables byte-oriented reading and writing

next					- Increment position and return next byte in file
nextPut: aByte 			- Increment position and store aByte (for example a Character) in the new position
nextPutAll:	aCollection	- Increment position and store aCollection''s elements one-by-one in consecutive positions; aCollection is very often a String

status

close		- close underlying file

Example: Store text in a file called test.txt

| filename writeFileStream |
"Create a file in the current directory and a write stream over it, store string in it, close."
filename := ''test file.txt'' asFilename.
writeFileStream :=filename writeStream.
writeFileStream nextPutAll: ''testing, testing''.
writeFileStream close

Read the data back one character at-a-time, displaying the characters in the Transcript one character per line, close file and delete it:

| filename readFileStream |
filename := ''test file.txt'' asFilename.
readFileStream :=  filename readStream.
Transcript clear.
[readFileStream atEnd] whileFalse: [Transcript nextPut: readFileStream next; cr].
Transcript flush.
readFileStream close.
filename delete

Notes: 
- Don''t forget to close a stream when you are finished  with it. Preferably use the ensure: message described in the section on exceptions below.
- Note that the Transcript understands stream accessing protocol. For a sequence of outputs to Transcript, a sequence of nextPut: and nextPutAll: followed by flush is much faster than a sequence of show: messages.

Although there are messages to output Smalltalk objects such as arrays, accounts, or library catalogs as text files, objects should be saved and read back using BOSS.

BOSS is the name of a collection of VisualWorks classes used to store objects in files and read them back, and BinaryObjectStorage is its main class. BOSS is not a part of the basic image and if you want to use it, you must load the BOSS parcel. BOSS is very powerful and can store very complicated objects such as a sorted collection of Book objects. It does, however, have limitations and the major one is that it cannot store objects that ''belong'' to the operating system such as windows of graphical user interfaces and objects that reference them. This can be quite annoying because windows may, for example, be indirectly referenced by names of Book authors displayed in a list in a window. To avoid this, code that uses BOSS to save such objects usually stores copies.

For routine use, the only BOSS class you need to know is BinaryObjectStorage. It includes the streaming protocol and to read or write objects using BOSS you just use the accessing and positioning methods described above. The only other methods you need are onNew: aStream (to create a Stream for writing) and onOld: aStream (for reading objects from an existing file).

Example: Store an Array in a file and read it back. The code is rather redundant - I could achieve the same result with fewer lines and variables but this version clearly indicates the objects involved. A shorter version is given in the next example.

| array filename writeFileStream boss |
"Create file and a write stream over it, use BOSS to store an Array, close."
filename := ''test file.bos'' asFilename.
array := #(''string 1'' ''string 2'' 100 200).
writeFileStream :=filename writeStream.
boss := BinaryObjectStorage onNew: writeFileStream.
boss nextPut: array.
boss close

Examine the file with the File Browser to see that it contains binary data rather than text.

| array filename readFileStream boss |
"Open a read stream over the file created above, read the Array from it using BOSS, print it, close and delete file."
filename := ''test file.bos'' asFilename.
readFileStream :=filename readStream.
boss := BinaryObjectStorage onOld: readFileStream.
array := boss next.
Transcript clear; show: array printString.
boss close.
filename delete

Note that the whole array was stored as a single object rather than a sequence of the array''s elements. The following variation stores the elements separately and reads them back one-by-one:

| array boss |
"Create file and a write stream over it, store individual elements of an Array object in it using BOSS, close."
array := #(''string 1'' ''string 2'' 100 200).
boss := BinaryObjectStorage onNew: ''test file.bos'' asFilename writeStream.
boss nextPutAll: array.	"nextPutAll: stores the collection''s elements one-by-one."
boss close

| filename boss |
filename := ''test file.bos'' asFilename.
boss := BinaryObjectStorage onOld: filename readStream.
Transcript clear.
[boss atEnd] whileFalse: [Transcript show: boss next printString; cr].	"Typical pattern for reading files."
boss close.
filename delete

Using random access stream messages, BOSS could be used as a simple database program.

Exercises:
1. Create a two-element array whose first element is the array of all even numbers between 1 and 10 and whose second element is the array of all odd numbers between 1 and 10. Store this object in a file as a single object using BOSS. Read this object back and print it to Transcript.
2. Store the same array as a sequence of elements (a 10-element sequence of objects consisting of 2, 4, 6, 8, 10, 1, 3, 5, 7, 9), read it back into an OrderedCollection, and inspect the result.

2. Exceptions

Well-designed programs must anticipate illegal conditions such as reading from a file that does not exist, or accessing an array index outside its legal bounds. One way to deal with such conditions is to test for them and deal with non-stanard situations, another is dealing with the problem when it occurs. Prevention consists of conditional logic with expressions such as collection detect:ifNone: or aFilename exists ifTrue: [...] ifFalse: [...]. The problem handling approach uses Exception objects. This section explains the principles of Exceptions.

A Smalltalk exception is an object designed to help in handling non-standard situations, an instance of one of the subclasses of Exception. According to VisualWorks documentation, ''exceptions are unusual or undesired events that can occur during the execution of a VisualWorks application'', and exception handling consists of ''raising an exception'' (instantiating one of the exception classes) when the ''unusual or undesired event'' occurs, and specifying how to handle a particular exception.

To use the exception-handling system, one must understand
- the classes that define exception objects
- the methods that raise and handle exceptions, and
- the principle of their operation.

The following is a brief summary of these topics; read the Application Developers Guide for more details.

Exception classes and how to raise an exception

All VisualWorks exceptions are subclasses of class GenericException. This branch of the class tree is quite large as you can see by printing

GenericException allSubclasses size

Class GenericException defines a number of instance and class variables. They include messageText (describing the error), originator (the object that raised the exception), notifierString (the default string used to describe the receiver),  initialContext (the initial context of the message send in which the exception was raised), and others.

The most important subclasses of GenericException are Error, Warning, and Notification and the difference between them is in the severity of the event that raised them. Error is the superclass of exception classes raised when a serious program error that requires an intervention occurs; its subclasses include ArithmeticError, DomainError, ZeroDivide, RangeError, MessageNotUnderstood, KeyNotFoundError, SubscriptOutOfBoundsError,  and many others. The default response to an Error is opening a notification window as happens, for example, when you evaluate

#(1 2 3) at: 4

For a less disruptive response, the program should define a handler that deals with the situation programmatically and avoids the exception window. I will show how to do this shortly. Warning is a less serious exception raised when the user (or the program) should be to be notified of some exceptional event by a dialog rather an exception window. The default action for a Notification is to do nothing and continue execution; the presence of this exception can, however, be handled using the same techniques as other exceptions.

You can define your own exception classes as subclasses of Exception and activate (raise) them at appropriate places of your program with messages raiseSignal or raiseSignal: aString. More commonly, you will only need to intercept (trap) some of the predefined exceptions and handle them in ways similar to the examples included in the class-side protocol examples of class Exception. Note, however, that these examples are written in terms of the older exception handling mechanism that used Signals rather than exceptions. In essence, Signals map to exceptions and have been introduce for conformity with the ANSI Smalltalk standard.

Handling exceptions

Every exception has its default handler action (method defaultAction, usually inherited) which is executed when the exception occurs and the program does not provide an explicit error handling action. As an example,

3 / 0

by default opens the familiar Exception window, whereas a Warning by default simply opens a true/false confirmation dialog as in (Do It)

Warning raiseSignal: ''Very large object encountered. Proceed?''

If you anticipate the possibility of an exception and want to handle it, you must ''guard'' the operation that might create the exception by inserting it in a block, and send it the message on: anExceptionClass do: handlerBlock. The on: argument is the name the class of the anticipated exception, and handlerBlock is a block that will be evaluated if the exception of the specified class or its subclass is raised during the evaluation of the guarded block. As an example, to guard against division by 0, you could write

| divisor |
divisor := (Dialog request: ''Enter divisor'' initialAnswer: ''0'') asNumber.
[10 / divisor]		"Operation to be attempted in a guarded fashion."
	on: ZeroDivide	"Anticipated possible type of Exception."
	do: [:exception | Dialog warn: ''Attempt to divide by zero.''].	"Handler - evaluated only if ZeroDivide exception occurs. Note that the raised exception is available to the code of the block."
Transcript clear; show: ''divisor = '', divisor printString

When this code fragment is evaluated and divisor ~=  0, the receiver block performs the indicated division and evaluation proceeds to the Transcript statement. When divisor = 0, the handler catches the exception, evaluates the do: block, and proceeds to the Transcript statement. The exception window is never displayed. Note that the behavior depends on the notion of a block of statements that is only evaluated when the specified exceptional condition occurs.

The principle of the the operation of Smalltalk error handlers is as follows: As the receiver block of on:do: is being evaluated, each invoked message puts an ''evaluation context'' object with information about the message, its receiver, and its arguments on an evaluation stack (of the kind shown in a Debugger window). A large number of contexts may thus pile up on top of the context of the method evaluating the on:do: message. If the evaluation of a message succeeds without raising an exception, its context is removed from the stack and if all messages in the guarded block succeed, the piled up messages unwind one-by-one and eventually strip the stack down to the context object of the on:do: message. If, however, a message executed in the guarded block raises an exception, Smalltalk starts searching the context stack from this message''s context (now on the top of the stack) until it finds an on:do: message whose on: argument is the exception class of the exception that was raised or its subclass. It then evaluates the do: block and execution proceeds from this point. If a matching on:do: message is not found, the default action is invoked opening an Exception window.

Excercises
1. Modify the example above to open an inspector when the exception occurs. Inspect the components of the exception.
2. Repeat the previous exercise but open the debugger.
3. Browse the Exception hierarchy and examine the instance variables and methods defined in Exception and its subclasses.
4. Examine the definitions of the following exceptions and write code fragments that will raise them. Write handlers to deal with them: IndexNotFoundError,	 keyNotFoundError,	NotFoundError,	PositionOutOfBoundsError.
5. What is the difference between instance variable messageText and class instance variable notifierString, both defined in class GenericException?

Other ways of responding to exceptions

The exception available in the do: handler block can be asked to respond in special ways. Two of them are illustrated in simple examples below and others are described in VisualWorks documentation and demonstrated in several examples in class Exception. All these methods are defined in class GenericException and you can, of course, define your own additional methods using information available in Exception objects.

retry	- instead of exiting from the guarded block after handling the exception, re-evaluate it, possibly modifying some objects first to make the re-evaluation possible

| divisor |	"On exception, give divisor a new but reasonable value that will succeed."
divisor := (Dialog request: ''Enter divisor'' initialAnswer: ''0'') asNumber.
[10 / divisor]		"Operation to be attempted."
	on: ZeroDivide
	do: [:exception | Dialog warn: ''Attempt to divide by zero.\Replacing divisor.'' withCRs. divisor := 0.000001. exception retry].
Transcript clear; show: ''divisor = '', divisor printString

resume	- instead of exiting, continue processing the protected block immediately behind the point where the exception occurred; this example traps <Ctrl> y pressed by the user during execution:

"Press <Ctrl> y during the execution of the block to see the effect of the following."
[(Delay forSeconds: 5) wait]
		on: UserInterrupt	"Trap <Ctrl> y, which normally causes user interrupt and opens an exception window."
		do: [:ex | Dialog warn: ''You pressed Ctrl y''. ex resume]	"Return to the loop inside the guarded block."

Another way to deal with exceptions is to use ensure: aBlock or ifCurtailed: aBlock messages. As on:do:, both are defined in class BlockClosure and start by evaluating the receiver. The ensure: message then evaluates the block argument aBlock - whether the receiver block evaluated successfully or not. A typical use of ensure: is in processing files where we must ensure that the external stream is closed whether the file operations succeeded or not. The pattern (the recommended way to deal with files) is as follows:

[open stream on Filename and do something]
			ensure: [stream close]	"Close stream whether the operations in the block succeeded or not. Note that the exception is not specified."

As another example, evaluate

| divisor |
divisor := (Dialog request: ''Enter divisor'' initialAnswer: ''0'') asNumber.
[10 / divisor] ensure: [Dialog warn: ''Division may or may not have succeeded.'']

Message ifCurtailed: aBlock evaluates aBlock only if the evaluation of the receiver fails. As an example,

| divisor |
divisor := (Dialog request: ''Enter divisor'' initialAnswer: ''0'') asNumber.
[10 / divisor]	 ifCurtailed: [Dialog warn: ''Division by zero attempted.'']	"Click Terminate in Exception window on exception. Note again the exception is not specified."

If the divisor is not 0, the argument block is not evaluated.

As you have noted, these two messages allow the raised exceptions to perform their default actions (such as opening an exception window) but ''tolerate'' (ensure:) or ''sense'' (ifCurtailed:) their occurrence.

Exercises
1. Modify the retry example to ask the user for a new divisor.
2. Modify the retry example to ask the user whether to enter a new divisor or continue and proceed accordingly.
3. Browse references to ensure: and ifCurtailed: and see examples in class Exception.


Part 7: Creating Graphical User Interfaces

This section explains the basics of creating a graphical user interface (GUI) for your application. Read on-line help or VisualWorks documentation for more details and the WalkThrough.pdf document for a complete example..

Typical Object-Oriented application development starts with ''domain'' classes followed by the development of the GUI. As an example, in a library information system, you would first create classes representing books, patrons, catalogs, and other library objects, and when you are sure that they work you would then create the windows for interacting with them. To create the windows, you would use the UI Painter tool to ''paint'' widgets on a blank window (''canvas'') and write the ''glue'' code to interface the GUI to your domain objects. You could also create windows programmatically, possibly even at runtime.

The UIPainter is accessible via the canvas-like button on the Launcher or through the Painter command. Its interface consists of three windows: the canvas (future window) itself, a Palette with widgets, and a GUI Painter tool. To create a window, you can proceed as follows:

1. Use the Painter tool to define the properties of the canvas (the future window) such as its label, the name of the method that will supply its menu and tool bars (menus themselves can be created using the Menu Editor tool accessible from the Painter tool), its size (minimum, fixed, etc.), its background color, and its scroll bars. When you are done, use the Install command (again available through the Painter tool and through the <operate> menu of the canvas) to ''install'' the canvas on a class such as LibrarySystemUI, usually a subclass of ApplicationModel. For the less common ''modal dialogs'', the window will be a subclass of SimpleDialog. Specify the name of the class method that will hold the window''s description (normally windowSpec). If the class does not yet exist, UI Painter will define it. Once the canvas is installed, you can open it via the Open command or programmatically via LibrarySystemUI open, and browse the application model class (our LibrarySystemUI) to edit its definition.

Besides storing a description of your window, the application model class has several other functions. As I already mentioned, LibrarySystemUI open will open the GUI and probably the whole application with it. In doing this, it will create an instance of UIBuilder which will build the window from the specification stored in windowSpec, sending several intermediate ''hook'' message to the application model, the new instance of your LibrarySystemUI. By default, these messages do nothing but you can redefine them to intervene into the building process, for example to initialize the contents of some window widgets. The application model also provides an interface between the GUI and your domain objects so that, for example, when the user enters the name of a book into a text field, the application model propagates the value to your library classes. Finally, the builder provides a permanent interface to the window and allows you, for example, to enable or disable widgets, change their labels, etc.

2. To populate the canvas with components, drag the desired widgets (buttons, text fields, lists, etc.) from the Palette to the window. (There are about 25 predefined widgets and you can define your own.) Their exact positions and size are not important because they can be easily accurately adjusted and aligned later.

3. Define widget properties by selecting the widgets one-by-one in the canvas or in the Painter tool, entering the properties into the Painter tool, and clicking Accept. Different kinds of widgets have different properties and you will have to learn about them from On-line Help or from the manual. The more common properties are as follows:
- 	name (a String) displayed inside or beside certain widgets
- 	action (a Symbol) - only for buttons - the name of the message sent when the user clicks the button
-  	aspect (a ValueHolder), an object holding the widget''s value, for example the text displayed by a text field or the names displayed inside a list
- 	ID (a Symbol), used to access the widget, for example to hide or disable it.

4. Adjust the size and position of your widgets in the canvas either by dragging them with the mouse, or by selecting group of widgets and using alignment tools in the Palette. Widget corners can be use absolute positioning (offset) in pixels, or relative positioning (proportion of window size), or the combination of the two. Relative positioning causes widgets to automatically adjust when the user changes the size of the window. The choice can be made via Layout in the Painter tool.

5. Use Define under Edit in the Painter tool to create instance variables to hold your widget properties, and method ''stumps'' (do-nothing methods) for widgets that require methods, such as action methods for buttons and aspect accessors for aspects. You will fill in the bodies later.

6. Install the window again (on the same application model class) to capture the changes in the windowSpec method. In general, if you modify the canvas and don''t re-install it, the changes will not be recorded in the class and will not show when you open the window. This is a frequent cause of surprises.

7. Use a Browser (most easily opened from the Painter tool) to write the code required by the GUI. This requires at least some of the following:
- 	Add instance variables for access to your domain objects. As an example, if the GUI provides access to a Book, you probably need an instance variable in your application model to refer to it.
- 	Redefine any ''hook'' messages sent to your application during the building of the window to intitialize your application and its GUI. These messages include initialize which is sent as a result of instantiating your application model class (LibrarySystemUI), and the following messages sent subsequently by the UIBuilder as it builds your window and opens it:
- -   Message preBuildWith: is sent before the builder constructs the window, 
- -   postBuildWith: is sent when the builder is done building but before the window opens on the screen, and
- -   postOpenWith: is sent when the window displays but before the use starts interacting with it. 
Each of these hook messages has its proper uses but I leave the details for the more detailed documents. The following are the most common actions performed by hook messages:
- 	Initialize instance variables providing access to your domain objects: Since the application model probably opens the whole application, you will want to create new instances of your domain objects and assign them to application model''s instance variables. You may also want to intialize them from files now. This is usually done in method initialize. 
- -	Initialize widgets'' aspect variables so that the window opens with desired initial contents of lists, radio buttons, check boxes, and so on. Use postBuildWith: and expressions like anAspect value: newValue to assign a new value to an aspect variable, and anAspect value to retrieve the value; here anAspect is the widget''s aspect variable. Using value and value: accessors to deal with widgets (here and everywhere else in your code) is essential because if you try to change the value of an aspect by assigning to its instance variable, you will ruin the bindings between the application model and the widgets and the widgets and their values will become disjoint. This is a very frequent mistake.
- 	Specify the names of the messages that should be automatically sent to the application model at runtime when the aspect of a widget changes - as when the user selects a different radio button causing perhaps the list labels to change, or when the state of a check box changes, or a new item is selected in a list. This is achieved by a message like anAspect onChangeSend: aSymbol to: self - in postBuildWith: Here aSymbol is the name of the message sent to the application model when the change occurs.

8. Write methods implementing button actions; if you used Define, the stump methods already exist and you only need to fill in the code.

9. Write methods corresponding to changes - the methods named aSymbol in your onChangeSend:to: expressions in step 7.

10. If you need to interact with a widget (for example, to disable or enable it) access it is by (builder componentAt: idSymbol) widget where idSymbol is the ID property of the widget.

That''s it! Note that you can test all of your code and your installed window at any point by opening your  application. In fact, you can even change your methods while the application is open without closing the application and develop the interface interactively. This is because application model messages are sent only when they are activated by the user and can thus be changed at any point. The only times when you must close and reopen the window is when you reinstall it (to add or remove widgets, reposition them or change other properties, etc.), or when you want to change the initialization process and therefore need to work with a window different from the one currently displayed.

There are, of course, lots of details that you must learn to build a more sophisticated GUI and you can find them in On-line help and in the documentation. The most important additional details concern the nature of the widgets. The essential facts about the basic widgets include the following:

- action button - has a name (label) and an action method which is evaluated when the user clicks the button
- text editor widget and input field - have an aspect holding the text that should only be accessed by value and value:; it has an <operate> menu (the easiest way to define it is via the Menu Editor in the UI Painter
- check box - has an aspect holding true when checked On, and false when Off
- radio box - come in groups; each radio button in a group has its individual name (a Symbol - the button''s Selection property) and all radio buttons in a group share an Aspect (another property) that holds the name of the currently selected button; when the user selects a different button, its Selection name becomes the new value of the Aspect.
- list widget - holds the list and the current selection in an aspect variable; its list and current selection can be accessed by list list: selection and selection:; it may have an <operate>  menu; you can also define it as a multi-select list allowing multiple selections at a time. 

Exercises
1.Read the comments of classes ApplicationModel, SimpleDialog, and UIBuilder. Read class-side examples in UIBuilder to see how to build windows programmatically.
2. Examine a few existing applications (such as the Menu Editor, the Browser, or the Palette via the Resource Finder (the Painter command in the Launcher or the other canvas-like button). At this point, focus on their UI features. As an example, select Tools.Menu Editor and windowSpec, click Edit, and explore the widgets and their properties.
3.Create an application implementing a simple counter. The window should have two buttons labeled Up and Down, and a text input field showing the current count. When the window opens, the field is initialized to 0, and clicking the buttons increments or decrements the displayed count. This problem is so simple that you can do without a domain class and implement the whole application in your application model class. (Note: When defining the input field, select its Type as Number so that you can assign a numerical value to it directly through value: without first converting it to a String.)
4. Add Save and Load buttons to the counter. When the user clicks Save, a dialog requests a file name and stores the current count in it. Clicking Load requests a filename and displays the stored value in the input field.
5. Create an application displaying the names of available colors. It will have a list displaying the names of all color constants (class ColorValue) and when the user clicks one, the background of the window changes to the selected color. (Hint: Your application model can obtain the window via its builder.)
6. Create an application displaying a list of all classes and showing the name of the superclass of the selected class in an input field.
7. Create an application that allows you to view, edit, save, and load information about you books (CD collection, etc.).


Part 8: Developing a Smalltalk Application

1. What is a Smalltalk application?

A software application in a typical programming language usually consists of an executable  .exe file and supporting files. The structure of a typical VisualWorks application usually consists of supporting files and two main files - a collection of classes and other objects stored in an image file with extension .im, and an executable .exe file containing the virtual machine that executes the code in the image. The image can be ported among different platforms without any change provided that it does not use platform-specific features such as platform-specific syntax of filenames. Only the  virtual machine executable is platform-specific. For Windows applications, you can combine the two files into a single .exe file as explained in the documentation.

The development environment that you are now using is also essentially an application, but it uses two additional files. One contains the source code and has extension .sou (this file would not usually be supplied with a commercial application), and the other is the ''changes'' files with extension .cha, which contains all the changes that you made to the image and the source code. The .cha file allows you to restore modified code up to the point where the changes file has been created or ''compressed'' into the image; this topic is covered in the documentation. A commercial application would not have a changes file because it would be compressed into the image file. In addition, the image file would be ''stripped'' of all classes that the application does not need, such as Browser classes, UI Painter classes, and so on. 

Most of the classes in an application usually come from the built-in library (numbers, strings, collections, windows, etc.), some possibly modified by the programmer. Application-specific classes - for example Book, Patron, Librarian, and Catalog for a book library application - are either developed specifically for the application or come from another source. Some classes may be obtained from parcels separately loaded into the basic image.

As already mentioned, the classes that constitute the application can usually be conceptually divided into three basic groups:

- base classes such as numbers - obtained from the built-in library
- domain classes that represent objects in the problem domain (such as Book, Patron, Librarian, and Catalog - written by the developers), 
- user interface classes - defining the general behavior of windows and their widgets, usually obtained directly from the built-in class library without any change
- application model classes that provide the glue between the developer''s domain classes and the user interface. As explained earlier, application model classes are usually derived from the built-in ApplicationModel class.

Creating a new application thus requires 
- Defining new methods and classes in the domain category, and application model classes defining windows and their interfaces to domain classes. Changes to built-in classes are much less common but not unusual.
- ''Stripping'' the image of unnecessary classes using the RuntimePackager available via Launcher Tools -> Runtime Packager. The procedure is explained in the packager itself and in VisualWorks documentation.

Make sure to read your license to see what you can legally deliver and read the documentation for full details on application deleivery.

Exercise
1. Deploy one of the applications developed earlier.

2. Smalltalk style

Just as programmers using other languages, Smalltalk programmers have their opinions on what is good programming style. Some are based on established conventions, but most are recommended because they produce efficient, readable, maintainable, and extendible code.

Perhaps the main guiding principle is that Smalltalkers consider readability to be of paramount importance  - more than programmers in most other languages. They think that code should be succinct, self-documenting, and no other documentation should normally be required to help the experienced reader understand the code. This leads to numerous guidelines summarized in the widely recognized books by Skublics and Beck. Within this limited space, I will list only a few selected Smalltalk style rules:

- Choose names of classes, variables, and messages very carefully. If you cannot find a good name, reconsider whether the construct is appropriate. If it is, use the best name you can think of and improve it when you revisit the code. If it isn''t change your design.
- Don''t hesitate to combine several names into a single identifier. If you do, capitalize the second and consecutive words as in raisedTo: asUppercase, GenericException, etc. However, don''t make names too long.
- Avoid unnecessary comments; they break the fluidity of the code and may become misleading if the code is later edited. Well-written Smalltalk code should be self-explanatory.
- Methods should be short, no more than 10 lines or so. A method definition should fit into the Browser without scrolling.
- If a method becomes too long, it should probably be divided (refactored) into several methods.
- Use conventional protocol names such as accessing, instance creation, testing, etc., whenever possible.
- Use available methods whenever possible. In particular, use appropriate enumeration messages when working with collections.
- Avoid nested logic and use polymorphism instead. (Polymorphism means that different classes implement messages with the same names and the same function but using class-specific logic. A good example are methods that draw geometric objects - they all have the same name and can thus be used without knowing, which specific object is being drawn, but each works differently to achieve the desired result.) 


Part 9: What next

Now that you learned the basics, explore Smalltalk in more depth:

-Rread at least WalkThrough, VisualWorks Developer''s Guide, and GUI Developer''s Guide documents supplied with VisualWorks.
- Read some of the code in the class library but Remember that although the code in the image is very instructive, it is not always perfect.
- Create applications with your own classes.
- Learn about Extreme Programming (XP).

When studying the source code in the Browser, consider the following:
- Take advantage of class categories. If you want to know about collections, then a good place to start is in the categories with the word Collections.
- Learn about implementors-of, senders-of, references-to, and other relationships and examples. Use Browse in the Launcher and similar commands in the Browser.
- Read class comments, and look at the class side for  examples and documentation protocols. Examples are also sometimes included as comments, as in the Dialog class methods.
- Find a more experienced Smalltalker or study with a fellow student.
- Read the comp.lang.smalltalk newsgroup.
- Read the references below.
- Read Smalltalk material on the Web such as Cincom Smalltalk Chronicle and Why Smalltalk, and new groups such as comp.lang.smalltalk..

References

Smalltalk books

There are a number of Smalltalk books and the following are a few of them:
A. Goldberg: Smalltalk 80 - the language and its implementation. The famous ''blue book'' containing among other things a detailed specification of the original Smalltalk run-time system and garbage collection written in Smalltalk. Addison-Wesley, 1980. Edited reprint 1989.
P.Winston: On to Smalltalk, Prentice-Hall, 1998. Slim and readable.
K. Beck: Smalltalk best practice patterns, Prentice-Hall, 1997. Kent Beck is one of the most recognized Smalltalk programmers, co-inventor of design patterns, the testing framework, and Extreme Programming, and this slim book is one of the most valuable Smalltalk style references.
S. Skublics, et al.: Smalltalk with style, Prentice-Hall, 1996. A list of commented style guidelines written by leading Smalltalk experts.
S. Lewis: The Art and Science of Smalltalk, Prentice Hall, 1995. A popular slim book written around VisualWorks.
S. Alpert, K. Brown, B. Woolf: The Design Patterns Smalltalk Companion, Addison-Wesley, 1998. Parallels the classical ''Gang of Four''  book on Design patterms but focuses on Smalltalk.
I. Tomek: The Joy of Smalltalk, 1996. My own approximately 700-page unpublished text dedicated to VisualWorks 3, freely available at http://plato.acadiau.ca/courses/comp/tomek/jos.htm
There are also several recent books about Squeak, a very popular dialect of Smalltalk, Dolphin Smalltalk, and books about Dolphin Smalltalk and IBM''s VisualAge Smalltalk.

Smalltalk Web sites
There are many Smalltalk Web sites and the following is only a small selection:
http://www.cincomsmalltalk.com/ is the Website of Cincom, the developer of this product.
http://st-www.cs.uiuc.edu/	The University of Illinois Urbana Champaign archive of free Smalltalk code and much Smalltalk information.
http://www.whysmalltalk.com/ - a well-maintained site with information on Smalltalk books, articles, conferences, dialects (including VisualWorks and others), etc.

Smalltalk newsgroups
comp.lang.smalltalk is a very lively newsgroup.

Extreme Programming (XP)
The following are a few of a number of books about XP, a development process favored by many Smalltalk programmers.
K. Beck: Extreme Programming Explained. Addison-Wesley, 1999.
R. Jeffries, A. Anderson, Ch. Hendrickson: Extreme Programming Installed. Addison-Wesley, 2001.
W. Wake: Extreme Programming Explored. Addison-Wesley, 2001.

Refactoring
Martin Fowler, et al.: Refactoring: Improving the Design of Existing Code.  Addison-Wesley, 1999.
'
NonCommercialWorkspace: Text for 'VisualWorks Non-Commercial -  Features

	• What is VisualWorks Non-Commercial?
	• What add-on functionality is available, and how do I find it?
	• What third-party packages are available?

What is VisualWorks Non-Commercial?
VisualWorks Non-Commercial is a freely available version of VisualWorks, Cincom''s industry-leading Smalltalk programming environment. VisualWorks is the most mature pure Object-Oriented programming environment available, and excels at building complex, scalable, networked applications, with true binary portability across a wide range of popular platforms.

VisualWorks Non-Commercial is available for Solaris SPARC, HPUX HPPA, IRIX MIPS, AIX RS6000, Compaq Unix AXP, Linux Intel, Windows Intel, MacOS 9 and X platforms. Additional platforms may become available in the future.

What add-on functionality is available, and how do I find it?
VisualWorks Non-Commercial 7.3 is identical to the commercial release of VisualWorks 7.3, Enterprise Edition, except that it presents a non-commercial license agreement at start-up.
All features and add-on components included in the commercial release are also available in VisualWorks non-commercial. These may be installed from with the Cincom Smalltalk CD.

Once the add-on functionality has been installed, you may use VisualWorks to explore the add-on components using the Parcel Manager. To begin, choose Parcel Manager from the System menu in the VisualWorks Launcher window.

Some of the more useful add-ons are:

	• Advanced Tools -  extra programming tools, such as profilers and code analysis tools. For details, see the Advanced Tools User''s Guide.

	• COM Connect -  allows use of COM components and construction of COM Smalltalk servers on Windows platforms only. For details, see the COM Connect User''s Guide.

	• Database Connects for Oracle, CTLib and ODBC (e.g. MSSQL) -  enable VisualWorks to use relational databases. In concert with the Object Lens these provide automatic object-relational mapping facilities. For details, see the Database Application Developer''s Guide. Preview connects for Cincom''s own database products SupraSQL and SocratesXML are also available, as are unsupported "goodie" connects for Postgres, DB2 and InterBase, and OODB connects for GemStone and Objectivity.

	• DLL and C Connect -  a set of tools for generating interfaces to call external libraries and code written in ''C''. For details, see the DLL & C Connect User''s Guide.

	• Distributed Smalltalk (DST) -  a powerful CORBA-based distributed programming system implemented in VisualWorks. With DST, developers may create and use CORBA interfaces to other languages. DST also includes the Implicit Interface Invocation (I3) which allows multiple VisualWorks images to interconnect without using IDL.  For details, see the Distributed Smalltalk Application Developer''s Guide and the Distributed Smalltalk Configuration Guide.

	• Opentalk -  a powerful framework for distributed programming that provides both Smalltalk-to-Smalltalk communication, remote debugging and distributed profiling and integration with web services such as SOAP.  For details, see the Opentalk Communication Layer Developer''s Guide.

	• VisualWorks PlugIn -  a Web-Browser plugin that can load and execute VisualWorks parcels over the internet. Currently this is provided only for Netscape 4.x and Internet Explorer 4.x on Windows platforms. Additional platforms may become available in the future.  For details, see the Plug-In Developer''s Guide.

	• VisualWorks Application Server -  a full-featured Application Server for building Web applications using industry-standard server pages (ASP, JSP, tag libraries), servlets, and VisualWave applications.  For details, see the Web Application Developer''s Guide, the Web Server Configuration Guide, and the Web GUI Developer''s Guide.

	• Store (Smalltalk Open Repository Environment) -  a powerful team programming tool set, allowing teams of programmers to share and version code using industry-standard databases (e.g., Oracle, SQLServer, and PostgresSQL). For details, see the Source Code Management Guide.

	• Internet Connecivity Toolkit -  a set of frameworks for building internet-enabled applications. The toolkit includes the following frameworks: FTP, MIME, RFC822, POP3, IMAP4, SMTP, URI (Universial Resource Identification), HTTP and SSL.  For details, see the Net Clients Developer''s Guide.


What third-party packages are available for VisualWorks Non-Commercial?
Along with the supported add-ons described above, are a large number of unsupported goodies with substantial functionality, as well as non-commercial offerings from third-party vendors. Some of the larger components include:

	• GemStone 6.0 Object-Oriented Database (non-commercial version).

	• Objectivity 6.1 Object-Oriented Database (trial version).

	• JUN 3D Graphics, Animation and Modelling Framework.

	• DOME (Domain Modelling Framework) -  including an OOD Tool comparable to Rational Rose, built using DOME. For details, see /goodies/other/DOME

	• WikiWorks -  a system for out-of-the-box user-editable web sites (e.g. wiki.cs.uiuc.edu/VisualWorks).

	• HotDraw and GF/ST -  two powerful frameworks for structured graphics. See: /goodies/other/HotDraw and /goodies/parc/GFST.

	• Aragon goodies -  includes a Rich Text framework, new widgets and more. See: /goodies/other/Aragon.

	• STAMP -  A POP and IMAP Mail client for VisualWorks. See: /goodies/parc/STAMP.

Copyright © 1999-2004 Cincom Systems, Inc. All Rights Reserved
'
OverviewWorkspace: Text for 'Overview

	• What''s Smalltalk?
	• What makes Smalltalk so interesting?
	• What are Smalltalk''s strengths?
	• Is Smalltalk available from other vendors?

What''s Smalltalk?
Smalltalk is a language, a complete class library, and an interactive programming environment rolled into one seamless whole. The environment itself is built in Smalltalk. The system includes its own compiler, debugger, and class library browser that combines a text editor, code analyzer, interactive compiler and code refactoring tool.  Since these are all written in Smalltalk, they are extensible by the user. Smalltalk is an incrementally compiled system, allowing these tools provide perfect source-level debugging with "debug and continue" facilities.

Smalltalk was developed at the Xerox Palo Alto Research Center in the ''70s and ''80s. The language was designed to combine comprehensibility with power and malleability, and its use by local school children helped create a system that was responsive (kids get impatient quickly) and fun to use (they won''t use anything else!). 

In 1988, Xerox spun off ParcPlace Systems as an independent company to commercialize its Smalltalk work. Later, ParcPlace merged with Digitalk to form ParcPlace-Digitalk in 1995, which renamed itself ObjectShare in 1997. In 1999, Cincom Systems acquired the VisualWorks technology and its engineering team.

For brief histories of Smalltalk by two of its principal creators, see:

	 "The Early History of Smalltalk" by Alan C. Kay,
	in History of Programming Languages
	Thomas J. Bergin and Richard G. Gibson, Eds.
	Addison-Wesley, ISBN 0-201-89502-1.

	"The Community of Smalltalk" by Adele Goldberg,
	in Handbook of Programming Languages, Vol. 1.
	Object-Oriented Programming Languages,
	Peter H Salus, Ed.
	McMillan, ISBN 1-57870-008-6.

What makes Smalltalk so interesting?
Smalltalk is a mature programming system that has been the testing and proving ground for much of the technology in today''s programming environments. Just to consider a few reaaons...

Smalltalk runs on a virtual machine, an abstract computer that can be implemented on different processors to provide a binary-portable execution environment. Virtual machine technology can be traced back to Peter Landin''s SECD machine for LISP, designed in the early sixties. In 1983 the Xerox PARC Smalltalk group applied just-in-time (JIT) compilation technology to implement the Smalltalk virtual machine efficiently on commodity hardware, namely the Motorola 68020. This provided the first high-performance implementation of a late-bound implicitly-typed incrementally-compiled system. More recently, Java has popularized this implementation scheme. 

In their desire to provide an interactive graphical environment the PARC Smalltalk group invented overlapping windows and pop-up menus, within the Smalltalk environment. Steve Jobs saw the Smalltalk environment at PARC in the eighties, took the ideas back to Apple and incorporated them in the Lisa and the Mac. The windowing environment pioneered in Smalltalk is now the common UI environment on most desktop computers.

Smalltalk performs automatic memory management (known as garbage collection), to relieve the programmer of the error-prone task of reclaiming unused storage. Generation scavenging, the first truly high-performance garbage collection algorithm, was pioneered in Berkeley Smalltalk, and soon incorporated in the 2nd generation ParcPlace virtual machine, HPS. HPS is the engine underneath VisualWorks Non-Commercial. It runs on at least 8 major instruction set architectures (Intel x86, PowerPC/RS6000, SPARC, HPPA, Alpha, MIPS, Motorola 68k and ARM), and runs on the Windows, MacOS and Unix with X11 operating/window systems.

Smalltalk introduced the notion of a reflective programming language, whereby the objects that define the language are themselves built with the language. Hence in Smalltalk, code entities such as classes and methods are themselves programmable and extensible objects, just like any other Smalltalk object. Smalltalk even represents processes and method activations as objects. The use of Smalltalk objects to define the Smalltalk system itself allows the programmer to extend the language and environment in a way that is unparalleled in conventional programming environments.

What are Smalltalk''s strengths?
There are many, including:

	• Smalltalk has been providing high-performance, write-once-run-anywhere execution technology since the early eighties.  

	• Smalltalk is the context in which eXtreme Programming was developed and is still by far the most productive XP environment.  

	• Smalltalk is a dynamic implicitly-typed language where objects, not variables, carry type information, freeing the programmer from declaring variable types, but still providing complete type-safety.  

	• Smalltalk has block closures, anonymous function closures which are more general and much more concise than Java''s inner classes, and help make Smalltalk''s Collection hierarchy the most powerful set of container classes available.  

	• Smalltalk has always provided an integrated programming environment freeing programmers from the tyranny of the compile-link-debug-edit cycle, allowing them to concentrate on developing great programs.

	• Smalltalk excels at building large systems that evolve over time. The original Smalltalk implementations were hosted on a bare machine and consequently were the operating system.  The combination of a polymorphic, pure object-oriented language which is simple yet powerful with strong encapsulation, an incremental programming environment, a large robust class library and garbage collection make Smalltalk an excellent vehicle for building complex systems that must adapt to a changing world.

Is Smalltalk available from other vendors?
Yes. There are a number of commercial Smalltalk vendors, and a vendor-neutral industry council. The Smalltalk Industry Council (STIC) is an umbrella organization for commercial Smalltalk interests. For more information about STIC and its members, visit:

	http://www.stic.org

There are also a number of free versions of Smalltalk:

	• Squeak -  another direct descendant from the original PARC Smalltalk-80. It is being developed by a group that comprised a number of the original researchers from PARC, including Dan Ingalls, the principal language designer of Smalltalk. Squeak has a very active user group and is the context for much innovative work in Smalltalk, user interfaces, and music. To learn more, visit the following sites:

	http://squeak.cs.uiuc.edu
	http://www.create.ucsb.edu/squeak

	• ObjectStudio -  another Smalltalk environment from Cincom Systems, Inc.  It features an excellent native Windows and OS/2 GUI and strong database integration. It is included on the Cincom Smalltalk CD. For more information, see:

	http://www.cincom.com/objectstudio

	• Dolphin Smalltalk -  a 32-bit Smalltalk implementation for Windows 95 and NT available for free from Object Arts. See:

	http://www.object-arts.com/home.htm

	• Smalltalk/X -  a commercial Unix-based implementation from Germany that generates C code. A non-commercial version is available from:

	http://www.exept.de/sites/exept/english/Smalltalk/frame_uebersicht.html

	• Little Smalltalk, a.k.a. GNU Smalltalk -  a complete implementation of Smalltalk, including the virtual machine, available from any GNU site, e.g.:

	http://www.gnu.org/software/smalltalk/smalltalk.html

To find LittleSmalltalk on a GNU site, search for smalltalk in the directory listing.

	• Pocket Smalltalk -  an implementation of the popular programming language Smalltalk for the PalmPilot. To find out more, visit:

	http://www.pocketsmalltalk.com

	• Self (Son of Smalltalk) -  Smalltalk is by no means the end of the story in language design. Self is even simpler than Smalltalk. It was designed in the early eighties and, because of its simplicity required novel implementation technologies to achieve good performance. Self has spawned much of the work on high-performance implementation of dynamic object-oriented languages like Smalltalk, Self and Cecil done in the eighties and nineties. Self, including the source for its high-performance virtual machine, is available for Solaris. For details, see:

	http://research.sun.com/self

Enjoy!

Copyright © 1999-2004 Cincom Systems, Inc. All Rights Reserved
'
PackageName: Non-Commercialization
Parcel: #('Non-Commercialization')
ParcelName: Non-Commercialization
PrerequisiteParcels: #(#('UIPainter' '') #('SLesson Intro Content' '') #('StoreForPostgreSQL' '') #('Tools-Workspace' ''))
PrintStringCache: (1.0.36,bobw)
SaveSource: true
Version: 7.4
Pre-Save Block: 
	[ :pkg |  
(Warning raiseSignal: 'Update the workspace properties?') ifTrue:
	[''Store the workspaces.''
	pkg 
		propertyAt: #gettingStartedWorkspace 
		put: Tools.SimpleWorkspace.GettingStartedWorkspace value.
	pkg 
		propertyAt: #overviewWorkspace 
		put: Tools.SimpleWorkspace.OverviewWorkspace value.
	pkg 
		propertyAt: #nonCommercialWorkspace 
		put: Tools.SimpleWorkspace.NonCommercialWorkspace value.
	pkg 
		propertyAt: #ivanWorkspace 
		put: Tools.SimpleWorkspace.IvanWorkspace value]]
Date: 2:15:36 pm December 5, 2005
 -->
<time-stamp>From VisualWorks® NonCommercial, 7.4 of December 5, 2005 on December 5, 2005 at 2:15:36 pm</time-stamp>


<do-it>(Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned.  Choose terminate or close.']</do-it>

<shared-variable>
<name>LicenseAgreement</name>
<environment>UI.SimpleHelp</environment>
<private>false</private>
<constant>false</constant>
<category>non-commerical</category>
<initializer>LicenseAgreement isNil  ifTrue: [(Text string: '						CINCOM SYSTEMS, INC.
					SOFTWARE LICENSE AGREEMENT
					  FOR NON-COMMERCIAL USERS


IMPORTANT NOTICE:  READ THE TERMS AND CONDITIONS OF THIS LICENSE AGREEMENT CAREFULLY BEFORE PROCEEDING TO USE THE ENCLOSED COMPUTER SOFTWARE AND THE RELATED USER DOCUMENTATION (THE "PRODUCT"). THE PRODUCT IS COPYRIGHTED AND ITS USE IS LICENSED (NOT SOLD).  BY USING THE PRODUCT, YOU ARE ACCEPTING AND AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT.  IF YOU ARE NOT WILLING TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS LICENSE AGREEMENT, YOU SHOULD NOT USE THE PRODUCT.  THIS LICENSE AGREEMENT REPRESENTS THE ENTIRE AGREEMENT CONCERNING THE PRODUCT BETWEEN YOU AND CINCOM SYSTEMS, INC. (REFERRED TO HEREIN AS "LICENSOR"), AND THIS AGREEMENT SUPERSEDES ANY PRIOR PROPOSALS, REPRESENTATIONS, OR UNDERSTANDING BETWEEN THE PARTIES.

	1. License Grant.  Licensor hereby grants to you, and you do hereby accept, a nonexclusive license to use the Product only as is authorized in this License Agreement. You shall not reverse assemble or otherwise translate the Product.

	U.S. Government Restricted Rights:  Licensor provides the Product with RESTRICTED RIGHTS.  Use, duplication, or disclosure by the U.S. Government or any agency or instrumentality thereof is subject to restrictions set forth in subparagraphs (c) (1) and (2) of the Commercial Computer Software - Restricted Rights clause at 48 C.F.R. 52.227-19, or any successor provision, as applicable. The Contractor/Manufacturer is Cincom Systems, Inc., 55 Merchant Street, Cincinnati, Ohio  45246.
	
	2. Licensor''s Rights.  You acknowledge and agree that the Product is a proprietary product of Licensor protected under U.S. copyright law and international treaty provisions.  You further acknowledge and agree that all right, title, and interest in and to the Product, including associated intellectual property rights, are and shall remain with Licensor. This License Agreement does not convey to you an interest in or to the Product, but only a limited right of use revocable in accordance with the terms of this License Agreement.

	3. Licensee''s Rights.  
		a. Licensee may distribute copies of the Software in unmodified form to persons who have agreed to the terms of this license agreement. 
		b. Licensee may distribute, without charge of any kind, applications developed using the Software to persons who have agreed to use such applications for non-commercial purposes, pursuant to a license agreement containing terms and provisions at least as restrictive and protective of Licensor''s rights and interests as this Agreement.

	4. Rental Fees.  This license is granted to you on a non-commercial basis.  Therefore, no Rental Charges are involved, unless you breach the terms and conditions of Section 1 herein.  Upon any such breach and the request of Licensor, you shall pay Licensor the applicable rental charges for the Product for your nonconforming use.

	5. Term.  This License Agreement is effective upon delivery of the Product to you and will remain in effect until terminated.  You may terminate this License Agreement at any time by giving 30 days prior written notice to Licensor.  You shall not be entitled to a refund or credit for any amounts which may become due prior to the date of termination.  Licensor may terminate this License Agreement upon your breach of any term hereof.  Upon termination by Licensor, you agree to discontinue usage and return or destroy all copies and portions of the Product.

	6. Limited Warranty. THE PRODUCT IS LICENSED "AS IS," AND LICENSOR DISCLAIMS ANY AND ALL OTHER WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

	7. Limitation of Liability.  Licensor''s cumulative liability to you or any other party for any loss or damages resulting from any claims, demands, or actions arising out of or relating to this Agreement will not exceed the total amount paid by you to Licensor in the twelve months immediately preceding such claim, in license charges for the use of any Product that causes damages.  In no event shall Licensor be liable for any indirect, incidental, consequential, special, or exemplary damages or lost profits, even if Licensor has been advised of the possibility of such damages.  THE ABOVE LIMITATION OR EXCLUSION MAY NOT BE ALLOWED BY ALL JURISDICTIONS.

	8. Trademark.  The trademark listed on the Product is a trademark of Licensor.  No right, license, or interest to such trademark is granted hereunder, and you agree that no such right, license, or interest shall be asserted by you with respect to such trademark.

	9. Governing Law.  This License Agreement shall be construed and governed in accordance with the laws of the State of Ohio.

	10. Costs of Litigation.  If any action is brought by either party to this License Agreement against the other party regarding the subject matter hereof, the prevailing party shall be entitled to recover, in addition to any other relief granted, reasonable attorney fees and expenses of litigation.

	11. Severability.  Should any term of this License Agreement be declared void or unenforceable by any court of competent jurisdiction, such declaration shall have no effect on the remaining terms hereof.

	12. No Waiver.  The failure of either party to enforce any rights granted hereunder or to take action against the other party in the event of any breach hereunder shall not be deemed a waiver by that party as to subsequent enforcement of such or any other such rights or any subsequent actions in the event of future breaches.

If you have any questions about this License Agreement, or if you have any questions or comments about the Product, please contact your local Cincom sales office.

						TERMS AND CONDITIONS
				SPECIFIC TO EDUCATIONAL INSTITUTIONS
						AND RESEARCH CENTERS

THE TERMS AND CONDITIONS STATED BELOW SHALL BE CONSIDERED INCORPORATED AND MADE PART OF THE PRIOR TERMS AND CONDITIONS. THOSE STATED HEREAFTER MODIFY THE TERMS AND CONDITIONS SET FORTH ABOVE IN PART AND ONLY APPLY TO PRODUCTS LICENSED BY EDUCATIONAL INSTITUTIONS AND RESEARCH CENTERS.  IF THERE IS ANY INCONSISTENCY BETWEEN THE TERMS AND CONDITONS SET FORTH ABOVE AND THOSE SET FORTH BELOW, THE TERMS AND CONDITIONS BELOW SHALL CONTROL.  

	13. Academic License.  In order to be covered under these extended terms and conditions, Customer must first register on Cincom''s Website as an Academic/Research user.  

	14. Support Contact.  Customer may designate up to three named users as Support Contacts when registering.

	15. Licensee''s Rights (extended).  Registered Customer, its students, or research teams are free to use the software for their research and teaching.  

	16. License Fees (extended).  Customer, its students or research teams shall, in no way, use the Product for any internal or external commercial business, or for any internal or external commercial operational activities.  Customer is fully responsible for any prohibited use of Product by it, its students or research teams and accepts this nondisclosure clause for it, its students and/or research teams.

	17. Support.  Any of Customer''s registered Support Contacts has full access to Cincom''s on-line and telephone support, as needed, for assistance with problem resolution relating to the proper operation of the Product.

	18. Additional Support.  Any additional support and/or special services are separate, and subject to the terms and conditions of a separate agreement with Cincom. 

	19. Licensor''s Rights (extended).  Cincom may use Registered Customer''s name in any of its marketing or promotional materials.


						TERMS AND CONDITIONS
				SPECIFIC TO COMMERCIAL EVALUATION 
						USAGE OF THE PRODUCT

	20. Licensor''s Rights (extended).
		a. Licensee may use this software for commercial evaluation purposes for a period not to exceed ninety (90) days.  Any additional evaluation must be mutually agreed upon by Cincom and Licensee
		b. Licensee may receive support from Cincom during the period of evaluation provided that Licensee has first registered with Cincom.  
		c. In order to register with Cincom for evaluation purposes, Licensee must sign the bottom of this license and deliver it to Cincom.  


		I ____________________________________________, an 


employee of ______________________________ agree to the terms of 


this license for commercial evaluation.  


Signed: ________________________________________________________



Date: ___________________________________________________________' runs: (Core.RunArray runs: #(91 2 16 717 16 52 6 4 12 39 10 585 20 516 20 6 1 138 1 337 14 133 3 183 7 555 19 228 26 124 7 503 12 78 7 168 16 110 23 135 10 133 16 190 13 479 94 443 20 83 5 64 19 90 32 122 27 70 7 305 11 139 7 63 22 144 32 97 93 2 32 4 1 194 1 136 1 136 301) values: #(#(#serif #bold) #serif #(#serif #underline) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold) #serif #(#serif #bold)))) asValue] ifFalse: [LicenseAgreement]</initializer>
<attributes>
<package>Non-Commercialization</package>
</attributes>
</shared-variable>

<shared-variable>
<name>IvanWorkspace</name>
<environment>Tools.SimpleWorkspace</environment>
<private>false</private>
<constant>false</constant>
<category>workspaces</category>
<initializer></initializer>
<attributes>
<package>Non-Commercialization</package>
</attributes>
</shared-variable>

<shared-variable>
<name>NonCommercialWorkspace</name>
<environment>Tools.SimpleWorkspace</environment>
<private>false</private>
<constant>false</constant>
<category>workspaces</category>
<initializer></initializer>
<attributes>
<package>Non-Commercialization</package>
</attributes>
</shared-variable>

<shared-variable>
<name>OverviewWorkspace</name>
<environment>Tools.SimpleWorkspace</environment>
<private>false</private>
<constant>false</constant>
<category>workspaces</category>
<initializer></initializer>
<attributes>
<package>Non-Commercialization</package>
</attributes>
</shared-variable>

<shared-variable>
<name>GettingStartedWorkspace</name>
<environment>Tools.SimpleWorkspace</environment>
<private>false</private>
<constant>false</constant>
<category>workspaces</category>
<initializer></initializer>
<attributes>
<package>Non-Commercialization</package>
</attributes>
</shared-variable>

<methods>
<class-id>Tools.Workbook class</class-id> <category>system workbooks</category>

<body package="Non-Commercialization" selector="openIntroductionWorkbook">openIntroductionWorkbook
	"Open a workbook with various getting started and introductions pages."
	"self openIntroductionWorkbook"

	| book |
	book := self new.
	book
		replaceAllTextPagesWith: WorkspacePage gettingStarted;
		addPage: WorkspacePage overview;
		addPage: WorkspacePage features;
		addPage: WorkspacePage introduction;
		open.
	book builder window label: 'Welcome to VisualWorks'</body>
</methods>

<methods>
<class-id>Kernel.SystemUtils class</class-id> <category>fileIn/Out</category>

<body package="Non-Commercialization" selector="version">version
	"Answer the version of this release."

"	| stream |
	stream := (String new: 50) writeStream.
	stream nextPutAll: 'VisualWorks® NonCommercial, Release 7 of '.
	stream print: SystemReleaseDate.
	^stream contents"

	^(#vwversionNC &lt;&lt; #dialogs &gt;&gt; 'VisualWorks® NonCommercial, &lt;1s&gt; of &lt;2p&gt;') expandMacrosWith: SystemVersionName with: SystemReleaseDate</body>
</methods>

<methods>
<class-id>Kernel.NameSpace</class-id> <category>backwards compatibility</category>

<body package="Non-Commercialization" selector="versionName">versionName
	"Answer the version identification, e.g. VisualWorks®"

	^(#VisualWorks1NC &lt;&lt; #dialogs &gt;&gt; 'VisualWorks® NonCommercial')</body>
</methods>

<methods>
<class-id>Tools.Workspace class</class-id> <category>useful workspaces</category>

<body package="Non-Commercialization" selector="openGettingStartedWorkspace">openGettingStartedWorkspace
	"Schedule a view of the Getting Started Workspace."
	"self openGettingStartedWorkspace."

	^(self on: SimpleWorkspace.GettingStartedWorkspace labeled: 'Getting Started') open</body>

<body package="Non-Commercialization" selector="openIvanTomekWorkspace">openIvanTomekWorkspace
	"Schedule a view of the Ivan Tomek's Workspace"
	"self openIvanTomekWorkspace."

	^(self on: SimpleWorkspace.IvanWorkspace labeled: 'Ivan Tomek''s VisualWorks Smalltalk Workspace') open</body>

<body package="Non-Commercialization" selector="openNonCommercialWorkspace">openNonCommercialWorkspace
	"Schedule a view of the what's so cool about Smalltalk Workspace."
	"self openNonCommercialWorkspace."

	^(self on: SimpleWorkspace.NonCommercialWorkspace labeled: 'What''s So Cool About Smalltalk Workspace') open</body>
</methods>

<methods>
<class-id>Tools.VisualLauncher class</class-id> <category>accessing</category>

<body package="Non-Commercialization" selector="title">title
	"Return a title for the launcher which includes the image name"

	^(#VWLauncherLabelNC &lt;&lt; #labels &gt;&gt; 'VisualWorks NonCommercial  &lt;1s&gt;') expandMacrosWith: ObjectMemory imagePrefix</body>
</methods>

<methods>
<class-id>Tools.SimpleWorkspace class</class-id> <category>useful workspaces</category>

<body package="Non-Commercialization" selector="openGettingStartedWorkspace">openGettingStartedWorkspace
	"Schedule a view of the Getting Started Workspace."
	"SimpleWorkspace openGettingStartedWorkspace."	

	| application |
	application := self new.
	application setWorkspace: GettingStartedWorkspace.
	application open.
	application builder window label: 'Getting Started'.
	^application</body>

<body package="Non-Commercialization" selector="openIvanTomekWorkspace">openIvanTomekWorkspace
	"Schedule a view of the Ivan Tomek's Workspace"
	"SimpleWorkspace openIvanTomekWorkspace."	

	| application |
	application := self new.
	application setWorkspace: IvanWorkspace.
	application open.
	application builder window label: 'Introduction to VisualWorks'.
	^application</body>

<body package="Non-Commercialization" selector="openNonCommercialWorkspace">openNonCommercialWorkspace
	"Schedule a view of the Non-Commercial Overview Workspace."
	"SimpleWorkspace openNonCommercialWorkspace."	

	| application |
	application := self new.
	application setWorkspace: NonCommercialWorkspace.
	application open.
	application builder window label: 'Overview of VisualWorks Non-Commercial'.</body>
</methods>

<methods>
<class-id>Tools.WorkspacePage class</class-id> <category>system workpages</category>

<body package="Non-Commercialization" selector="features">features

	^WorkspacePage
		on: SimpleWorkspace.NonCommercialWorkspace
		labeled: 'Features'</body>

<body package="Non-Commercialization" selector="gettingStarted">gettingStarted

	^WorkspacePage
		on: SimpleWorkspace.GettingStartedWorkspace
		labeled: 'Getting Started'</body>

<body package="Non-Commercialization" selector="introduction">introduction

	^WorkspacePage
		on: SimpleWorkspace.IvanWorkspace
		labeled: 'Introduction'</body>

<body package="Non-Commercialization" selector="overview">overview

	^WorkspacePage
		on: SimpleWorkspace.OverviewWorkspace
		labeled: 'Overview'</body>
</methods>

<methods>
<class-id>Tools.VisualLauncher class</class-id> <category>resources</category>

<body package="Non-Commercialization" selector="menuBar">menuBar
	"Tools.MenuEditor new openOnClass: self andSelector: #menuBar"

	&lt;resource: #menu&gt;
	^#(#{UI.Menu} #(
			#(#{UI.MenuItem} 
				#rawLabel: 
				#(#{Kernel.UserMessage} 
					#key: #_File 
					#defaultString: '&amp;File' 
					#catalogID: #menus ) 
				#nameKey: #file 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #saveImage 
								#defaultString: '&amp;Save Image' 
								#catalogID: #menus ) 
							#nameKey: #imageSave 
							#value: #imageSave 
							#labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #fileSave ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #saveImageAs 
								#defaultString: 'Save Image &amp;As...' 
								#catalogID: #menus ) 
							#nameKey: #imageSaveAs 
							#value: #imageSaveAs ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #permSaveImageAs 
								#defaultString: '&amp;Perm Save Image As...' 
								#catalogID: #menus ) 
							#nameKey: #filePermSaveAs 
							#value: #filePermSaveAs ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #permUndoAs 
								#defaultString: 'Perm &amp;Undo As...' 
								#catalogID: #menus ) 
							#nameKey: #filePermUndoAs 
							#value: #filePermUndoAs ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #exitVW 
								#defaultString: 'E&amp;xit VisualWorks...' 
								#catalogID: #menus ) 
							#nameKey: #visualWorksExit 
							#value: #visualWorksExit ) ) #(4 1 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 
				#(#{Kernel.UserMessage} 
					#key: #_System 
					#defaultString: '&amp;System' 
					#catalogID: #menus ) 
				#nameKey: #system 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #Changes 
								#defaultString: 'Changes' 
								#catalogID: #menus ) 
							#nameKey: #changes 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #condenseChanges 
											#defaultString: '&amp;Condense Changes' 
											#catalogID: #menus ) 
										#value: #changesFileCondense ) ) #(1 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #collectGarbage 
								#defaultString: 'Collect &amp;Garbage' 
								#catalogID: #menus ) 
							#nameKey: #collectGarbage 
							#value: #collectGarbage ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #collectAllGarbage 
								#defaultString: 'Collect &amp;All Garbage' 
								#catalogID: #menus ) 
							#nameKey: #collectAllGarbage 
							#value: #collectAllGarbage ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #_ClearTranscript 
								#defaultString: '&amp;Clear Transcript' 
								#catalogID: #menus ) 
							#nameKey: #clearTranscript 
							#value: #clearTranscript 
							#labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #delete ) ) ) #(1 2 1 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 
				#(#{Kernel.UserMessage} 
					#key: #_Browse 
					#defaultString: '&amp;Browse' 
					#catalogID: #menus ) 
				#nameKey: #browse 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #system 
								#defaultString: 'S&amp;ystem' 
								#catalogID: #menus ) 
							#nameKey: #browseSystem 
							#value: #browseSystem 
							#shortcutKeyCharacter: #F5 
							#shortcutModifiers: 0 
							#labelImage: #(#{UI.ResourceRetriever} nil #systemIcon ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #_ClassVariableNameSpaceDots 
								#defaultString: '&amp;Class/Variable/Name Space...' 
								#catalogID: #menus ) 
							#nameKey: #browseGlobalName 
							#value: #browseGlobalName 
							#shortcutKeyCharacter: $F 
							#shortcutModifiers: 3 
							#labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #findClass ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #sendersOfSelector 
								#defaultString: '&amp;Senders of Selector...' 
								#catalogID: #menus ) 
							#nameKey: #browseSendersOf 
							#value: #browseSendersOf 
							#shortcutKeyCharacter: #F6 
							#shortcutModifiers: 2 
							#labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #selectorReferences ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #implementorsOfSelector 
								#defaultString: 'I&amp;mplementors of Selector...' 
								#catalogID: #menus ) 
							#nameKey: #browseImplementorsOf 
							#value: #browseImplementorsOf 
							#shortcutKeyCharacter: #F7 
							#shortcutModifiers: 2 
							#labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #selectorImplementors ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #referencesToVariable 
								#defaultString: 'References to &amp;Variable...' 
								#catalogID: #menus ) 
							#nameKey: #browseGlobal 
							#value: #browseGlobal 
							#shortcutKeyCharacter: #F5 
							#shortcutModifiers: 2 ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #_Inspect 
								#defaultString: '&amp;Inspect' 
								#catalogID: #menus ) 
							#nameKey: #inspect 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #_Variable 
											#defaultString: '&amp;Variable...' 
											#catalogID: #menus ) 
										#value: #browseInspect 
										#shortcutKeyCharacter: #F5 
										#shortcutModifiers: 8 ) 
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #Processor 
											#defaultString: 'Processor' 
											#catalogID: #menus ) 
										#value: #inspectProcessor ) 
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #ScheduledControllers 
											#defaultString: 'ScheduledControllers' 
											#catalogID: #menus ) 
										#value: #inspectScheduledControllers ) ) #(1 2 ) nil ) ) ) #(1 4 1 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 
				#(#{Kernel.UserMessage} 
					#key: #_Tools 
					#defaultString: '&amp;Tools' 
					#catalogID: #menus ) 
				#nameKey: #tools 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #advanced 
								#defaultString: '&amp;Advanced' 
								#catalogID: #menus ) 
							#nameKey: #advanced ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #dllAndCConnect 
								#defaultString: '&amp;DLL and C Connect' 
								#catalogID: #menus ) 
							#nameKey: #dllcc 
							#value: #openExternalFinder 
							#labelImage: #(#{UI.ResourceRetriever} nil #extFinderIcon ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #database 
								#defaultString: '&amp;Database' 
								#catalogID: #menus ) 
							#nameKey: #database 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #adHocSQL 
											#defaultString: 'Ad Hoc &amp;SQL' 
											#catalogID: #menus ) 
										#nameKey: #adHoc 
										#value: #openAdHocQuery ) 
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #dataModelr 
											#defaultString: 'Data &amp;Modeler' 
											#catalogID: #menus ) 
										#nameKey: #dataModeler 
										#value: #openDataModelBrowser 
										#labelImage: #(#{UI.ResourceRetriever} nil #dbToolIcon ) ) 
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #canvasComposer 
											#defaultString: 'Canvas &amp;Composer' 
											#catalogID: #menus ) 
										#nameKey: #canvasComposer 
										#value: #openCanvasComposer ) 
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #newDataForm 
											#defaultString: 'New Data &amp;Form...' 
											#catalogID: #menus ) 
										#nameKey: #dataForm 
										#value: #newDataForm ) 
									#(#{UI.MenuItem} 
										#rawLabel: 
										#(#{Kernel.UserMessage} 
											#key: #newDatabseApplication 
											#defaultString: 'New Database &amp;Application...' 
											#catalogID: #menus ) 
										#nameKey: #dataBaseAp 
										#value: #newDataMain ) ) #(1 4 ) nil ) ) ) #(2 1 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 
				#(#{Kernel.UserMessage} 
					#key: #windowMenu 
					#defaultString: '&amp;Window' 
					#catalogID: #menus ) 
				#nameKey: #window ) 
			#(#{UI.MenuItem} 
				#rawLabel: 
				#(#{Kernel.UserMessage} 
					#key: #_Help 
					#defaultString: '&amp;Help' 
					#catalogID: #menus ) 
				#nameKey: #help 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 
							#(#{Kernel.UserMessage} 
								#key: #aboutVWNC 
								#defaultString: 'About &amp;VisualWorks NonCommercial...' 
								#catalogID: #menus ) 
							#value: #helpAbout ) ) #(1 ) nil ) ) ) #(6 ) nil ) decodeAsLiteralArray</body>
</methods>

<methods>
<class-id>Tools.VisualLauncher</class-id> <category>actions</category>

<body package="Non-Commercialization" selector="helpGettingStartedWorkspace">helpGettingStartedWorkspace
	&lt;menuItem: #(#gettingStartedWorkspace #menus 'Getting Started Workspace...')
		nameKey: nil
		menu: #(#menuBar #help)
		position: 6.01&gt;
	
	Workspace openGettingStartedWorkspace.</body>

<body package="Non-Commercialization" selector="helpIvanTomekWorkspace">helpIvanTomekWorkspace
	&lt;menuItem: #(#ivanTomekWorkspace #menus 'Introductory Workspace...')
		nameKey: nil
		menu: #(#menuBar #help)
		position: 6.03&gt;
	
	Workspace openIvanTomekWorkspace.</body>

<body package="Non-Commercialization" selector="helpNoncommercialWorkspace">helpNoncommercialWorkspace
	&lt;menuItem: #(#helpNoncommercialWorkspace #menus 'Features Workspace...')
		nameKey: nil
		menu: #(#menuBar #help)
		position: 6.02&gt;
	
	Workspace openNonCommercialWorkspace.</body>
</methods>

<methods>
<class-id>UI.SimpleHelp class</class-id> <category>interface specs</category>

<body package="Non-Commercialization" selector="licenseSpec">licenseSpec
	"UIPainter new openOnClass: self andSelector: #licenseSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'License Agreement' 
			#min: #(#{Core.Point} 400 300 ) 
			#bounds: #(#{Graphics.Rectangle} 212 164 812 604 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.TextEditorSpec} 
					#layout: #(#{Graphics.LayoutFrame} 1 0 1 0 -1 1 -42 1 ) 
					#model: #helpString 
					#isReadOnly: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 0 0.288333 -36 1 0 0.436667 -4 1 ) 
					#name: #accept 
					#model: #accept 
					#tabable: false 
					#label: 'I Accept' 
					#isDefault: false ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 0 0.563333 -36 1 0 0.711667 -4 1 ) 
					#name: #cancel 
					#model: #cancel 
					#tabable: false 
					#label: 'Quit' 
					#isDefault: false ) ) ) )</body>
</methods>

<do-it>"Imported Classes:"</do-it>

<do-it>self error: 'Attempting to file-in parcel imports.  Choose terminate or close'</do-it>

<class>
<name>NameSpace</name>
<environment>Kernel</environment>
<super>Kernel.GeneralNameSpace</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>parent name </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>System-Name Spaces</category>
<attributes>
<package>System-Name Spaces</package>
</attributes>
</class>

<class>
<name>VisualLauncher</name>
<environment>Tools</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>menuBar toolBar textCollector toolDock </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Tools-Misc</category>
<attributes>
<package>Tools-Misc</package>
</attributes>
</class>

</st-source>
