See also: Learn Dolphin Smalltalk
Smalltalk is undoubtedly one of the
most influential programming languages ever developed.
It was created way back in the ‘70s and early '80s
at a time when many programmers were still entering code
at a command prompt rather than into a half-way decent
text editor.
Smalltalk was to change all that. Unlike other languages,
Smalltalk had its own dedicated user interface. Its programming
environment included a multi-font editor, a graphical
debugger, overlapping windows and pop-up mouse menus.
Indeed, it was this environment that provided the inspiration
both for the Macintosh and, later on, for Windows.
You can follow
our tutorial using the free Squeak Smalltalk
shown here. When you want to evaluate some
code, right-click and select Do It from the
menu on the right. To evaluate code and display
the result, select Print It. Alternatively,
use the keyboard shortcuts ALT-D and ALT-P. |
|
|
In retrospect we can see now that Smalltalk was way
ahead of its time. Smalltalk programmers were using a
mouse a decade before most PC users had even seen one.
And while many of its Object Orientated features have,
in recent times, been adapted (though not necessarily
improved) by C++, C#, Delphi and Java, Smalltalk remains
more completely Object Orientated than any of these.
The great thing about Smalltalk is that it is not only
a powerful language but it is also enormous fun. If
you’ve
never used Smalltalk before, now’s a good time
to start. This month we’ll be providing you with
a simple step-by-step introduction to programming in
Smalltalk. And it won’t cost you a thing. Our
tutorial is based around Squeak – a
superb free Smalltalk development environment available
for Windows, Unix, the Mac and other platforms. Download
a copy of Squeak from www.squeak.org.
I am also very fond of the commercial Windows-based
system, Dolphin Smalltalk (http://www.object-arts.com)
and I shall therefore provide details of differences
between Squeak and Dolphin Smalltalk when appropriate.
Alternatively,
you can use another Smalltalk system such
as the commercial Dolphin Smalltalk for Windows
seen here. Its menu lets you Evaluate code
or evaluate and Display. This time the keyboard
shortcuts are CTRL-E and CTRL-D |
|
|
Look, No Code!
If you are used to programming in some other language,
one of the things you'll find odd about Smalltalk is
that you can run your code - all of it or just selected
bits of it - whenever you like. You don't need to compile
it. You don't need to select 'Run' from a menu. You don't
even need to write a complete program. A single statement
is enough.
To see what I mean, let's see how simple it is to write
the classic 'Hello world' program in Smalltalk. In fact,
this is so simple, it can be done in zero lines of code.
Don't believe it? Then try it out.
You can drag special types of window such as a Workspace
or Transcript from Squeak's Tools palette
First, we'll open up a new workspace. To do this, click
the Tools tab on the right of the Squeak environment.
This will cause a vertical page of tools to appear. Click
the Workspace tool and drag it into the main Squeak work
area (in Dolphin Smalltalk, just select File, New).
This opens up an empty window. In this window, enter
the following, making sure that it is enclosed by single
quotes:
'Hello world'
Now, with your cursor still on the on this line of
text, press ALT-P (or CTRL-D in Dolphin) . This
tells Smalltalk to evaluate the expression and display
or ‘print’ the
result. It immediately displays 'Hello world'.
And not a single line of programming code in sight!
OK, but maybe you think this is a cheat. How can you
be sure that Smalltalk actually evaluated the expression
rather than just copying and pasting the text? Well,
let's try it out with a bit of maths. On a new line,
enter this expression:
2.5 * 100
Now with your cursor on this line, press ALT-P again.
This time it returns the result 250.0. It clearly hasn’t
copied and pasted that! It has evaluated the expression
and displayed the result in just the same way that it
evaluated the string expression, 'Hello world', and displayed
the result - only in that case the result happened to
be the same as the original string.
In these two examples, the string, 'Hello world', and
the floating point number, 2.5, are both Smalltalk objects.
An object on its own evaluates to itself. On a new line,
type the number, 2.5, and press ALT-P. It returns itself,
2.5.
Objects of Attraction
Generally it is more useful to do something with an
object. In most programming languages, you would do this
by sending data, such as a string or a floating point
number, to a function called, let's say Squared() or
Reverse(). The function would then return some value.
In Smalltalk, a String, a Float or any other type of
object, has all its own functions or 'methods' bound
into it. This is a bit like the objects in other OOP
(Object Orientated Programming) languages only more so.
In Smalltalk, everything is an object. Other languages,
even a fairly 'pure' OOP language such as Java, make
exceptions to this rule for 'primitives' such as integers
and floats.
In Smalltalk, on the other hand, an integer or a floating
point number is a true object and the object itself knows
how (that is, it contains the necessary methods) to do
maths. All you have to do is to send it an appropriate
message. On a new line, enter and print (ALT-P) this
expression:
2.5 squared
Similarly, a string is an object that knows how to
do string operations. Enter and print this:
'Hello world' reverse
Getting The Message
Now load our tutorial file, Smalltalk1.st. If you are
using Squeak do this by first dragging a File List from
the Tools palette. Use its top-left pane to navigate
to the appropriate directory. Highlight the file Smalltalk1.st in the top-right pane. Right-click to pop up a menu and
select ‘workspace with contents’ Users of
Dolphin Smalltalk can simply load the tutorial file using
the File, Open menu in one of the Workspace windows.
Use the File List to find and load our tutorial file
into Squeak
This tutorial document contains lots of code fragments
that you can try out as you go along. We'll be explaining
the essential features of the code is in this tutorial,
though you will also find a few extra examples in the
document itself. When I tell you to print or display code, you can do so by pressing ALT-P in Squeak (or CTRL-D in Dolphin Smalltalk). When I say evaluate some code,
press ALT-D in Squeak (or CTRL-E in Dolphin). Be sure
to print or evaluate every code fragment in the correct
order as this has the effect of creating objects required
by other pieces of code later in the document.
The first thing to notice is that this document is
liberally peppered with explanatory text enclosed between
double-quotes. In some programming languages double-quotes
are used to delimit strings. In Smalltalk they are used
to enclose comments. These comments are ignored by Smalltalk.
Now let's look at the first bits of Smalltalk code.
As I said earlier, everything in Smalltalk, including
a number, is an object that evaluates to itself. If you
are familiar with other OOP languages, you will know
that an object is defined by a class. In other words,
a Class is the type of an object.
A Class is a generalised description of an individual
object in the same that that a Person or a Dog is a generalised
description of individual people and dogs such as Wallace
and Grommit or Charlie Brown and Snoopy. Each object,
such as Grommit, Snoopy, 100 or 1000 is said to be the
instance of its Class - such as a Dog class or a SmallInteger
class.
In Smalltalk, you can easily find out which class each
object belongs to. Find the first few lines of code in
our sample file, starting with '100 class.' and ALT-P Print
(or CTRL-D Display in Dolphin) each line, one
by one.
In these examples, 'class' is a message that is sent
to each of the objects. So far we've looked at several
one-word messages such as 'squared' and 'reverse' with
no other data supplied as an argument. In fact, some
Smalltalk messages do take other objects as arguments.
These are called 'binary messages'.
In Smalltalk, even mathematical operators such as '+',
'-' and '*' are binary messages. Using Smalltalk, display
the expression 2 * 10. As expected, it returns the value,
20. Strictly speaking, the '*' symbol is a message that's
sent to the first number object, 2, with the second object,
20, as an argument.
But it's probably easier to understand binary messages
that don't look like mathematical operators. For example,
the 'at:' message can be sent to a String object with
an Integer argument. Display the results of this expression:
'Smalltalk is wonderful!' at: 1
It returns the value, $S. This is the character at
position 1 in the string object. In Smalltalk, a single
character is denoted by a dollar sign prefix.
Some messages have two or more parts. Normally each
part is terminated by a colon. For example, copyFrom:to: is a two-part message that can be sent to a String object
with two integer arguments, as follows:
'Smalltalk is wonderful!' copyFrom: 1 to: 9
Incidentally, you may be wondering what happens if
you send the wrong message to an object or pass an inappropriate
argument to a message. Well, give it a go. Try copyFrom:to: with a number:
123456789 copyFrom: 1 to: 9
A dialog box pops up to tell you that the SmallInteger
class does not understand the message copyFrom:to:.
There are various buttons that you can click on this
dialog. If you want to cancel the operation and get back
to work, you might click ‘Abandon’ ('Terminate'
in Dolphin). For now, though, let's see what happens
when you click 'Debug'.
This loads up the Smalltalk debugging environment.
The first pane shows a 'stack trace' which is like a
short history list of the current error condition. You
can highlight lines in this trace in order to view the
code and active variables. Highlighting variables give
you information on their current values.
The Smalltalk debugger is a powerful tool. You may
want to experiment with the buttons across the top of
the workspace to step into and over code. When you've
finished experimenting with the debugger, close it and
return to the workspace containing our tutorial.
Brand New Key
Every program of any complexity needs to have variables
to store reusable values. In Smalltalk, you can assign
values using Pascal-like notation - colon-equals:
i := 10.
Notice that this expression is terminated by a full-stop.
For single lines of code, the full-stop is optional.
In longer programs, containing many lines of code, however,
it is obligatory, so you might as well get used to using
it now.
When you Evaluate or Print the assignment to i, Smalltalk
creates an object, i, of the appropriate type. In Smalltalk,
you don't need to specify the object type in advance.
It is deduced automatically from the type of data used
to initialise the object.
To understand this, Print these lines in the sample
document:
i := 10.
i.
i class.
Then follow the instructions in our tutorial document
to re-use the variable name, i, and assign a string value
to it. A variable such as i, which starts with a lower-case
letter, is a 'workspace variable'. It exists in the current
workspace window but nowhere else. Open a new Workspace
using the Tools palette (or select File, New in Dolphin
Smalltalk). In this new workspace enter and Print i.
You will see an error message stating that i is nil (or
undeclared). Switch back to the workspace containing
our tutorial, however, and you can once again Print the
value of i.
Variables beginning with a capital letter, have global
scope. Evaluate this line in our tutorial:
Hello := 'Hello from the world of Smalltalk!'
A dialog pops up or menu pops up. Use this to declare
Hello as a global variable. Now enter Hello in a new
Workspace window and Print it. Apparently the Hello variable,
unlike the i variable, is available throughout the Smalltalk
world.
Note that, when you finish a programming session in
Smalltalk, it is normal to save an 'image' (see 'Altered
Images' below). This has the effect of saving
the entire state of the Smalltalk world, complete with
any changes you have made during the current programming
session. If you make a habit of adding global variables,
your image will soon fill up with all kinds of unwanted
junk. So unless you are sure you really want your global
variables available next time you load Smalltalk, you
should delete them when you've finished. You do this
by sending Smalltalk a removeKey: message followed by
the name of the variable preceded by a hash (#) symbol.
Evaluating this line will remove Hello:
Smalltalk removeKey: #Hello.
With luck you should, by now, be starting to feel a
little more at home with the Smalltalk way of working.
Let's conclude for this month by taking a look at a few
other useful features of the language.
Let’s Stick Together
If you are working with strings, you will inevitably
want to concatenate them at some stage. In Smalltalk
that's simple, you just join strings together with a
comma. Try this:
x := 'Hello'.
y := 'world'.
z := x , ' ' , y.
Many programs need to work with lists of items stored
in arrays. Smalltalk arrays are delimited by round brackets
preceded by a hash character. Each element in an array
is separated from the next by a space (don't use a comma,
which would concatenate the elements!). Arrays can contain
elements all of the same data type or elements of mixed
data types. Here, for example, we create an array object,
called mixedlist, which contains a string, an integer,
an array of three integers and a character:
mixedlist := #( 'one' 2 (3 4 5) $6 ).
One of the useful things about Smalltalk is that many
different types of object can respond to the same message.
In OOP jargon, this is called 'polymorphism'. The 'class'
message is one example of this. You can send this message
to any object in order to obtain the name of its class:
'Hello' class.
10 class.
mixedlist class.
The comma concatenation message provides another example
of polymorphism. It can be used to concatenate arrays
as well as strings. Try displaying this:
#(1 2 3 ), #(4 5 6).
Sometimes you may need to evaulate code in a workspace
window like the one at the bottom here and view output
in the Transcript window, shown above it
The semi-colon is another handy piece of Smalltalk
punctuation. You can use it to divide multiple messages
to send to the same receiver object. For example, this
code sends both the cr (carriage return) message and
the show: message to the Transcript (the System Transcript
window) object:
Transcript cr; show: ob.
Often you may want to display a string data as output
from your own code. To display numerical values you can
use the printString message as follows:
Transcript cr; show: 10 printString.
Of course, it's all very well writing single lines
of code. But how do you get Smalltalk to execute whole
blocks of code? Simple, you put each code block into
square brackets. Here's an example that prints 'Hello'
and a carriage return in the Transcript window ten times:
10 timesRepeat: [Transcript show: 'Hello'; cr].
Here is a more complete example which prints the object
and class of each item in the mixedlist object we created
earlier:
| a |
a := 1.
mixedlist size timesRepeat: [
ob := mixedlist at: a.
Transcript cr; show: '[', a printString , '] ',
ob printString, ' is an object of the Class: ',
ob class printString.
a := a + 1.
].
The above example demonstrates yet another type of
Smalltalk variable. Here 'a' has been enclosed by two
vertical bar characters which make it a temporary variable.
This means that 'a' will automatically be destroyed after
the code has finished running. If you try to display
'a' after evaluating this code, Smalltalk will complain
that the variable has not been declared.
If you've followed our tutorial to this point, you
now know quite a lot about Smalltalk's classes, its programming
syntax and the Smalltalk development environment. We'll
be doing some more adventurous Smalltalk programming
next month.
Before you exit Smalltalk, you may decide to take a ‘snapshot’ of
the current state of the Smalltalk system so that it
can be restored as it is the next time you use it. This
is called saving an image of Smalltalk. In Squeak, you
can save an image using the Save button on the panel
which appears when you click the Squeak tab on the left
of the workplace. In Dolphin Smalltalk you can select
File, Save Image.
The Smalltalk image contains all the objects you have
created, all the variables you have used and all the
text you have entered into windows. It even contains
information on the number and position of the windows
you've opened on screen. By saving the image, you make
it possible to pick up precisely where you left off when
you next run Smalltalk.
There is a downside to this, however. If you make a
habit of adding 'throw-away' code or variables to the
Dolphin image, you will eventually fill the system with
unwanted junk. For now, try not to use global variables
unless absolutely necessary. Any global variables you
no longer need should be deleted using Smalltalk
removeKey:.
For example, you would evaluate this code to delete a
global variable named GlobVar.
Smalltalk removeKey: #GlobVar.
Don't be tempted to change the source code of existing
classes and methods in the Class Browser. Doing so could
corrupt the Smalltalk system itself. If, for any reason,
you have experienced a system crash, or if you really
don't want to save the work you've done during the current
session, don't save the image.
June 2005 |