Smalltalk

Vladimír Janoušek, ÚIVT FEI VUT Brno, 1997

Smalltalk je čistě objektově orientovaný jazyk a systém, který dodnes zůstává velkou inspirací pro všechny objektové technologie. Pohodlí programátora je ve Smalltalku zajištěno jednoduchým interpretačním jazykem s jasnou sémantikou bez zbytečných komplikací, rozsáhlou a promyšleně navrženou knihovnou tříd a interaktivními nástroji pro podporu programování a ladění aplikací.

Smalltalk vznikl na počátku sedmdesátých let ve výzkumném středisku PARC (Palo Alto Research Center) firmy Xerox. U jeho zrodu a dalšího vývoje stáli Alan Kay, Adele Goldberg a Dan Ingalls. Významé verze Smalltalku byly Smalltalk-72, Smalltalk-76 a prozatím poslední verze, Smalltalk-80, pro který se v současné době vytváří ANSI norma.

Tradičním výrobcem Smalltalku je firma ParcPlace Systems, produkující Smalltalk 80 včetně vývojového prostředí (ObjectWorks\Smalltalk, VisualWorks) pro širokou škálu platforem (SUN, RS6000, HP, DEC, Windows, Macintosh, OS/2). Dalším výrobcem, který se nedávno spojil s ParcPlace Systems, je Digitalk. Jeho Smalltalk/V byl poněkud zjednodušený Smalltalk-80, omezující se zpočátku pouze na platformu PC (Windows), později i na Macinstoshe. Spolupráce Digitalku s IBM vedla k implementaci Smalltalku pro OS/2 a AIX a k vytvoření systému PARTS Workbench (Parts Assembly and Reuse Tool Set), což je nadstavba nad Smalltalkem, umožňující skládat aplikace z komponent. Nyní IBM vyvíjí vlastní Smalltalk se systémem VisualAge, obdobou systému PARTS. Výrobců Smalltalku je samozřejmě více a existují i freewarové verze Smalltalku.

Jak již bylo naznačeno, Smalltalk není jen jazyk. Pod pojmem Smalltalk rozumíme konzistentní celek, sestávající z jazyka, vývojového prostředí a rozsáhlé knihovny znovupoužitelných tříd. Jinak lze též pohlížet na Smalltalk jako na jazyk a systém. Není bez zajímavosti, že asi 90% systému Smalltalk je naprogramováno přímo ve Smalltalku a je k dispozici ve zdrojovém tvaru.

Smalltalk - jazyk

Ve Smalltalku je všechno objekt. Objekt zapouzdřuje stav (data) a operace (metody) pracující nad ním. Objekty skrývají informace a umožňují tak datovou abstrakci: klient nemůže se stavem objektu manipulovat přímo, ale pouze prostřednictvím metod, které jsou invokovány na základě přicházejících zpráv. Objekty tedy komunikují předáváním zpráv, přičemž zprávy jsou polymorfní: různé objekty mohou stejnou zprávu zpracovávat různými metodami.

Ve Smalltalku nelze zapsat nic jiného, než zaslání zprávy, eventuelně je možné výsledek vyhodnocení tohoto výrazu přiřadit do proměnné. Dokonce i řídicí struktury (podmíněné větvení a cykly) jsou řešeny zasíláním zpráv. Velkou inspirací tvůrců Smalltalku byl LISP. Odtud si Smalltalk odnesl kromě některých funkcionálních rysů hlavně maximální jednoduchost jazyka. Syntax Smalltalku však byla vytvořena tak, aby odstranila nutnost masového používání závorek, která je pro LISP typická. Smalltalk dokonce nepoužívá závorky ani tam, kde jsme na to z jazyka C nebo z Pascalu a jiných jazyků zvyklí - při předávání parametrů funkcím (metodám). Závorky se ve Smalltalku používají kromě některých literálů jen pro vyjádření priority vyhodnocování výrazů, sestávajících ze zasílání zpráv. Zaslání zprávy má obecně tvar

"příjemce" "zpráva",

přičemž zpráva sestává ze selektoru zprávy a argumetů. Například výraz

1 + 2

