Frequently Asked Questions

Here are answers to questions that new users frequently are interested in knowing the answer to. (FAQ means "Frequently Asked Questions") If you don't find your answer here, please drop a comment.

Introduction (10)
What is "The Smalltalk for those who can type" supposed to mean?

It is a pun on the usage of a text editor (and thus using the keyboard more, and the mouse less) to write programs for GNU Smalltalk, which sets it different from other Smalltalk.

What is Smalltalk?

Smalltalk is a programming language, though very often the term is used to indicate a programming environment for the language. Note that the t in Smalltalk is lowercase.

GNU Smalltalk implements the recognized ANSI standard for the Smalltalk language, which is ultimately a descendant of the Smalltalk-80 language developed at Xerox PARC. Much of the class library is identical to that of Smalltalk-80: they both have objects, classes, single inheritance, blocks, garbage collections, collections, streams, and many other bits. In addition to this, GNU Smalltalk provides other classes including networking and GUI programming.

How does Smalltalk look like?

Let's define a class called Person, holding a name and an age. (Note: this code only works in Smalltalk 2.95a and later. The syntax for previous versions is more verbose and less clear).

Object subclass: Person [
    | name age |
    Person class >> name: aString age: anInteger [
        ^self new name: aString; age: anInteger; yourself
    ]

    name [ ^name ]
    name: aString [ name := aString ]
    age [ ^age ]
    age: anInteger [ age := anInteger ]

    printOn: aStream [
        aStream << ('%1 (%2)' % {name. age})
    ]
]

Now, let's try it out:

(Person name: 'Paolo' age: 27)    "returns Paolo (27)"

Let's add two of them into a collection:

coll := {
   Person name: 'Paolo' age: 27.
   Person name: 'Luisa' age: 28.
}

... so that we can sort them:

coll asSortedCollection: [ :x :y | x name <= y name ]
coll asSortedCollection: [ :x :y | x age <= y age ]

We can also load people from a file. This uses a powerful tool for iteration known as the stream:

file := (File name: 'foo') readStream.

The following lines modify the stream in place. That is, each line returns another stream:

lines := file lines.
lines := lines select: [ :line | line ~ '^[A-Za-z]+ [0-9]+$' ].
fields := lines collect: [ :line | line subStrings ].
people := fields collect: [ :data |
            Person name: data first age: data second asInteger ].

These lines operate on different kinds of stream: one that returns lines, one that filters away invalid data, one that processes what remains, and one that finally creates Person objects. However, all of them operate in the same way.

Also note that so far the code has not read a single line from the file! This allows big amounts of data to be processed efficiently. Continuing the example, the following iteration command prints the people in the file, keeping in memory only one line at a time:

people do: [ :each | each printNl ]

That's it!

How do I get GNU Smalltalk?

See the download section of this site.

If you are interested in development versions, you might also use the git repository (or the CVS mirror) that host the most recent code for GNU Smalltalk.

How stable is GNU Smalltalk? How scalable? How fast?

It is quite stable. There are bugs for sure in the virtual machine, but unless you're unlucky you shouldn't be affected. This is especially true for the stable branch, where only changes to improve stability are made; development releases are by their very nature less stable.

It is quite scalable, even though the garbage collector performs worse once you have more than 150-200 MB of live data. Very long strings also do not perform as well as they could. In general, object-orientation makes it easier to pick good data structures (such as streams).

It is quite fast. While GNU Smalltalk has an experimental just-in-time compiler, even the bytecode interpreter should be faster than most other scripting languages. However, GNU Smalltalk's base classes are written entirely in Smalltalk (unlike Python or Lua, for example). While this gives more flexibility to the programmer, programs that heavily use dictionaries may run slower than the equivalent programs in other languages.

Is there a GNU Smalltalk tutorial?

Yes, there is a tutorial that is part of the GNU Smalltalk manual. See here for an online version.

You may also be interested in Canol Gokel's book "Computer Programming using GNU Smalltalk". You can get the e-book version for free, or buy a printed version.

