
Smalltalk ist eine objektorientierte Computersprache. Bereits 1980 arbeitete diese Sprache mit Bytecode, Virtual Machine und Garbage Collection, wie auch Java heute. Da die allgemein verfügbaren Computer zu dieser Zeit aber noch langsam waren, hat Smalltalk zu unrecht den Ruf, ebenfalls nicht perfomant genug zu sein. Gegenüber C++ ist das richtig, es ist aber mindestens so schnell wie Java, und hat den Vorteil, daß es bedeutend mehr Spaß macht, damit zu programmieren, was wohl jeder bestätigen wird, der dieses Tutorial auprobiert.
Die Beispiele in diesem Tutorial sind mit jeder Smalltalk-Umgebung nachvollziehbar, soweit nicht anders beschrieben. Falls Sie noch kein Smalltalk installiert haben, dann laden Sie sich z.B. Squeak, eine Open Source Smalltalk Umgebung.
Ab Squeak 3.0 ist man nach dem Start in einem Morphic Project. Klickt man mit der linken Maustaste (im folgenden heißt "klicken" immer mit der linken Maustaste, wenn nichts anderes beschrieben ist) auf dem Hintergrund, dann erscheint ein Menü, in dem man mit dem Menüpunkt "jump to project..." zu den bereits definierten Demo-Projekten wechselt.
Um die Beispiel nachzuvollziehen, ist es sinnvoll, ein eigenes Testprojekt anzulegen. Dazu auf den Hintergrund klicken, "open..." auswählen und dann den Menüpunkt "morphic project". Den Text "Unnamed1" anklicken und z.B. durch "Learning" ersetzen (mit der Eingabetaste bestätigen). Durch Klick innerhalb dieses Projektfensters wird es auf die gesamte Hauptfenstergröße vergrößert.
In diesem Projekt danach wieder mit Klick auf den Hintegrund das Menü anzeigen und "open..." gefolgt von "browser" anklicken. Außerdem noch ein "workspace" und ein "transcript" öffnen. Sie können die Fenster verschieben, indem Sie den Mauszeiger auf der Titelleiste plazieren und bei gedrückter linker Maustaste ziehen. Skalieren geht an den Rändern und Ecken geht analog (nur an den schwarzen Umrandungen anfassbar), wenn das Fenster mit Klick darauf zuvor aktiviert wurde.
Tippen Sie nun im Workspace-Fenster folgende Zeile ein:
Transcript show: 1 + 2
Danach mit der Maus alles markieren und mit der rechten Maustaste "do it" auswählen. Es erscheint im Transcript-Fenster die Ausgabe "3". Es geht auch ohne Transcript-Fenster. Löschen Sie den Workspace und tippen folgende Zeile ein:
1 + 2
Wenn Sie das markieren und im Kontextmenü "print it" auswählen, dann wird das Ergebnis direkt in den Workspace geschrieben. "do it" kann mit Alt-d und "print it" mit Alt-p direkt aufgerufen werden.

