Mint már korábban volt szó róla: a Smalltalk egy teljesen objektum-orientált nyelv. Minden, amivel dolgozunk objektum, még a legegyszerűbb típusú adatok is. A nyelv egyszeres öröklődést enged meg, de az kötelező, vagyis valamilyen szinten az összes osztály egy közös ősosztályból származik (az Object osztályból). Az objektumok interakciójának egyetlen módja van: üzenetek küldése az objektumoknak. Ha küldünk egy objektumnak egy üzenetet, akkor a rendszer kiválasztja az üzenethez tartozó metódust, és azt végrehajtja. (Ez hasonló más objektum-orientált nyelvekben egy adott metódus megkereséséhez és végrehajtásához.) A metódusok kifejezések sorozatából állnak, amelyeket a rendszer sorban egymás után végrehajt. Másféle utasítás nincs, a vezérlési szerkezeteket is különleges objektumokkal oldhatjuk meg. A kifejezések pedig mindig objektumnak küldött üzenetek.
A rendszer az ASCII karaktereket használja. Megkülönbözteti a kis- és nagybetűket, és ezek használatára ajánlást is ad. A globális változókat és osztályneveket nagybetűvel, minden mást (a lokális változókat, az osztály- és objektumszintű metódusokat) kis kezdőbetűvel írunk. Ha a név több szóból áll, akkor a további szavakat nagy kezdőbetűvel emeljük ki.
Számliterálokat a következő alakban lehet írni: [-][<radix>r]<egészrész>[.<törtrész>][e[+|-]<kitevő>] értéke: (egészrész.törtrész)radix*(radixkitevő). A radix (számrendszer alapszáma) és a kitevő mindig tízes számrendszerben szerepel. Az előbbi tetszőleges szám lehet 2 és 36 között. Az alapban pedig a számokon kívül csak nagybetűk használhatók (A=10, Z=35). Példák: 42 16r5E 2r11e5 34e-5 8r23.45e-3. Bizonyos implementációkban nem lehet egy literálon belül megadni más (10-estől eltérő) számrendszert és exponenciális alakot. A számliterál típusa a következők alapján dől el:
Látható, hogy a gépi szónál nagyobb számokat is kezelni tudja, ezért tetszőlegesen nagy számmal lehet számolni.
A Fraction egy kényelmesen használható típus, mert ha egy törtszámot írunk fel (pl. 2/3), valójában a két egész szám között végrehajtódik az osztás művelet, aminek eredményeként egy Fraction típusú objektumot kapunk.
A karakterliterálokat egy dollárjel vezeti be: $a az 'a' karaktert jelöli, $ a szóközt, $$ pedig a $-jelet. A sor végén elhelyezett dollárjel elvileg a sorvége-karaktert jelöli, de ez nem mindig van így (sőt, egészen furcsa eredményeket lehet kapni).
A stringliterált aposztrófok közé kell írni. A stringen belüli aposztrófot annak megduplázásával jelölhetjük: 'Joe''s pub'. Az így létrejött objektumok a String osztály példányai, és karaktertömbként kezelhetők. Ennek ellenére nem leszármazottja a String osztály az Array osztálynak, csupán "testvére", mindkettőnek az ArrayedCollection osztály az őse (más implementációkban FixedSizeCollection).
A rendszerben definiált azonosítók (pl. osztályok, üzenetek, globális változók) nevei. Pl.: #Variable, #Object, #at:put:, #GREEN A szimbólumok a Symbol osztály példányai, amely a String osztály leszármazottja.
A Smalltalk speciális szintaxissal segíti literálok tömbjének definiálását:
#( <elem1> <elem2> ... ) Ezek egyszerűen az Array osztály példányai lesznek. A tömbök egymásba is ágyazhatóak. Példák:A tömbelemek literálok lehetnek: szám, string, karakter, tömb - illetve amit nem tud az előző kategóriákba besorolni, azt automatikusan szimbólumnak tekinti. (Pl. az utolsó példában a symbol-t, vagy az utolsó előttiben a vesszőket.) Az utolsó példát tehát így értelmezi: #(42 $c #symbol 'ZB' #($a $b) #x). Így tehát változót nem lehet tömbliterálban elhelyezni. Ez alól kivétel a három konstans változó, amelyeket felismeri: true, false és nil. Így tehát #(true false nil var) eredménye #(true false nil #var) lesz.
A változók a Smalltalkban is csak referenciák, mint ahogy minden eleve objektumorientáltnak tervezett nyelvben megszokhattuk, hiszen ez teszi lehetővé a polimorfizmus teljes kihasználását. Ezenkívül fontos megjegyeznünk, hogy a változóknak nincs típusa, pontosabban minden változó típusa: objektumra (Object-re) mutató referencia. Ebből következik, hogy a változók deklarálásakor csak a nevüket kell megadnunk. A változók deklarálása kötelező, tehát nem használhatunk változót anélkül, hogy deklaráltuk volna.
A változóba tehát bármikor, bármilyen értéket beírhatunk, például az alábbi utasítássorozat hibátlan:
Alapértelmezésként a változók az UndefinedObject osztály nil nevezetű példányára mutatnak. Az UndefinedObject osztálynak ez az egy példánya létezik, minden inicializálatlan változó ugyanarra az objektumra mutat. Egy újabb érdekes ötlet a Smalltalkban, hogy ez az osztály is teljesen átlagos, az Object leszármazottja, így néhány metódus erre is meghívható, melyek közül a legfontosabb az isNil.
Változók deklarálása a következő formában történhet:
| vált1 vált2... |Ezt a formát használjuk az osztályok adattagjainak deklarálásakor, a metódusok definiálásakor, és a szövegszerkesztő ablakokban is. A változók neve betű[betű/szám]* alakú lehet.
Változók fajtái:
Példányváltozók:
Az objektum részei. Élettartamuk az objektum élettartama. Egy osztály minden példányának megvannak a saját, külön példányváltozói. Ezeknek vagy nevük, vagy indexük van. A névvel ellátott példányváltozókra a nevükkel hivatkozhatunk, az indexeltek üzeneteken keresztül érhetők el. Indexeltek például a tömbök. Az indexelt változók száma különbözhet ugyanazon osztály különböző példányaiban, például a #( 1 2 3 ) kifejezéssel egy olyan tömböt hozhatunk létre, amelynek 3 indexelt példányváltozója van, a #( 'fel' 'le' ) pedig 2 elemű tömböt hoz létre, annak ellenére, hogy ezek ugyanazon Array osztálynak példányai. Indexelt példányváltozókat tartalmazó objektum létrehozásakor valamilyen formában meg kell adni az indexelt példányváltozók számát (például: f := Array new: 5). A size üzenet megadja az objektum indexelt példányváltozóinak számát. A példányváltozók csak az adott objektum számára érhetőek el.
Időszakos változók:
Egy művelet lokális változói, argumentumai és a tartalmazott blokkok
argumentumai. Élettartamuk a művelet végrehajtási ideje. Blokk hívásakor
érték szerinti paraméterátadás van.
Osztott változók:
Több objektum között vannak megosztva.
Addig léteznek, amíg explicit módon nem töröljük őket.
Ide tartoznak az osztályváltozók, amelyeket az osztály összes példánya elér,
a globális változók, amelyeket minden objektum elér, és a készletváltozók (pool
változók), amelyeket csak bizonyos osztályok példányai láthatnak.
Ez utóbbiakat szótárakban definiálják. Nevüket nagybetűvel illik
kezdeni. A készletbe a változó nevét és értékét tartalmazó Association
osztályok kerülnek. A System az a készlet, ami a globális
változókat tartalmazza. A készletváltozók névvel ellátott szótárakban vannak,
amelyeket a Dictionary osztályból hozhatunk létre. Az osztályok
definiálásakor megadott poolDictionaries részben ezen készleteket
adhatjuk meg.
Pszeudováltozók:
A Smalltalk rendszerben előre definiált változók, melyek
Jele: := vagy <-, az adott implementációtól függően. A bal oldalon mindenképpen egy változónak kell szerepelni, amely a jobb oldalon álló (akár kifejezés eredményeként kapott) objektumra mutató referencia lesz. Az értékadást is kifejezésnek tekinti, értéke az értékül adott objektum, és ezért láncolni lehet: a:=b:=c
A megjegyzést idézőjelek között kell elhelyezni. Konvenció, hogy minden metódus
elé (a neve után, de a törzs előtt) megjegyzésként leírjuk, hogy az mit csinál.
Ugyanezt sajnos az általunk használt rendszerben osztályokra nem tehetjük meg,
mert az ilyen megjegyzéseket szó nélkül törölte a rendszer.
(Osztályokhoz tartozó megjegyzést az osztályt reprezentáló objektumnak küldött
#comment: üzenettel, és egy String típusú paraméterrel lehet megadni:
MyClass comment: 'This is my class.')
A Smalltalkban utasításainkat ponttal kell elválasztanunk. A pont az utasítások elválasztására, és nem lezárására szolgál, tehát az utolsó utasítás után nem kell szerepelnie. Ennek ellenére használhatjuk ott is, de a rendszer figyelmen kívül hagyja. Ennek jelentősége a blokkoknál látható, ahol az utolsó kifejezésnek különleges jelentése van, s így a mögé helyezett pont nem befolyásolja azt.
Egy metódusban meghatározhatjuk annak visszatérési értékét, ha az egyik kifejezés elé a ^ jelet tesszük. Ekkor a további kifejezések nem kerülnek kiértékelésre, a metódus futása befejeződik. Ha egy blokkon belül helyezzük el, akkor a blokk futása is megszakad, így például egy ciklus belsejéből is ki lehet lépni. Ha nem határozzuk meg explicit módon a visszatérési értéket, akkor alapértelmezésként a fogadó objektumot adja vissza (self-et.)
:= vagy <- | Az értékadás jele (az adott implementációtól függően). |
"" | Az idézőjelek közé írt szöveg megjegyzés. |
'' | Az aposztrófok közé írt szöveg string konstans. |
$ | A jellel karakter konstanst adhatunk meg, pl. $G vagy $@. |
# | A felhasználó által definiált szimbólumok, pl. osztálynevek, üzenetek, és tömbliterálok # jellel kezdődnek. Például: #Variable, #MyClass, #+, #at:put:, #(1 2) |
. | A Smalltalkban utasításainkat ponttal kell elválasztanunk. |
; | Az ugyanarra az objektumra vonatkozó, egymást követő metódushívások összevonhatók egy sorozatba a pontosvessző segítségével. |
^ | A metódus visszatérő értékének meghatározására szolgál. |
|| | A metódusok elején a lokális változók deklarálására szolgáló jelek. |
! | A metódusok lezáró jele. |
[] | Blokk definiálása |
:| | A blokkok elején a lokális változók deklarálására szolgáló jelek. |