How do I submit bug reports and patches for GNU Smalltalk?

There is a mailing list. See also the community section of this web site.

Does copyright restrict the use of GNU Smalltalk?

It does, but in general you don't need to worry much about the licensing of your Smalltalk programs.

The class library is licensed under the GNU LGPL. Thus, it permits using the library together with non-free programs.

The virtual machine and the bindings to external libraries are licensed under the GNU GPL, with a special exception that allows Smalltalk programs to be linked with the functions exported by the virtual machine and said bindings.

Where's the GUI?

GNU Smalltalk does not by default start a full-blown integrated development environment. However, one is available and can be started with this command:

gst-blox

The latest git versions include a new IDE, called VisualGST, that can be started with this command instead:

gst-browser

My question is not listed here!

Write it in a comment to this question.

Comparison (4)
What is cool about Smalltalk?

Smalltalk is an object-oriented programming language with a uniform programming model. Unlike many other languages, learning the Smalltalk programming language is easy because there are just a few concepts to grasp. Everything is an object in Smalltalk (including number, string, character, code blocks, and classes themselves), and everything is done through a single paradigm, that of sending messages from one object to another.

Many cool and revolutionary ideas were conceived from the Smalltalk community, including the very idea of window-based, graphical user interfaces. Smalltalk systems are open, as source code for every class is available and modifiable, including all the kernel classes; being free software, GNU Smalltalk extends this openness to the virtual machine, and complements it with the freedom to redistribute and publish your improvements.

What else is cool about GNU Smalltalk?

First of all, it is free software. This means that you can play with it and understand how it works, break it and understand why it broke, fix it and enjoy having fixed it.

Compared to other Smalltalk implementations, GNU Smalltalk is very different in one aspect: it is pragmatically designed to be a tool rather than an environment. It complements other tools that you use in your daily work, without any pretense of completely replacing them. This also provides a smoother learning curve for people who know other scripting languages such as Python or Ruby.

How does GNU Smalltalk compare to Python or Ruby?

Both Python and Ruby are object oriented languages meant to provide a smooth transition from procedural to OO programming styles. Smalltalk, by contrast, is object only—you can't do anything serious without understanding objects and inheritance. By providing procedural training wheels, Python and Ruby meant to ‘fix’ one of the features that may have kept Smalltalk out of the mainstream.

However, it is actually not clear whether this is true, because the two families of scripting and object-oriented languages were strongly separated until recently. On one hand, object-oriented programming skills are (luckily) widespread nowadays, but were not when Perl and other scripting languages were introduced. On the other hand, the idea of powerful scripting languages merging advanced features (such functional and object-oriented programming) and emphasizing rapid prototyping was nowhere in sight when Smalltalk was created. In fact, most Smalltalk environments are not designed with scripting in mind.

Smalltalk (and GNU Smalltalk in particular) is much more similar to Ruby than it is to Python. Both are pure OO languages, though Ruby can masquerade as a procedural one; both have no functions, only method calls. Both have always had many features that were only recently retrofitted in Python: a unified type/class hierarchy, metaclasses, the ability to subclass everything, uniform method invocation, transparent arithmetic on large integers, and a powerful set of collection classes and iterators.

Like Python, and unlike Ruby, GNU Smalltalk's syntax and design philosophy are meant to have as few as possible syntactic variabilities. Shortly put, it was not influenced by Perl. No optional syntax elements (including keywords, since Smalltalk has only a couple of operators and five reserved variables—the only keyword could be said to be super). This also means a little fewer commodities (here documents, for example), but in general means cleaner code.

If you like Perl, you will like Ruby and be right at home with its syntax. If you like Python, you may like Smalltalk more than Ruby and be right at home with its semantics.

Is GNU Smalltalk a complete implementation of Smalltalk?

GNU Smalltalk is a complete implementation of the Smalltalk language. In fact, it is a superset, since some features (regular expressions, streams, packages, namespaces, etc.) were absent or more limited in the original Smalltalk-80 specification (the Blue Book).

