Quick 30 Minute Introduction

Ok, so you really don't want to spend a lot of time to
see what's in here for you.
Give yourself 30 minutes.
Be aware, that that's a short time, only enough to get a very rough feeling on what
this is all about. We'll try anyway, to get you hooked...

There are multiple Smalltalk systems around, but the differences are much smaller
than usually thought; they all follow the same principles,
but differ on details in the implementation (speed),
the GUI (experimental vs. conservative)
and intended target users (experimental vs. business).
If you know one Smalltalk, you should not have problems to move on and feel
comfortable in any other (Its like switching from Java-Swing to Java-SWT,
or from one Visual-C to eclipse).

Smalltalk is different! It is not just another programming language,
but a combination of a powerful IDE,
a highly reflective and dynamic programming language,
and a comprehensive, well proven class library.
Smalltalk as a language alone, without IDE and class library does not make really sense
(although languages like Ruby and Python actually are almost that, and are successfull too).

Smalltalk is a much more dynamic environment
than anything you've ever seen before (with the exception of some Lisp systems, maybe):

Classes can be created, changed or removed at any time (especially: at run time).

Individual methods can be created, changed or removed at any time (especially: at run time).

The tools which make up the IDE can be made available even in deployed applications
(although, they are typically made invisible to the end-user).

Changes can be made while the program is running. Sounds strange at first, but
it means that you don't have to shutdown an application to fix bugs or add more features.

Code is installed and effective as soon as you have typed it in.
There is no extra compile, link and execute-the-program phase.
Therefore, programs are typically debugged while being coded.

Programming can be done in the living system - even in the debugger

Every bit of the system (except for the low-lvel virtual machine) is itself written in Smalltalk and open to be read and learned or even
to be changed and adapted to your needs. If you ever thought that some menu function is missing from your
favourite program, here you can easily change eveything.
Even while you are working with it.
If you find anything to improve, there is no need to wait for the next release.

The Smalltalk language is a programmer's dream:

Simple, very regular, elegant and readable syntax.
It may look strange and different at the beginning,
especially to programmers which are used to C-style languages,
but once you got it, many other languages may simply look ugly to you.

Entirely object oriented.
Down to integers, code, classes, stack frames and threads, everything
is defined by a class which specifies its behavior. Everywhere, you can add methods
to extent any class. There are no builtIn primitive classes, for which the behavior
is hidden.

Highly reflective.
Every information is available and even changeable at run time.
This includes the class inheritance, set of methods, private variables, globals and threads.
Classes are themself objects which respond to messages.

Highly dynamic
Any behavior can be changed at any time. You can access classes and methods by name, add, remove or change
their behavior. Code can be changed without a need to stop the program.
You can change the program in the debugger and proceed.

Higher order functions.
Functions can be created dynamically and treated like any other object.
Especially they can be returned as a value, passed as argument or stored in a private variable.
They are also used to implement a very powerful and easy to use collection and GUI class
hierarchies and control structures.
In Smalltalk, those functions are called "blocks" and have
full closure semantics
(same semantics as in the Scheme language but with a very nice syntax).

Sophisticated exception handling.
Smalltalk is one of the rare languages which provides proceedable exceptions.
These are the base for notifications, queries and other control structures which
are hard to implement in other languages.

The class library is mature and well proven:

Smalltalk has been in use for more than 35 years now, and a lot of
experience has flown into the implementation of its class libraries.
It provides one of the most sophisticated collection, stream and numeric class hierarchies.

Many of the modern GUI concepts and patterns originated in Smalltalk: MVC, observer, visitor
and many more.
The GUI libraries are powerful, flexible and portable.

The tools are a dream to work with:

The class browser is unreached in power.
Even after all those years, no other IDE is comparable.
Programs can be debugged and changed while running, and even in the debugger.
Turn around times are in the seconds range - you don't have to stop, recompile and restart for
a change to be made.

(notice the double quotes to ensure that the expression is passed as a single argument to the
stx program.)

