Hlavní navigace

Programovací jazyk Forth a zásobníkové procesory

11. 1. 2005
Doba čtení: 11 minut

Sdílet

S novým rokem začíná na Rootu i nový seriál, ve kterém bych chtěl čtenáře seznámit s neobvyklým a současně velmi zajímavým programovacím jazykem Forth, který se v dnešní době používá zejména ve vestavěných (embedded) systémech a real-time prostředích. Pro urychlení běhu aplikací vytvořených ve Forthu byly zkonstruovány specializované mikroprocesory, které místo sady obecných registrů používají dvojici zásobníků. Také tyto procesory budou v dalších dílech tohoto seriálu popsány.

Obsah

1. Prehistorie
2. Počátky Forthu
3. Výhody a nevýhody Forthu oproti jiným programovacím jazykům
4. Dostupnost veškeré funkcionality prostředí
5. Snadná přenositelnost vývojového prostředí
6. Obsah dalšího pokračování
 

1. Prehistorie

Na počátku sedmdesátých let minulého století, která byla z hlediska vývoje výpočetní techniky a informačních technologií obecně velmi důležitá až přelomová, se většina aplikací stále programovala v assembleru, přesněji řečeno v jazyku symbolických adres. Ve druhé polovině sedmdesátých let se postupně začalo přecházet na vyšší programovací jazyky, zejména na Fortran a Basic, protože se začaly vytvářet složitější aplikace, jejichž vývoj v assembleru byl velmi namáhavý a pomalý (což můžu nejenom já z vlastní zkušenosti potvrdit) a výsledný produkt byl většinou nepřenositelný na jiné platformy.

Pro specializované úlohy, například pro tehdy vznikající projekty umělé inteligence nebo pro hromadné zpracování dat, byly vyvinuty další programovací jazyky, zejména stále populární a velmi zajímavý LISP a od něj odvozené Scheme. Tyto jazyky jsou i v současné době využívány v mnoha aplikacích, jmenujme například AutoCAD, hru Abuse, grafický editor GIMP, textový editor Emacs apod. Vývoj programovacích jazyků je naznačen na přehledném grafu dostupném z adresy www.levenez.com/lan­g.

Současně s těmito systémy a programovacími jazyky se začaly objevovat i první systémy umožňující spuštění více procesů současně (dnes známý mutliprocessing), například systém DEC RT-11. Víceuživatelské (multiuser) operační systémy byly teprve ve svých počátcích, například se jedná o systémy používané na minipočítačích PDP-11, které podporovaly současnou práci až osmi uživatelů, i když současné připojení všech osmi uživatelů znamenalo značné zpomalení jejich práce.

Pro tyto doby bylo také typické, že existovalo značné množství různých typů počítačů (dnes bychom řekli spíše platforem), které mezi sebou nebyly kompatibilní, a to nejenom ze strany podporovaných aplikací a programových knihoven, ale i například používanými formáty souborů (textové ASCII vs. EBCDIC), sběrnicemi, porty, externími paměťmi (disky, páskové mechaniky) apod.

Poznámka: současnost je z tohoto pohledu pro programátory i výrobce periferních zařízení mnohem jednodušší, protože i přes velké množství různých digitálních zařízení, jako jsou osobní počítače, pracovní stanice, herní konzole, PDA nebo „inteligentní“ telefony, existují hardwarové i softwarové standardy, které většina výrobců docela dodržuje (dokonce i jedna nejmenovaná firma z Redmondu).

2. Počátky Forthu

Vývoj programovacího jazyka Forth probíhal velmi zajímavě. Nikdy se totiž nejednalo o čistě „akademický produkt“, který by měl reprezentovat nějakou nosnou myšlenku (a tím méně o jazyk určený pro výuku programování), ale o programovací jazyk, který vytvořil v podstatě jeden člověk pro svoji osobní potřebu tak, aby přesně splňoval jeho pracovní požadavky.

Tento člověk se jmenuje Charles „Chuck“ Moore a dodnes patří mezi zajímavé a současně velmi rozporuplné osobnosti, které se podílely na rozvoji výpočetní techniky, zejména vestavěných (embedded) řídících systémů a systémů běžících v reálném čase. Moore byl prý překvapen, když zjistil, že systém, který vyvinul pro své potřeby, používají i další lidé, kterým v jejich práci vyhovuje více než v té době komerčně prosazovaný Fortran). Podrobnější informace o Chucku Moorovi budou uvedeny v dalších pokračováních tohoto seriálu.