GNU Smalltalk also includes a graphical Smalltalk environment. The quality of the environment is low compared to modern IDEs (including other Smalltalk dialects); however, this does not hamper GNU Smalltalk's main intended utilization as a scripting language.

Community (5)
How do I join the GNU Smalltalk community?

Assuming you have already downloaded GNU Smalltalk and tried it out a little, you can join the GNU Smalltalk mailing list. That's the primary means to share your experience about GNU Smalltalk, or otherwise assist the GNU Smalltalk project with your development skills.

You can discuss things freely with other developers and enthusiasts on the #gnu-smalltalk IRC channel on Freenode.

Where do I find interesting links about GNU Smalltalk?

Many interesting texts are published in the blog section of this site. If you come across anything useful, make sure to note it in the wiki so that other people can peruse it.

Where can I put my cool GNU Smalltalk example/tutorial? (or where can I find some?)

Most likely, the wiki is the correct place. In particular, there is an examples page.

Can you help hosting a project on your site?

Yes. You will have to put the source code elsewhere, however by registering on the Hosted projects section you will be access to an issue tracker and your package will be easily downloadable into GNU Smalltalk.

The code will be hosted elsewhere; a common choice is GitHub. You will have to provide a link to the repository; this is done through an additional level of indirection.

In a project's edit page you can specify a URL to a package.xml file. Usually, this URL points inside a source code repository, for example to a gitweb or GitHub page. It usually looks like http://github.com/NicolasPetton/iliad/raw/master/package.xml. Inside this package.xml file, the <url> tag will point to the repository (svn or git) containing the same package.xml file at its root, for example git://github.com/NicolasPetton/iliad.git. You can specify a branch by appending its name to the end of the URL preceded by a hash sign, for example .../iliad.git#stable.

This additional indirection may seems like a useless complication, but it makes it easier for the gst-package tool (and ultimately for your users) to upgrade your package.

What should I do if I find spam on the GNU Smalltalk web site?

Please open a bug report. You do not need to include the path to the spam comments or pages if they were left in the last few days.

Anyway, spammers have little or nothing to gain, since links within comments and wiki pages are marked as nofollow.

Usage (13)
How do I convert Squeak code to GNU Smalltalk?

gst-convert can be used. It also supports rewrite rules to fix dialect incompatibilities automatically. You can write a script called, for example, gst-squeak like this one:

#! /bin/sh
#
# usage: gst-squeak SOURCE DEST
#
# Converts Squeak code to GNU Smalltalk