You can also put a script into a file
and call it as:

stx -F "<filename>"

.
On Linux/Unix systems, make it executable and run it just like any other script:

bash$ cat script
#!stx --script
1 to:23 do:[:i |
'the factorial of %d is %d\n' printf:{ i . i factorial } on: Stdout
].
bash$ chmod +x script
bash$ ./script
the factorial of 1 is 1
the factorial of 2 is 2
the factorial of 3 is 6
the factorial of 4 is 24
...
the factorial of 22 is 1124000727777607680000
the factorial of 23 is 25852016738884976640000
bash$

Finally, ST/X can be started in an interactive line-by-line interpreter mode
with:

These options may be useful for little scripts or computations.
However, the real power lies in the integrated development envronment.
It is not very useful, to write longer programs in a dumb (non-Smalltalk-aware)
editor.
Therefore, for the following examples,
start the full ST/X IDE
with the command line:

This chapter demonstrates in 5 minutes, how to create a little standalone (fully compiled) demo application
with a GUI. The coding is not explained, as the goal is to give you an impression
of how an experienced Smalltalk programmer can make use of the tools.

In the Launcher, click on the "Open SystemBrowser" button:

to open the most useful tool, the SystemBrowser.
This is the programmer's main interface to write, change and to execute programs.

First notice, that the system browser is not file oriented.
You are presented the class- and method objects as they are present in the current system,
not with files.

Smalltalk does not normally need and use files for its operation
(but of course allows for source files to be used for code exchange
and also interacts with source code repositories
such as CVS or Mercurial for version management).
The browser shows the code base as it is present in your memory, not in some file.
When you change code in it, it is directly and immediately affecting the existing code
and possibly even code which is currently being executed.
This means, that you are living inside the system, and your programming
becomes part of the running program.

Second, notice that classes can be shown in various different organisations:
by name, inheritance, package, namespace and by category.
The default and the one also shown in the above picture is "by category".
This organization presents classes by their function,
even if you don't know the inheritance or the exact name.
Of course, there are also functions to search for a class by various
criteria - especially, by a matching name pattern, or if it calls for an operation in its code,
if it references another part of the system or if it contains a particular string or code sequence.

The top panes are named "class-category-list", "class-list", "method-category" or "protocol"-list and
"method-list" from left to right. They are used to select the class and method (= function).
There is also a variable list, which we ignore for now.
When anything is selected in the upper area,
the corresponding code is shown in the code-view area at the bottom.

Some people like to work with a hierarchical or package organisation.
Try the browser's "View"-menu to see those.

In this tutorial, we want to create a new little application.
Applications are usually written as subclasses of the
ApplicationModel class,
which provides common functionality for window handling,
resource management, startup and release etc.
So we will need a new so-called "Application-class" to start with.
To create it, press the right button in the class-list-pane (the second pane in the upper area)
and select the "New-Application" item from the "New" submenu.

The following initial class definition template will be shown in the code-view:

Be aware that this is only a template - no real class has been
created at this time. You have to change and fill in the details as required.
Ignoring the other fields at the moment (they can be changed
at any time later easily), we will only
change the offered default name "NewApplication1" into something appropriate;
for example "HelloWorldApplication".

To do this, select the text which is to be changed with the mouse pointer, and
type in the new name. When you are finished,
select the "Accept" menu item from the
code view's right-button-menu (or press the green bar at the left, which performs the same action).
Pressing "Accept" ("accepting", for short)
tells the browser, that you are done with editing of whatever is shown in the code view,
and you want to make this change permanent.
In other words: "to let it create the new class as specified".

In other languages, or IDEs you'd say "compile" a class (although nothing has yet been compiled, actually).
All we did so far was to create a new class object, and if you look
at the accepted code, you will notice that this is actually an instance
creation message being sent to the parent class. An operation which can also
be performed by the program at execution time!.