znamená, že objektu, kterým je celé číslo 1 se zasílá zpráva "+ 2", kde "+" je selektor zprávy a "2" je argument. Vyhodnocením tohoto zaslání zprávy bude zřejmě číslo 3. Podívejme se nyní na průběh vyhodnocování uvedeného výrazu trochu podrobněji. Nejprve je přečeten literál 1, pro který je vytvořen objekt třídy SmallInteger s hodnotou 1. Pak je přečtena zpráva "+ 2" a je vyhodnocen argument - je tedy vytvořen objekt třídy SmallInteger s hodnotou 2. Tento objekt je posléze předán spolu se selektorem + prvnímu objektu. Ten reaguje vyhledáním metody (operace) pro selektor +. Tuto metodu s předaným argumentem vyhodnotí. V našem případě dojde k vytvoření nového objektu třídy SmallInteger s hodnotou 3 a tento objekt je výsledkem uvedeného zaslání zprávy. Poznamenejme však, že vyhodnocování aritmetických operací se ve skutečnosti provádí efektivněji než jak to vypadá z hlediska programátora, prakticky je stejně efektivní jako v každém jiném jazyce. Výhoda čisté objektové orientace se může projevit například v tom, že vyhodnocení výrazu

10000 factorial

dá správný výsledek, přestože někde v průběhu vyčíslování dojde k překročení rozsahu daného třídou SmallInteger. Velká čísla jsou samozřejmě implementována o něco složitěji než malá, ale pracuje se s nimi stejně.

Zatímco výraz

10000 factorial

byl příkladem unární zprávy, výraz

1 + 2

příkladem binární zprávy, výraz

anArray at: 4 put: 'hello'

je příkladem zprávy s klíčovými slovy. Zpráva at:put: s argumenty 4 a 'hello' se zasílá objektu identifikovanému obsahem proměnné anArray. Tento typ zprávy s jedním a více argumenty je asi nejnezvyklejším prvkem syntaxe Smalltalku ve srovnání s jazyky je C a Pascal. Nicméně v případě sugestivně pojmenovných klíčů (což bývá dobrým zvykem a knihovní třídy to dodržují) je Smalltalkovský kód velmi dobře čitelný a intuitivně pochopitelný.

Třídy jsou také objekty a lze jim zasílat zprávy. Jména tříd jsou globálně dostupná a začínají velkým písmenem. Například výraz

Dictionary new

vede k vytvoření nové instance třídy Dictionary. Nové třídy se vytvářejí také zasíláním zpráv. Třídě, od které má nová třída dědit, se zašle zpráva s informací o struktuře nové třídy. Tuto činnost obvykle realizují nástroje, které jsou součástí vývojového prostředí Smalltalku.

Významným rysem Smalltalku je to, že nerozlišuje ukazatel a přímá data, jak to činí C a Pascal. Všechny objekty jsou dostupné referencemi. Obrovskou výhodou tohoto přístupu je vyšší bezpečnost vyvíjených aplikací díky tomu, že není možné explicitně pracovat s pamětí.

Dalším zajímavým rysem Smalltalku je to, že objekty jsou typované (každý zná svou třídu), ale proměnné nemají deklarované typy. Tato skutečnost umožňuje tvorbu velmi obecných datových typů, jako jsou obecné množiny, uspořádané kolekce, slovníky atd. Kdykoli je však možné (pokud je to potřeba) kontrolovat typy zpracovávaných objektů.

Smalltalk - systém

Základními komponentami systému Smalltalk jsou programovací nástroje, inkrementální kompilátor a knihovna tříd. To vše (kromě několika primitivních operací) je naprogramováno přímo ve Smalltalku a interpretováno virtuálním strojem Smalltalku.

Virtuální stroj interpretuje tzv. byte-kód, který má uložen v paměti. Paměť virtuálního stroje obsahuje binární podobu všech objektů Smalltalku. Obraz této paměti je uložen v souboru, tzv. image. Virtuální stroj je jedinou částí Smalltalku, která je závislá na hostitelské platformě. Image zůstává nezávislý.

Byte-kód je produktem kompilace zdrojového textu třídy nebo metody. Jde o inkrementální kompilaci. Zdrojový kód systémových tříd je uložen ve zvláštním souboru. Kromě toho se udržuje soubor se změnami, kde jsou uchovány zdrojové texty všech tříd, které byly k základním třídám Smaltalku přidány nebo byly modifikovány. Nepřetržitě se zde udržuje historie změn, je tedy kdykoli možné vrátit se k libovolné předchozí verzi libovolné třídy (pokud ovšem programátor neprovedl komprimaci změn, která odstranila všechny staré verze). Zatímco změny se ukládají vždy, image se ukládá do souboru jen na požádání.

Při novém spuštění Smalltalku se začíná přesně ve stavu, který odpovídá naposledy uloženému image. Změny, které byly provedeny od posledního uložení image do ukončení předchozí práce ve Smalltalku je možné znovu reprodukovat podle informací ze souboru se změnami. Toho se s výhodou využívá především v případech, kdy došlo z jakéhokoli důvodu k násilnému ukončení práce ve Smalltalku a je potřeba se znovu dostat do stavu těsně před touto událostí.