Do značně heterogenního prostředí počítačů a operačních systémů sedmdesátých let přišel Moore se svým jazykem (či lépe řečeno celou vývojovou platformou) Forth. Vývojové prostředí Forthu obsahovalo interaktivní editor, interpret jazyka Forth a univerzální vazbu na assemblerupravený na právě provozovaný systém. Toto prostředí umožňovalo spouštět souběžně více procesů a současně mohlo v systému nezávisle pracovat až 64 uživatelů, a to i na platformách, jejichž operační systém nebyl multiuživatelský a dokonce ani multitaskový.

Ve skutečnosti Forth (resp. jeho vývojové prostředí, tyto dva pojmy však většinou splývají) nepotřeboval pro své spuštění žádný operační systém, pracoval totiž přímo s periferními zařízeními – z toho také vyplývá skutečnost, že se zdrojové kódy vytvářených aplikací neukládaly tak jako dnes do textových souborů, ale byly v předkompilované či přímo přeložené podobě uloženy v blocích pevné délky (takzvaných obrazovkách), které se podle potřeby nahrávaly do operační paměti počítače. Tyto programové bloky u mnoha systémů odpovídaly velikosti bloků na disku (typická velikost je 512 B a 1 kB), což značně urychlovalo práci s disky, protože se nemusely provádět složité přepočty adres na bloky.

Chuck Moore začal vytvářet programovací jazyk Forth docela nevinně – zpočátku se jednalo pouze o jakási makra, která používal při programování aplikací z oblasti astronomie (jednalo se o poměrně složité astronomické výpočty a řízení radioteleskopů). Tato makra se postupným vývojem proměnila v translátor vyšších operací do jazyka symbolických adres (assembleru) a v dalších letech do plnohodnotného interaktivního programovacího jazyka s vlastním vývojovým prostředím.

Jedná se přitom o jazyk interpretovaný a současně interaktivní, proto se v něm aplikace vyvíjí a především testují velmi jednoduše, zejména v porovnání s jazyky kompilovanými, jako jsou dnes často používané programovací jazyky C, C++, Pascal, C# a v podstatě i Java. Všechny vyjmenované kompilované jazyky potřebují pro vývoj programů mnoho podpůrných prostředků (editor, překladač, linker, debugger), které však mezi sebou nejsou (a ani nemohou být) příliš propojeny – proto je v nich ladění programů těžkopádné.

Ve Forthu jsou všechny tyto prostředky sloučeny, ale to v žádném případě neznamená, že by vznikl mnohasetkilový moloch. Naopak, celé vývojové prostředí Forthu zabírá jednotky, maximálně desítky kilobytů. Vývojové prostředí Forthu je totiž účelně vytvořeno tak, že obsahuje jen nejnutnější součásti (jak uvidíme v dalších dílech, je Chuck Moore zapřísáhlý minimalista).

Výpočetní výkon počítačů v té době nebyl příliš vysoký, k čemuž se dále přidávala poměrně vysoká cena za jednotku strojového času. Programátoři byli nuceni vytvářet programy co nejrychlejší a s co nejmenšími nároky na kapacitu operační paměti (v té době se to vyplatilo, v dnešním světě je jednodušší programovat resp. „bastlit“ co nejrychleji a ušetřené prostředky investovat do nového hardwaru). Časově kritické úseky aplikací se tedy neustále tvořily v assembleru, k čemuž byl Forth dokonale připraven, neboť existovalo jednoduché programátorské i aplikační rozhraní pro přístup k assembleru.

Také fakt, že Forth využíval vlastní blokový souborový systém (v dnešních OS se využívá pouze „streamový“ souborový systém, i když nejmenší adresovatelná jednotka na disku je právě jeden blok), v některých aplikacích značně urychlil práci se soubory. Týká se to zejména databázových aplikací a aplikací pro zpracování obrazu (viz další díly).

3. Výhody a nevýhody Forthu oproti jiným programovacím jazykům

Je zajímavé, že téměř všechny univerzální programovací jazyky vycházejí z některého ze tří „základních“ programovacích jazyků nebo z jeho kombinací. Tyto jazyky jsou Algol/Fortran, LISP a Forth. Všechny tyto jazyky jsou velmi staré – několik desítek let. S výjimkou Algolu a Fortranu, který byly až na výjimky postupně nahrazeny Pascalem, Céčkem a jeho následovníky, se LISP aForth stále používají a zejména LISP a Scheme je v některých svých aspektech doposud nepřekonatelný.