You will be asked if you want the browser to generate some standard application framework
code for you. Confirm by clicking "Yes" (or "OK"). This is a convenient service provided by the
browser: whenever you create a new application class, it can generate a typical
framework of UI and menu components.
If you clicked on "Cancel" by accident,
find the corresponding "Create Initial Code" item in the class list's popup menu and select it.
Now, your new class should be presented as:

Notice the little "launch rocket" icon in the toolbar. This appears whenever a launchable
application class is being shown.
Click on it, to see the first appearance of our "hello world" application.

Editing the Menu
When playing with the application, you'll notice that the generated menu contains many items which
we do not need or want to change. Let us fix this.
In the browser, you'll find the menu specification on the class side
(in Smalltalk, both object instances
and classes are objects in the sense that their method protocol can be changed.
If you have a Java background, think of class methods as some kind of "static" class methods,
with the added benefit of being redefinable and inherited).

Click on the radio button named "Class" below the browser's class list.
You'll see "menu specs" in the method category list. Select it, then double click on
the now appearing "mainMenu" method entry in the rightmost method list.
A Menu Editor will appear:

In the left tree list, select and remove all entries except for the "Exit" item
(select, then either press the Delete-key,
or use the right-button menu).
Finally, save the changed menu specification
via the menu editor's "Save as Method" toolbar button, and close the menu editor.

Restart the hello world app via the "rocket-launch" button in the browser to see
the changed menu (in this case, we have to restart the application,
because by default, the menu is constructed once at startup of an application.
(We could have defined it to be constructed dynamically whenever clicked,
but that is described elsewhere.)

Editing the User Interface
Let us take a look at how user interfaces are edited. In the browser,
find the "windowSpec" method on the class side and double click on it.
A UI-painter window appears, together with a drawing canvas and a gallery of draggable widgets.
The drawing canvas represents the UI as it will look when the application
is eventually started. Here, in the editor, it is used to select and manipulate
the sub-parts of the UI. These are called widgets. Common widgets are buttons,
checkboxes, panes or input fields.

Let us enhance the application by adding a button to close the application window.
Drag a "close"-button from the gallery into the canvas:

Save the window specification ("Save as Method" button in the toolbar) and exit the UI-painter tool.
Then retry the HelloWorld application, and close it via the new button.

Notice that the UI-painter tool also shows a launch rocket button -
so you can also try the changed user interface right from within the UI painter,
without having to go back to the browser. You can keep the UI painter open or iconified if
you think that more changes are to be made soon.

All of the above did not involve any actual coding.
We were using automatically generated code or, as in case of the close button, were using code
as provided (inherited) by the ApplicationModel class.

Now we are going to add some real code to the application. First, reopen the UI painter tool
on the window specification.
Find and select the close button we have just added in the canvas view.
Notice that the widget tree expands the containers to make the selected widget visible.
Also find the two fields named "Text" and "Action" in the attribute area of the selected widget.
Change the text to something like "Press Me", and the action to the name of a method which
we are going to code in a minute, "pressMePressed".
Now, we have just told the button to call the "pressMePressed" function of our application
(which of course does not exist yet).

Click on the accept button at the bottom and then save the window spec again.
But do not close the tool. Instead, launch the application right
here via the tool's own rocket launcher toolbar button.

In your HelloWorld app, press this new button now. A debugger appears,
telling you, that "pressMePressed" was called,
but your application does not understand it.
This basically means, that an unimplemented function was called.
Of course, this was to be expected, because we have not yet defined
how the helloWorld app should react when the "Press Me" button is clicked.
We have not defined
what the "pressMePressed" response should be!

Close the debugger, and return back to the browser.
Notice, that your application is still open,
and you can press the non-functioning button again, if you like.
Being able to play with such an unfinished application is great
during development. You don't need any of the specified
callback methods until they are actually called.
This makes it easy to proceed in very small steps,
implementing and debugging code as it is written.
You may have noticed, that it is even possible to add or modify
code in the debugger itself, and then retry the just edited code.
This is the way most experienced Smalltalk programmers work, actually.

Back in the browser, switch to the instance side.
Then first create a new method category named "actions"
(in the method category/protocol view, which is the third list view), select this protocol,
and then enter the code:

This teaches the HelloWorldApplication a new trick:
how to respond to "pressMePressed".
Here, we tell it to send an "information:" message to Dialog,
passing the string "wow, it worked!" as argument.
Dialog happens to be a global variable, which is actually bound to a class
(yes, you remember? Classes are objects too, and can be sent messages just like regular objects).
If you are curious (and you should be), you can use a SystemBrowser to find out,
how Dialog responds to that and see how it is implemented.
And also see that there are many more helpful messages understood
by Dialog. If you feel attracted, you may now take a look at the syntax of
the Smalltalk programming language. An introductionary text is found in the
"Smalltalk Basics" chapter of the tutorial.

By the way: you can try code like this without a need to write an application or a test framework.
In the browser's
code view, simple select the whole line of code ("Dialog information:'....'") with the mouse
and evaluate it via the right button menu function "doIt".
An evaluator similar to Java's groovy is already built into the Smalltalk IDE (and has bee there for the past 30years!)

It is now time to save your work.
In the launcher, press the "Save Snapshot Image" button. This saves the state
of the whole system into a so called "snapshot" file. This not only saves the
application, but everything in the system. Including open browser windows, the contents
of any workspace or UI editors etc. Saving a snapshot is a good thing, when your
partner calls for dinner, and you want to continue later at exactly the same
place. When stx ist started the next time,
it will restore your session to that saved state.

Of course, the whole state is not what you need, when you want to give your new
application's source code to a friend
(the process of deploying a binary executable will be described later).

For this, a more fine-grain transport mechanism is useful:
the fileOut mechanism allows you to save individual classes or packages to a
source file. Try "Fileout As" in the class-list menu.
The resulting source file can be loaded into another Smalltalk either manually
via the FileBrowser application, or by evaluating

Smalltalk fileIn:'pathName'

in
a workspace or by another Smalltalk program (i.e. you can do all of this programmatically !).

It is also possible to save all of your session changes into a so-called change list.
This function is found in the launcher's "File" menu.
Session changes can also be loaded as described above.

Packaging

Saving individual source files is OK for tiny projects or demo and script classes like the above.
But if you have written a more complex application,
these will certainly be structured into at least one,
but usually into multiple packages.

Packages offer two big advantages: a) they can be loaded as a whole, and thus
be much easier transported, and b) they can be compiled into a binary class
library (which can later also be transported and loaded much faster as a single entity).