exec gst-convert -f squeak \
  -r'Float->FloatD' \
  -r'BlockContext->BlockClosure' \
  -r'MessageSend->DirectedMessage' \
  -r'DateAndTime->DateTime' \
  -r'TimeStamp current->DateTime now' \
  -r'TimeStamp->DateTime' \
  -r'ProtoObject->nil' \
  -r'UnhandledError->SystemExceptions.UnhandledException' \
  -r'Date current->Date today' \
  -r'(``@object and: ``@arg1 and: ``@arg2 )->
     ((``@object and: ``@arg1) and: ``@arg2)' \
  -r'(``@object ifNil: ``@arg ifNotNil: [ | `@t2 | `@.s2 ] )-> 
     (``@object ifNil: ``@arg ifNotNil: [ :foo || `@t2 | `@.s2 ])' \
  -r'(``@object ifNotNil: [ | `@t2 | `@.s2 ] ifNil: ``@arg )->
     (``@object ifNotNil: [ :foo || `@t2 | `@.s2 ] ifNil: ``@arg)' \
  -r'(``@object ifNotNil: [ | `@t2 | `@.s2 ] )->
     (``@object ifNotNil: [ :foo || `@t2 | `@.s2 ])' \
  -r'(``@object ifNil: ``@arg1 ifNotNilDo: ``@arg2 )->
     (``@object ifNil: ``@arg1 ifNotNil: ``@arg2)' \
  -r'(``@object ifNotNilDo: ``@arg2 ifNil: ``@arg1 )->
     (``@object ifNotNil: ``@arg2 ifNil: ``@arg1)' \
  -r'(``@object ifNotNilDo: ``@arg2 )->
     (``@object ifNotNil: ``@arg2)' \
  -r'(``@object doIfNotNil: ``@arg2 )->
     (``@object ifNotNil: ``@arg2)' \
  -r'(``@object newFrom: ``@arg2 )->
     (``@object from: ``@arg2)' \
  -r'(Dictionary withAll: ``@arg2 )->
     (Dictionary from: ``@arg2)' \
  -r'(``@object evaluateWithArguments: ``@arg2 )->
     (``@object valueWithArguments: ``@arg2)' \
  -r'(``@object beginsWith: ``@arg2 )->
     (``@object startsWith: ``@arg2)' \
  -r'(``@object allSubInstancesDo: ``@arg2 )->
     (``@object allSubinstancesDo: ``@arg2)' \
  -r'(``@object directoryNamed: ``@arg2 )->
     (``@object / ``@arg2)' \
  -r'(``@object fileExists: ``@arg2 )->
     (``@object includes: ``@arg2)' \
  -r'(``@object readOnlyFileNamed: ``@arg2 )->
     (``@object / ``@arg2) readStream' \
  -r'(``@object forceNewFileNamed: ``@arg2 )->
     (``@object / ``@arg2) writeStream' \
  -r'(``@object caseInsensitiveLessOrEqual: ``@arg2 )->
     (``@object <= ``@arg2)' \
  -r'(``@object isZero)->
     (``@object = 0)' \
  -r'(``@object recursiveDelete)->
     (``@object all remove)' \
  -r'(``@object containingDirectory)->
     (``@object parent)' \
  -r'(FileDirectory default)->
     (Directory working)' \
  -r'(``@arg2 assureExistence)->
     (``@arg2 createDirectories)' \
  -r'(FileDirectory on: ``@arg2 )->
     (``@arg2 asFile)' \
  "$@"

What platforms does GNU Smalltalk run on?

GNU Smalltalk is developed and routinely tested under Linux and Darwin (the kernel of Mac OS X), and should run under most Unix systems (as well as under Windows, using Cygwin). A native port to Windows is in progress.

How do I use the GNU Smalltalk REP-loop?

First of all, the REP loop (or REPL) is short for read-eval-print-loop: when invoked normally, GNU Smalltalk will read Smalltalk code, evaluate it, print the result, until it is exited.

While working in the REPL, GNU Smalltalk will automatically add a period at the end of a line (to terminate a statement) if the Smalltalk syntax allows it. If you don't want the statement to terminate (e.g. if you want to continue a keyword message on the next line), wrap the statement in parentheses. For example, instead of this:

'abc' copyFrom: 1  "does not work, evaluates this line separately..."
      to: 2        "... and gives an error on this line"

you can do this:

('abc' copyFrom: 1
       to: 2)

I found a bug in GNU Smalltalk, how do I debug it/fix it?

There are comprehensive information on this in the Hacker's guide.

Why am I getting strange results with simple arithmetic operations?

Or, why is 3 + 5 * 4 = 32?

For some people, this is the least cool feature of Smalltalk. Operators don't have any precedence in Smalltalk and expressions are evaluated left-to-right:

3 + 5 * 4 = (3 + 5) * 4 = 8 * 4 = 32
3 + 4 * 5 = (3 + 4) * 5 = 7 * 5 = 35

In practice, this rarely matters, but it is still something to be aware of.

Huh, so why can't this be changed?

There are already millions of lines of Smalltalk code around the world, so any change in the language that invalidates more than a very small fraction of existing programs has to be frowned upon.

However, in the future, GNU Smalltalk may warn about such constructs. If you feel this is very important for you, bug people enough so that they listen and implement this feature.

Why is there no switch statement?

Well, various syntaxes have been proposed along the years, but no one was really satisfying.