Současně existují dva konzistentní a čisté modely programovacích jazyků: model jazyka C a model jazyka LISP. Nově vznikající jazyky vyšší úrovně postupně nabírají detaily jazyků z úrovně nižší, a postupně se tak přechází od modelu jazyka C (Algol,Fortran, Pascal) k LISP-like jazykům, jako je Ruby, Python a částečně i Perl.

Všechny univerzální programovací jazyky jsou samozřejmě turingovsky úplné – ve vyjadřovací schopnosti algoritmů mezi nimi není žádný rozdíl. Dosti diametrálně se však liší složitostí, s jakou programátor ten Turingův stroj na pozadí naprogramuje pro řešení daného problému.

Klasické jazyky, které leží v C-čkovské (resp. Algolské) generační větvi, se vyznačují tím, že striktně oddělují výrazy a příkazy. Funkce jsou také považovány za něco odlišného od datových typů. V LISPovských jazycích jsou naopak výrazy, příkazy a funkce z hlediska konstrukce totožné. Funkce jsou totiž považovány za běžný datový typ (datové typy jsou samozřejmě v LISPovských jazycích používány, ale odlišným způsobem: proměnná nemá typ, ale hodnota ano. Ve skutečnosti je interně každá proměnná pouze ukazatelem, což zjednodušuje práci s pamětí).

Forth se v některých svých vlastnostech i původem přibližuje programovacímu jazyku Perl. Oba dva jazyky byly vytvořeny pro praktické použití, proto také jejich návrh není zdaleka tak „čistý“ jako u jazyků vytvořených v akademických institucích, jakými jsou napříkladLISP, Pascal nebo SmallTalk. To je v některých ohledech výhodné (možnost vytváření kompaktních a elegantních algoritmů), ale při programování komplikovanějších a rozsáhlejších systémů to může přinášet potíže. Forth a Perl se však výrazně odlišují svým zaměřením a datem vzniku. Perl je výborný při zpracování textových dat a na one-line utilitky, Forth zase při složitějších výpočtech s rozhodováním a velkým množstvím podprogramů a funkcí (ve Forthu jsou podprogramy a funkce nazývány slova, bližší informace si uvedeme v dalších dílech).

Forth však nebyl vytvořen, aby napravil chyby či nedostatky některého jiného programovacího jazyka, ale aby dovoloval psát kompaktní a snadno odladitelné programy. Z minulosti známe celou řadu takových „upgrade“ programovacích jazyků, například Algol->Pascal, C->C++, C++->Java nebo C->C#.Forth je prostě odlišný, což je z hlediska programátora, který přechází z jiného jazyka, nevýhodné, protože se musí naučit jinak přemýšlet o výstavbě svých programů.

Mezi největší nevýhody Forthu patří z tohoto hlediska postfixová notace zápisu matematických operací a řídících příkazů, která mnoha programátorům zpočátku vadí. Stejnou notaci však používá i PostScript (který z Forthu vychází), takže jednou naučené zvyky je možné uplatnit i v oblasti DTP apod. Druhou nevýhodou je, že za Forthem nestála a dosud nestojí žádná opravdu silná firma, která by ho propagovala. Open source komunita je orientovaná spíše do oblasti serverů a výkonných osobních počítačů,Forth je však vhodný zejména pro embedded systémy, PDA, mobilní telefony apod.

4. Dostupnost veškeré funkcionality prostředí

Zajímavé bylo, že Moore a jeho spolupracovníci vytvořili vývojové prostředí Forthu v samotném Forthu. To s sebou přinášelo resp. stále přináší několik výhod, které si popíšeme v dalších odstavcích.

První výhodou je dostupnost veškeré funkcionality překladače, editoru a interpreteru jazyka Forth programátorovi aplikací. O tomto se nikdy ani nesnilo programátorům, kteří pracují nebo znají pouze jazyky typu C, C++, Pascal nebo Java. V těchto jazycích například existují operace nad primitivními datovými typy (a to i v Javě, kterou někteří dodnes mylně nazývají čistě objektový jazyk :-), jejichž význam nelze žádným způsobem změnit.