To package the application, first switch the browser to the "package"-viewing
mode (in the "View" menu):

A hierarchical package list appears, replacing the previous "category" pane.
You will notice, that your hello application is found packaged under "__NoProject__".
Obviously, we did not assign it to any real project, yet.
Select the "New" item and enter a reasonable package name
into the dialog that pops up:

The name must conform to a certain pattern, which is described later.
Skipping the details here, use "xxx:myDemoApp1" or "xxx:demos/myDemoApp1",
where "xxx" is something unique for you, such as your company name or initials.
It is recommended that you use at least a 2-level hierarchy.
This makes your life easier later, when you add more and more projects.

The package name is similar to package names in other programming languages like Java.
It should be a unique string, consisting of a so-called module (the xxx) and a path (the rest after the colon).
The reason for the module to be special is due to its special role when it comes to source code management and versioning.
We'll describe that later.

If this is an initial package creation, and no classes have yet been created for it,
the browser opens another dialog, asking if you like some initial application class to
be created for you. If you confirm with "Yes", it will basically create an empty helloWorld like
application for you. If you followed the above steps (i.e. you already have your application class
defined), click on the "No" button.

After you have created the new package, move your application class (via drag&drop) into this package
(or, if you prefer menus, use the class-list's "Move to Package..." menu function).

When done, your browser should show something like:

Notice, that the "create package" operation also created a new class, which is a so-called "package definition".
This class ("cg_myDemoApp1" in the above example) contains all the meta information required for later building and loading of the packaged classes,
such as which classes are contained, how to compile and how to deploy it.
We'll come to this in a minute...

Now, having things packaged, you may file-out the whole package, to transport
the application to a friend.
For this, select the browser's "FileOut As..." menu function from
the package list on the source machine.
This creates a single source file which can be copied to the target machine.

On the target machine, open a FileBrowser, select the file,
and load it with the fileIn menu operation.
Alternatively, evaluate

'<fileName>' asFilename fileIn

in a Workspace.

File Formats

The file format used with the above fileOut is an ascii format,
which should be supported by all Smalltalk implementations
(it is the traditional "chunk" file format).
To load it into another
Smalltalk, make sure to not use any of ST/X's syntax extensions and honor any limitations in class, method
and variable naming (for example, Squeak/Pharo does not allow for underscores in a name).
If you plan for portability, you may want to change the compiler's settings to warn you,
whenever you use non-portable dialect specific extensions.

You can also use the so called Monticello file format for transportation.
This is a package format supported by many Smalltalk dialects.
It is dialect independent,
meaning that it works when transporting
code to other Smalltalk systems like VisualWorks or Squeak.

However, be aware that there still might be other obstacles, such as dialect specific language syntax
(Namespace support, EOL comments etc.). and class hierarchy issues (superclass hierarchy being different)
to be considered. For example, the ApplicationModel hierarchy is very similar in the VisualWorks Smalltalk
dialect, whereas it is completely missing in Squeak/Pharo.
As a rule of thumb, only non-UI packages are typically portable to other Smalltalk dialects,
as each provides different UI framework libraries.

To create a Monticello package, open the Monitcello repository browser from the Launcher-menu,
define a directory as package resource directory (or use the default package-cache),
and select the "Monticello - Commit or Create mcz File" menu function from the browser's package list.
Notice that Monticello support is autoloaded - the browser does not show that menu item
before the monticello repository browser has been opened from the launcher.

In all of the above, your application was developed and executed inside the IDE.
For many projects and for your own tools and applications, this is just fine.
After all: who needs many individual
executables, if you can have them all in one single environment.
Reusability is much enhanced, if you have all the parts at your hand in a single browsable environment.

Actually, many Smalltalk programmers (including the author) have their own universe, in which they find
almost every piece of code they ever wrote. That is often a good source of bits and pieces for new
projects. Already written parts can be resused or at least taken as a base to start with.

However, if you want to deploy an application to any other (especially "non-Smalltalker") user,
you want to have a standalone application, which does not include all of the other stuff,
and which also hides the graphical IDE and other development tools.

So you will sooner or later want to create something which can be given to an arbitrary user
and which should be easily installable on her machine.
This is called "deloying an application".

To create a self-installing package for deployment, open the "Application Packager" from
the Launcher's "Tools" menu and follow its guiding.
This assistent leads you through the build process interactively.
A short introduction to the packager is found in the "Hello World in 5 Minutes" introduction.

As an alternative, you can check in the package and supporting
build files (makefiles and scripts) into a source repository (CVS or Mercurial)
from the browser's SCM menu, go to the shell command level,
check out the package there, and built the stand alone executable
via make. This is also the way to go, if you want automatic builds
using Jenkins or a similar automatic build tool.

Headless in this context stands for "without a GUI". Headless applications are command line
utilities or server applications. If they offer a user interface, it is typically a web interface.

The following gives an example of a command line utility, which can be used just like any other
Unix or MSWindows utility via the shell/cmd command line. It will read its stdin and write to
stdout, so it can be used in a pipe just like any other Unix command.

Create a new startup class in the system browser

change the class name to "DemoConsoleApp1",
"accept" (either in the menu or via CTRL-s or by clicking on the green save-bar),
and answer "Yes", when asked if the initial template code should be generated.

This creates a so called "startup class". Startup classes are the entry for stand-alone
programs - i.e. programs which are not loaded into the Smalltalk/X IDE, but run as self-standing
executables (console commands to be started on the command line or server programs, which are started
by init on Unix machines or as services/autoexec programs on Windows).

Define its behavior

Take a look at the generated code,
starting with the "main:"-method on the class side.

This will be the very first entry to your standalone program,
and corresponds to the main()-function of other programming languages.
It gets the command line as argument vector
(a sequenceable collection of strings, accessable by numeric index).

You will notice, that it does not do much,
but simply instantiates itself and calls the "main:" method on the instance side.
There, the arguments are extracted (you may remove the sample code there),
and a finally, a "realMain:" method is called.

If course, you can remove all this and put your own code right into "main:" on the class side;
however, we found it convenient to have separate methods, allow for easier subclassing.

The "realMain:" method is where the actual action is, and it looks like:

so obviously, it prints a hello-message followed by its command line arguments on a second line
on the stdout-stream.

Leave everything untouched for now.
Our next task is to package this into a deployable package, which we can deliver as binary
to other users.

First, we need to package them up.
In the browser, change the view-mode to "package",

and select the "New..." menu item from the package list menu:

in the dialog, choose "NonGUI-Application" in the type-field,
and enter a reasonable name for your package (the same notation as described above).
You should now see a class with the funny name in the class list.
Here, it is "stx_doc_coding_demoConsoleApp", because we used "stx:doc/coding/demoConsoleApp" as
package name.

Move your own class (the one with the main-method in it) into this package (drag&drop or via the class's "Move to Package" menu function).

Your browser should now show the two classes in the class list, as in the picture above.

Fix the Package

Before building, we have to tell the packager some details for the build-process and
the startup of the generated executable.
Go to the package definition (the class with the funny name), select "Class"-side protocol,
and take a look at the methods you find there.

Most interseting are: "productName" and "startupClassName".
The first gives the name of your application as shown in the installer, and it will
also be the name of the deployable package. Change the returned string to something useful,
like "HelloWorld Application".

The second is the startup definition in the executable. Change the value returned by "startupClassName"
to the name of your startup class; here to return the string 'DemoConsoleApp1'.

Build the Thing

In the package list, select the package class and open its popup menu, selecting
"Build" - "Generate Deployable Package":

Take a look at the Transcript. A bunch of messages should appear, showing what is going on.
The output should look like:

At the end, a filebrowser should open in the temporary build directory,
and you should see your deployable package there. Depending on the system you are working on,
this will be either a linux package, a self installing exe for Windows, or a mountable
dmg package for OSX.

The above screenshot was taken on a Mac
(on Windows, you would find a file named "setup_demoConsoleApp.exe",
and on Linux, you'd find "demoConsoleApp.pkg").

Two files are of interest here:

demoConsoleApp
is the binary executable, which you can execute in a shell;
but only in this folder,
as it refers to the shared class libraries and possibly other support files
(language translations etc.). Read below, for more options.

demoConsoleApp.dmg
is the wrapped up application for deployment (contains all required shared libraries
and other support files, such as language translation strings etc.).

To get shrink wrapped installers, separate installation of the underlying runtime system
and the application alone is needed, which is currently not supported by the automatic
package process. Actually, from a maintenance point of view, it makes for more stability
if each application is self contained and contains all-it-needs in its version;
as Smalltalk tends to be less used for small headless programs than for complex server-
or GUI apps, size issues are less of a problem in practice.

If you absolutely need (or want) to have a smaller footprint,
make sure that the ST/X shared libraries are installed in some standard place
(i.e. /usr/local/lib) and the remaining support files are found in "/opt/smalltalk".
Then ensure that the LD_LIBRARY_PATH is set correctly so the libs are found.

Once these settings are correct, all you need is the compiled executable, which is
typically quite small (40Kb in the above hello world example).