Das Beispiel und im Browser den "+"-Operator von "Number"
angezeigt.
| Name | Beispiel | "print it"-Ergebnis | Kommentar |
|---|---|---|---|
| Dezimalzahlen | 12345 | Die Anzahl Stellen bei Dezimalzahlen ist nur duch den verfügbaren Speicher begrenzt | |
| Dezimalzahlen beliebiger Basis | 2r1101 | 13 | Bei Zahlen mit beliebiger Basis wird zunächst die Basis angegeben (im Dezimalsystem), danach ein kleines "r", gefolgt von der Zahl. Bei einer Basis größer 10 werden die Großbuchstaben zur Darstellung der Ziffern verwendet |
| Fließkommazahlen | 1.2e-10 | ||
| Fließkommazahlen beliebiger Basis | 16r2BC.8 | 700.5 | |
| Strings | 'It''s easy!' |
Strings werden durch Hochkomma eingeschlossen, wobei ein Hochkomma innerhalb eines Strings durch zwei Hochkommatas dargestellt wird. Ein String kann auch ein Zeilenumbruch enthalten. |
In Smalltalk sind alle Daten in Objekten gespeichert, so auch Klassen oder Zahlen. Jedes Objekt stellt eine Methodenschnittstelle zur Verfügung, die festlegt, welche Nachrichten an dieses Objekt verschickt werden kann. Es gibt drei Arten von Nachrichten, aufgeführt in der Reihenfolge der Abarbeitung bei zusammengesetzten Ausdrücken:
| Priorität | Name | Beispiel | "print-it"-Ergebnis | Kommentar |
|---|---|---|---|---|
| 1 | unäre Nachrichten (unary message) | 5 factorial | 120 | 5! (Faktultät) = 1*2*3*4*5 |
| 2 | binäre Nachrichten (binary message) | 40 + 2 | 42 | |
| 3 | Schlüsselwort-Nachrichten (keyword message) | 27 gcd: 18 | 9 | gcd: greatest common divisor |
Zur Begriffsdefinition: "Empfänger" wird das Objekt genannt, von dem eine Methode aufgerufen wurde, der Methodenname, ohne Argumente, wird auch "Selektor" genannt und eine "Nachricht" besteht aus einem Empfänger und einen Selektor, optional mit Argumenten, wenn es eine binäre oder Schlüsselwort-Nachricht ist.
Alle Ausdrücke sind linksassoziativ. Die Reihenfolge der Abarbeitung kann durch Klammerung geändert werden, was besonders für Formeln wichtig sein kann, da die Grundregeln für alle Nachrichten gelten und somit nicht Punktrechnung vor Strichrechnung gilt:
1 + 2 * 3 ==> 9
1 + (2 * 3) ==> 7
Bei Nachrichten mit mehreren Argumenten ist jedes einzelne Argument benannt:
1 to: 10 by: 2 ==> liefert ein "Interval"-Objekt von 1 bis 10 mit der Schrittweite 2
Einige weitere nützliche Nachrichten ersetzen einen Taschenrechner, wobei die Anzahl Stellen bei ganzen Zahlen nur durch den verfügbaren Speicherplatz begrenzt wird:
7 raisedTo: 28 ==> 459986536544739960976801 (7 hoch 28)
16r7CE printStringBase: 2 ==> 2r11111001110 (Hexadezimalzahl 0x7CE als Binärzahl dargestellt)
Variablen in Smalltalk sind nicht typisiert. Mit dem := Operator (oder _, angezeigt als Pfeil-Links in Squeak) wird einer Variablen etwas zugewiesen. Dabei wird immer eine Referenz auf das zugewiesene Objekt gespeichert, nicht das Objekt selbst.
languages := OrderedCollection new.
languages add: 'C++'; add: 'Java'; add: 'Smalltalk'.
languagesCopy := languages.
Transcript show: languages removeLast; cr.
Transcript show: languagesCopy removeLast; cr.
In der ersten Zeile wird zunächst eine Instanz der Klasse "OrderedCollection" angelegt. Die Referenz auf das Objekt wird der Variablen "languages" zugewiesen. Der Punkt schließt den Befehl ab, ähnlich dem Semikolon in C. In der zweiten Zeile werden mit "add" der Collection Objekte hinzugefügt. Nützlich ist hierbei die Schreibweise mit einem Semikolon, um mehrere Nachrichten an dasselbe Objekt zu schicken. Alternativ hätte man das auch so schreiben können:
languages add: 'C++'. languages add: 'Java'. languages add: 'Smalltalk'.
Danach wird der Variablen "languagesCopy" eine Referenz auf diesselbe Collection zugewiesen. Die Nachricht "removeLast" entfernt das letzte Element der Collection und gibt es zurück. Wie zu sehen ist, hat die Befehlsfolge "languages removeLast" das letzte Element, 'Smalltalk', zurückgegeben. "languagesCopy removeLast" gibt aber 'Java' zurück, da es sich um dasselbe Collection-Objekt handelt.
Eine einfache Kontoverwaltung könnte so aussehen (Kommentare werden in Smalltalk in Anführungszeichen geschrieben):
"Konto anlegen und Kontostände eintragen" myAccount := OrderedCollection new. myAccount add: 1234; add: -43; add: 7543. "Kontostände summieren und ausgeben" sum := 0. myAccount do: [:value | sum := sum + value]. Transcript show: sum; cr.
Neu ist hierbei das Argument des "do:" Selektors in der vorletzten Zeile. Dort wird ein kompletter Code-Block in der Nachricht an das Objekt gesendet. In diesem Fall führt es den Code-Block für jedes Element der Collection aus und setzt dabei die temporäre Variable "value".
In der letzten Zeile wird das Ergebnis ausgegeben. Die "cr"-Nachricht ist dabei ein Zeilenvorschub.
In Java ist unter anderem sehr schön zu sehen, welchen Vorteil Smalltalk mit seinen nicht typisierten Variablen hat:
// Konto anlegen und Kontostände eintragen ArrayList myAccount = new ArrayList(); myAccount.add(new Integer(1234)); myAccount.add(new Integer(-43)); myAccount.add(new Integer(7543)); // Kontostände summieren und ausgeben Iterator i = myAccount.iterator(); int sum = 0; while (i.hasNext()) sum += ((Integer) i.next()).intValue(); System.out.println(sum);
In C++ kann man sich durch die STL zumindest das casten sparen, hat aber immer noch nicht die Möglichkeit von Code-Blöcken als Methodenargumente:
// Konto anlegen und Kontostände eintragen
typedef vector<int> IntVector;
IntVector myAccount;
myAccount.push_back(1234);
myAccount.push_back(-43);
myAccount.push_back(7543);
// Kontostände summieren und ausgeben
int sum = 0;
for (IntVector::iterator i = myAccount.begin(); i != myAccount.end(); i++) {
sum += *i;
}
cout << sum << endl;
kommt noch...
16. Okbtober 2001