Nelze také použít například část překladače pro parsing nebo pro překlad kódu za běhu aplikace. Často by se to hodilo v situacích, kdy uživatel napíše výraz, který se následně programově vyhodnotí. Ve Forthu s tímto nebyl problém, proto bylo možné v aplikacích používat například celý integrovaný editor nebo části interpreteru. Taktéž stránkovací mechanismus (dnes bychom řekli virtuální paměť) použitý v prostředí Forthu byl automaticky použit při běhu programu. Rozdělení programu a dat na bloky fixní délky bylo mnohdy s úspěchem použito při zpracování databází, kdy jeden blok představoval jednu či více položek v databázi, takže přístup k nim mohl být velmi rychlý (samozřejmě, že v případě databází, kde má každý záznam jinou délku, je situace opačná).

Tyto vlastnosti Forthu bývají někdy srovnávány s vlastnostmi programovacího jazyka LISP, ve kterém se programy reprezentovaly, stejně jako data, ve formě seznamů. V LISPu však obecně neexistuje možnost měnit samotný interpreter, i když v samotné reprezentaci programu a dat zůstává LISP stále nepřekonán (proto se také pro přenos dat v jiných jazycích vymýšlí mnohdy zbytečně složité věci jako XML; v LISPu je přenos dat mnohem jednodušší – přenesou se data ve formě seznamu a program pro zpracování těchto dat, taktéž ve formě seznamu). LISP je také jazyk na mnohem vyšší úrovni (ve smyslu hierarchie jazyků) než Forth, se všemi svými výhodami i nevýhodami.

5. Snadná přenositelnost vývojového prostředí

Druhou vlastností, kterou již první verze Forthu disponovaly, je fakt, že samotné vývojové prostředí Forthu bylo velmi dobře přenositelné na další platformy a/nebo operační systémy. Pro vlastní překlad celého prostředí i s editorem a překladačem bylo potřeba pouze nadefinovat cca 60 primitiv (základních příkazů či, chcete-li, operací), které prováděly „překlad“ z Forthu do assembleru dané platformy.

Uvádí se, že přenos Forthu na novou platformu zabral Moorovi necelé dva týdny, což není mnoho, když si uvědomíme, že toto prostředí bylo víceuživatelské, podporovalo i multitasking a ve své podstatě nahrazovalo celý operační systém. Před vlastním přenosem (tj. překlademForthu) bylo někdy zapotřebí napsat nebo upravit assembler na tuto novou platformu, takže je docela pravděpodobné, že sám Moore napsal více assemblerů pro různé typy procesorů než kdokoli jiný (bylo by to dostačující pro zápis do Guinessovy knihy rekordů? :-).

Určitě stojí za povšimnutí rozdíl mezi Forthem a dalšími programovacími jazyky, u nichž se uvádí, že jsou určeny pro vytváření multiplatformních aplikací. Zatímco jazyky, jako je Java nebo SmallTalk (viz například články vyšlé zde na Rootu), potřebují pro spouštění aplikací operační systém a nad ním simulovaný virtuální počítač (virtuální počítač – VM – obou jazyků je představován zásobníkovým strojem! Forth je celý postaven nad zásobníkem), je Forth určen pro nasazení do oblastí, kde se operační systém nenachází, pouze je k dispozici operační paměť a někdy i blokové paměťové zařízení (disk, disketa atd.). Virtuální počítač Forthu tak neběží nad operačním systémem, ale přímo nad hardwarem, což znamená odstranění jedné potenciálně zpomalující a mnohdy zbytečné vrstvy.

CS24_early

Ostatní programovací jazyky řeší multiplatformnost tak, že uživatele odstiňují od operačního systému a hardwaru pomocí standardních knihoven (libc, math apod.). Pro větší systémy je tento přístup určitě výhodnější, ale pro systémy omezené jak výpočetním výkonem, tak i dostupnou pamětí, nejsou standardní knihovny nejvhodnější – například pouze implementace funkce printf() obsahuje více kódu než některé jednodušší interprety Basicu nebo Forthu.

6. Obsah dalšího pokračování

V dalším pokračování tohoto seriálu si popíšeme, ve kterých oblastech probíhalo nasazení Forthu, který sice při svém vzniku zcela jistě znamenal revoluci ve vývoji programovacích jazyků, ale zpočátku musel čelit nedůvěře programátorů – to ostatně není, vzhledem k jeho odlišnému přístupu k programování, nic divného.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.