There are many alternatives:

  • You can use #ifTrue:ifFalse: repeatedly.
  • You can create a dictionary or, in more complex cases, a dictionary of blocks
  • You can use polymorphism
Why is there no goto statement?

Anticipated return can be used to jump out of a method, and that's enough to emulate structured gotos like C's break statements.

Otherwise, you can use exceptions to provide a "structured goto" that even works across function calls. Exceptions are particularly powerful in Smalltalk, as they allow resuming the execution at the point the exception was thrown, as well as retrying the execution of the piece of code that triggered an exception.

^[ self assert: (Date daysInMonth: #feb forYear: Date today year) = 29 ]
    on: Error
    do: [ :ex |
        (Delay forSeconds: Time secondsPerDay) wait.
        ex retry ]

Exceptions should be able to conveniently emulate all reasonable uses of "goto".

How do I read input from the keyboard?

You can use the special stdin file, which you can also access (if you prefer) as FileStream stdin. Like this:

   line := stdin nextLine

or if you want a number

   n := stdin nextLine asInteger

Why should I use a separate image? How would I create one?

In GNU Smalltalk, an image is used mostly as a cache of preloaded packages. In general, if you plan to use a package in a script, development will be quicker if you preload packages into your image.

Creating an image
Start GNU Smalltalk, and save a snapshot of the running system

st> ObjectMemory snapshot: 'my-image.im'

Loading a package into an image
Use the gst-load script bundled with GNU Smalltalk. For example, to load NetClients, use this:

$ gst-load --image-file=my-image.im NetClients

Why should I modify the virtual machine?

You probably don't need to do it. GNU Smalltalk supports dynamic linking, and it's probably easier if you make a plug-in module instead. This is how most library bindings work.

If you are interested in how the virtual machine works, however, modifying it may be very instructive. The code is well commented.

What is a relocatable install? Are GNU Smalltalk installations relocatable?

A relocatable program can be moved or copied to a different location on the filesystem. A program supports a relocatable install if a user can copy a program, installed by another user on the same machine, to his home directory, and have it work correctly.

Versions of GNU Smalltalk up to 3.0a are never relocatable. Newer versions are relocatable under special conditions only. These are:

  1. the exec-prefix and prefix should be identical;
  2. the installation should reside entirely within the prefix;
  3. on systems other than Windows or Linux, shared libraries should be disabled.
  4. under Windows, you should use Libtool 2.2 (i.e. versions posterior to 3.1).

Item 2 usually means that packages offered by Linux distributions are not relocatable, because they install the image in /var (outside the prefix). However, user installations created with a standard ./configure will be relocatable. GNU Smalltalk's configure script prints whether the installation will be relocatable.

If you want a relocatable install, it is suggested that you configure with a non-existent prefix such as "--prefix=/nonexistent". Otherwise, on some OSes the executable will remember the location of shared libraries and will look for its shared libraries first in the original installation directory and only then in the relocated directory. To move the installation, you can install into a staging area with make DESTDIR and finish the installation from there.

For example, this will create a binary .tar.gz file that can be unpacked in multiple places (e.g. in /usr/local or $HOME).

 ./configure --prefix=/nonexistent
 make
 make install DESTDIR=`pwd`
 (cd nonexistent && tar cvf - .) > ../gnu-smalltalk-binary.tar.gz

Can I do a "debug build" of GNU Smalltalk?

Debug information is usually included in the build. However, usually the resulting optimized binary is very hard to debug. So you can compile without optimization by configuring with ./configure CFLAGS=-g (or otherwise passing CFLAGS=-g to make).

You can also add the --enable-checking option to configure, which adds extra assertions at the cost of performance.

After starting gdb and before starting the VM, you have to type handle SIGSEGV noprint to ignore signals generated by the generational GC machinery.

Features (10)
Can GNU Smalltalk programs access databases?

Yes, versions starting with 3.0 have a DBI-like library supporting PostgreSQL, MySQL and SQLite. In addition, you can use Glorp to map objects and relational databases.

Does GNU Smalltalk support Unicode and MBCS?

Yes. Strings however are processed (e.g. read from a file) byte-per-byte. If you need per-character processing, you should load the Iconv package and convert strings to UnicodeString, using the #asUnicodeString method.

Regular expression matching cannot operate directly on UnicodeString objects. This means that regular expression matching will not work with most multi-byte character encodings (it will work with UTF-8).

What is VFS?

VFS is GNU Smalltalk's Virtual FileSystem layer. VFS allows GNU Smalltalk programs to use archive files (.gz, .tar, .zip, etc.) and URLs transparently. The first implementation of VFS was inspired by the homonymous feature of the Midnight Commander, later incorporated in GNOME and now called GVFS.

VFS is a fundamental part of the implementation of .star packages.

What are .star packages?

Starting from version 3.0, GNU Smalltalk supports grouping multiple files for a single package into a single archive. These are just .zip files, but they are rebranded .star (Smalltalk archive) for this purpose.

A valid .star file must include an XML description of the package in the top directory, in a file that must be called package.xml.

GNU Smalltalk includes gst-package, a tool to create and install .star files. Projects hosted on this site can be downloaded into a .star file using it, using a command like:

gst-package --download Iliad

to install the package system-wide, or

gst-package -t ~/.st --download Iliad

to install it in your home directory.

What is a generator?

A generator is a quick way to create a Stream. As you might have seen in an earlier question, streams are a powerful iteration tool that Smalltalk offers. A generator is a kind of pluggable stream, in that a user-supplied blocks defines which values are in a stream.

For example, here is an empty generator and two infinite generators:

Generator on: [ :gen | ]
Generator on: [ :gen | [ gen yield: 1 ] repeat ]
Generator inject: 1 into: [ :value | value + 1 ]

As a more concrete example, these lines process a file and create Person objects out of the file:

lines := file lines.
lines := lines select: [ :line | line ~ '^[A-Za-z]+ [0-9]+$' ].
fields := lines collect: [ :line | line subStrings ].
people := fields collect: [ :data |
            Person name: data first age: data second asInteger ].

Let's see how to rewrite them to use a single Generator instead:

Generator on: [ :gen |
    file linesDo: [ :line || data |
        line ~ '^[A-Za-z]+ [0-9]+$' ifTrue: [
            data := line subStrings.
            gen yield: (Person name: data first age: data second asInteger) ] ] ].

As you can see, #select: becomes an if-statement, and the value from the final stream is yielded to the user of the generator.

Generators use continuations, but they shield the users from their complexity by presenting the same simple interface as streams.

Does GNU Smalltalk run Seaside?

The first stable version supporting Seaside will be 3.1.

The first release candidate, 3.0a, was released on March 7th 2008.

How do I download a document from the web?

First, make sure the NetClients package is loaded. You can use this Smalltalk code:

PackageLoader fileInPackage: 'NetClients'

Alternatively, you can create a separate image that preloads the package (that's explained in another FAQ).

Once you have the package loaded, you can open a FileStream on a remote URL just like you would do for a local file:

(FileStream open: 'http://www.gnu.org/' mode: FileStream read) contents

What is a continuation and why should I care?

A continuation object contains a snapshot of the program execution including all the local variables, and allows to restore the execution of the program from where the object was created. GNU Smalltalk supports continuations.

You will probably never use continuations directly, but they enable doing very interesting things, such as generators and continuation-based web frameworks.

How do threads work?

GNU Smalltalk uses preemptive green (non-native) threads; that is, multiple Smalltalk processes are run by the virtual machine in one operating system thread. The main disadvantage to this approach is that it is impossible to use multiple CPUs even when the machine has them available; for single-processor CPUs, green threads are faster than operating system threads, because they make context switches cheaper.

Threads are not preempted after a given amount of time, but other events could in general cause the current thread to be suspended: a higher priority process being resumed, a timer being fired, or I/O becoming possible.

Is it possible to set breakpoints or watch conditions?

Not yet, though there is a minimal debugger example included in the examples, as well as support for debugging in the VM.

User login