Ve Smalltalku se programuje pomocí tzv. browseru, neboli prohlížeče. Název browser však není zcela přesný. Ve skutečnosti browser umožňuje nejen prohlížet implementace existujících tříd, ale také je modifikovat a vytvářet nové. Přestože se browsery v různých Smalltalcích mohou mírně lišit, v hrubých rysech více či méně napodobují browser Smalltalku 80.

Browser umožňuje navigaci v dvouúrovňově organizované knihovně tříd. Třídy jsou rozděleny do tzv. kategorií. Třída obsahuje metody, které jsou opět organizovány do kategorií.

Modifikuje-li se metoda nebo struktura instance v browseru a tato změna se potvrdí, inkrementální kompilátor zkompiluje tuto část definice třídy do byte-kódu, který se stane součástí image. Současně je zdrojový text metody nebo třídy uložen do souboru se změnami.

Dalším prvkem programátorského prostředí je workspace. Workspace plní podobnou úlohu jako shell operačního systému. Umožňuje zadávat a vyhodnocovat Smalltalkovské výrazy, tedy zasílání zpráv. Tímto způsobem je možné experimentovat s kusy kódu, který ve Smalltalku vytváříte. Odtud lze mimo jiné spustit vyvíjenou aplikaci nebo její část.

Běžící objekty je možné zkoumat pomocí tzv. inspektoru. Inspektor umožňuje prohlížet a modifikovat obsah instančních proměnných libovolného objektu. Jelikož tyto proměnné obsahují reference na jiné objekty, je možné procházet strukturu celé aplikace (a vlastně i celého Smalltalku) a detailně tak sledovat její stav.

Inspektor se většinou spouští prostřednictvím debuggeru. Ten je vyvolán v důsledku neošetřené výjimky (ta může být mimo jiné důsledkem vloženého breakpointu). Zobrazí strukturu vnořených volání (obsah zásobníku), kód nedokončené metody a obsahy proměnných, tvořících kontext metody. Debugger umožňuje trasovat program a prostřednictvím inspektorů sledovat jeho dynamiku.

Vývojové prostředí Smalltalku se tedy neomezuje jen na překladač a debugger. Jde o komplexní nástroj pro prototypování, experimentování a interaktivní zkoumání. Je například možné kdykoli nechat provést libovolnou část Smalltalkovského kódu v uměle vytvořeném kontextu.

Kromě uvedených základních nástrojů programátora existují různé doplňkové nástroje, například pro tvorbu uživatelských rozhraní. V některých případech jde dokonce o ucelenou sadu nástrojů, které tvoří novou vrstvu nad Smalltalkem, umožňující interaktivní tvorbu celých aplikací a odstiňující aplikačního programátora od detailů Smalltalku. Příkladem takové vrstvy může být VisualAge (IBM). Jistě není třeba zdůrazňovat, že veškeré programátorské nástroje jsou naprogramovány přímo ve Smalltalku.

Závěr

Některé dřívější výhrady k výkonnosti Smalltalku jsou dnes již překonány. Přestože jde o interpret, virtuální stroj Smalltalku provádí tzv. dynamickou kompilaci byte-kódu do strojového kódu procesoru, na kterém běží, přičemž tento kód ukládá do vyrovnávací paměti, kde se i provádí. Co už bylo jednou přeloženo a je ve vyrovnávací paměti, to se už nepřekládá, ale přímo provádí. Díky dynamické kompilaci je typická aplikace ve Smalltalku jen asi o 20% pomalejší než tatáž aplikace napsaná v C++.

Dá se říci, že ve světě objektově orientovaných jazyků je Smalltalk asi jedinou vážnou alternativou k C++. Je ovšem jasné, že každý z těchto jazyků má trochu jinou oblast použití (C++ má oproti Smalltalku snad o něco blíže k systémovému programování). Dalším jazykem, o kterém se také hodně mluví, je Java. Java je ale prozatím tak mladý jazyk, že se v tuto chvíli nedá s C++ ani Smalltalkem srovnávat. Přesto však tento jazyk, který se snaží zevnitř napodobovat Smalltalk a navenek vypadat jako C++, má nadějnou budoucnost a může příznivě ovlivnit i některé aktivity spojené se Smalltalkem a distribuovaným počítáním na Internetu.

V každém případě ovšem Smalltalk i nadále zůstává základní inspirací pro všechny objektově orientované jazyky, programovací nástroje i databázové a operační systémy.