Hlavní navigace

Šedesátiny převratného programovacího jazyka ALGOL-60

Pavel Tišnovský

Prvním významným kulatým výročím, které si letos na Rootu připomeneme, jsou šedesáté narozeniny programovacího jazyka ALGOL-60. Dnes jde o mrtvý jazyk, ale stál na začátku vývoje dvou větví jazyků – „céčkové“ a „pascalské“.

Doba čtení: 29 minut

Sdílet

11. Další vývoj ALGOLu: rozkol v komisi

12. ALGOL-68

13. Algol-W

14. Rozdíly mezi ALGOLem-60 a Algolem-W

15. Od Algolu-W k Pascalu

16. Komu vděčíme za složené závorky a operátory ++ a –?

17. Vybrané vlastnosti programovacího jazyka „B“

18. Vznik programovacího jazyka „C“

19. Literatura

20. Odkazy na Internetu

1. Šedesátiny převratného programovacího jazyka ALGOL-60

„Here is a language so far ahead of its time that it was not only an improvement on its predecessors but also on nearly all its successors“
Sir Tony Hoare

V loňském roce jsme si na stránkách Roota připomněli trojici kulatých výročí v oblasti programovacích jazyků. Po dvojici článků o třicátých narozeninách Turbo Pascalu 5.5 a šedesátém výročí vzniku programovacího jazyka COBOL jsme si připomněli i sedmdesát let, které uběhly od vzniku nástroje, který dnes nazýváme assembler. Některá podobně významná (a možná i důležitější) výročí si postupně připomeneme i letos. Zapomenout nesmíme především na programovací jazyk ALGOL, jehož nejznámější varianta, která se jmenuje ALGOL-60, skutečně vznikla již v roce 1960 s malými doplňky o dva roky později. Dnes se s tímto programovacím jazykem prakticky nesetkáme, ovšem i přesto se jedná o jeden z nejvýznamnějších programovacích jazyků, jaké kdy byly vytvořeny.

Obrázek 1: Sálový počítač Burroughs B5000, který se primárně programoval právě v Algolu.

S koncepcemi, které byly do ALGOLu zařazeny, se setkáme nejen v jeho přímých následovnících (což je ve stručnosti Pascalská větev a céčková větev), ale například i v mnoha LISPovských jazycích. Ty sice tvoří samostatnou větev vývoje, ovšem z ALGOLu se do LISPovských jazyků dostal především koncept lexikální oblasti platnosti identifikátorů. A jen na okraj – právě na základě dvojice článků „Report on the Algorithmic Language ALGOL 60“ a „Revised Report on the Algorithmic Language Algol 60“ vznikla tradice, že se specifikace programovacího jazyka Scheme vydává v článcích pojmenovaných „RevisednReport on the Algorithmic LanguageScheme“ s postupně rostoucí číslovkou n.

Poznámka: zvláštní je, že některé dobré myšlenky, které v ALGOLu nalezneme, nebyly plně využity v navazujících jazycích. Znovu byly „objeveny“ až o několik desítek let později.

Obrázek 2: V pozadí tohoto snímku můžeme vidět moduly, v nichž se nachází procesory, operační paměť (core memory) a taktéž vstupně-výstupní kanály počítače Burroughs B5500. V popředí je dvojice řádkových tiskáren a taktéž operátorská konzole.

2. ALGOL ve stručnosti

Jak jsme si již řekli v úvodním odstavci, je dnes ALGOL mrtvým jazykem, ovšem přesto jazykem s velkým vlivem na další vývoj IT. Jedná se o programovací jazyk, který původně vznikl za účelem snadno pochopitelného algoritmického popisu matematických (především numerických) úloh, výuku programování a vývoj překladačů (na rozdíl od C, který byl naopak zaměřen přísně prakticky). Z tohoto důvodu například původní návrh jazyka (IAL – International Algorithmic Language, později přejmenovaný na ALGOL 58) zpočátku neobsahoval žádné konstrukce pro vstup a výstup dat, ovšem se vznikem prvních reálných překladačů se množina konstrukcí jazyka postupně rozrůstala, takže ve standardu ALGOL 68 (poslední významný standard ALGOLu, který se popravdě příliš nepovedl – více o tom za chvíli), již jazyk obsahoval jak operace vstupu a výstupu, tak i podporu pro nenumerické úlohy aj. V programovacím jazyce ALGOL byly prakticky poprvé použity konstrukce umožňující strukturované programování – týká se to především programových smyček bez návěští, podmíněných příkazů, blokové struktury programu a též výše zmíněný koncept lexikálního rozsahu (viditelnosti) proměnných (tuto vlastnost z ALGOLu převzal i programovací jazyk Scheme, který je v v mnoha jiných ohledech založený na LISPu).

ibm-5

Obrázek 3: Jedna z populárních dobových učebnic ALGOLU 68.

ALGOL se využíval jak pro zápis programů v učebnicích a vědeckých článcích, tak i v každodenní programátorské praxi. V tištěné literatuře se používal poněkud jiný způsob zápisu, protože bylo možné použít typografické zvýraznění jednotlivých prvků jazyka i sadu znaků velké a malé abecedy, zatímco některé mainframy používaly pouze znaky velké abecedy (ve skutečnosti existují minimálně tři způsoby zápisu, podrobněji se jimi budeme věnovat v navazujících kapitolách). Jednou ze zajímavostí je, že se tento jazyk (resp. jeden z jeho dialektů) používal i v SSSR, mj. také v projektu raketoplánu Buran. Tato verze jazyka byla dokonce v SSSR standardizována jako GOST 10859. Existuje i čínská verze tohoto jazyka, ve které se namísto znaků z tabulek ASCII či EBDIC používají národní znaky.

Poznámka: zde je patrné, že ALGOL byl chápán spíše jako koncept a ne jako konkrétní jazyk s pevně danou syntaxí a sémantikou.

Programovacím jazykem ALGOL se inspirovali tvůrci mnoha dalších programovacích jazyků. Jedná se například o jazyky Simula, Pascal (i další jazyky navržené N. Wirthem) a v neposlední řadě též trojice na sebe navazujících jazyků BCPL, B a C. Na syntaxi céčka jsou postaveny další jazyky, zejména C++, Java a dokonce dynamicky typovaný JavaScript. Těmto jazykům se proto také někdy říká „algolské“ (Algol-like) nebo též jazyky patřící do algolské větve.

Na následujícím výpisu krátkého programu (jedná se o známý Bresenhamův algoritmus rasterizace úsečky) si povšimněte, že je celý program snadno pochopitelný i v případě, že jazyk ALGOL neznáte. Mnoho konstrukcí ALGOLu totiž skutečně „zdomácnělo“ i v dalších programovacích jazycích. Poznámka: zde je použitý dialekt ALGOL 68, při použití ALGOLu 60 by se například programové smyčky zapisovaly odlišným způsobem.

PRAGMAT READ "Basic_bitmap_storage.a68" PRAGMAT;
 
line OF class image := (REF IMAGE picture, POINT start, stop, PIXEL color)VOID:
BEGIN
   REAL dx = ABS (x OF stop - x OF start),
        dy = ABS (y OF stop - y OF start);
   REAL err;
   POINT here := start,
         step := (1, 1);
   IF x OF start > x OF stop THEN
      x OF step := -1
   FI;
   IF y OF start > y OF stop THEN
      y OF step := -1
   FI;
   IF dx > dy THEN
      err := dx / 2;
      WHILE x OF here /= x OF stop DO
         picture[x OF here, y OF here] := color;
         err -:= dy;
         IF err < 0 THEN
            y OF here +:= y OF step;
            err +:= dx
         FI;
         x OF here +:= x OF step
      OD
   ELSE
      err := dy / 2;
      WHILE y OF here /= y OF stop DO
         picture[x OF here, y OF here] := color;
         err -:= dx;
         IF err < 0 THEN
            x OF here +:= x OF step;
            err +:= dy
         FI;
         y OF here +:= y OF step
      OD
   FI;
   picture[x OF here, y OF here] := color # ensure dots to be drawn #
END # line #;

3. ALGOL-58 – jazyk inspirovaný Superplanem

„ALGOL is probably the most influential language you’ve never heard of.“

Práce na vývoji programovacího jazyka, který později dostal název ALGOL, začala již na konci padesátých let minulého století. Tehdy se na konferenci v Curychu sešla skupina význačných osobností z oblasti IT, aby navrhli programovací jazyk vhodný primárně pro popis algoritmů. Mezi účastníky konference a současně i autory první varianty ALGOLu patřili Friedrich L. Bauer, Hermann Bottenbruch, Heinz Rutishauser, Klaus Samelson, John Backus, Charles Katz, Alan Perlis, Joseph Henry Wegstein (povšimněte si, že se tehdy o vývoji IT rozhodovalo jak v USA, tak i v Evropě).

Z těchto osobností je důležité zmínit především Heinze Rutishausera, který v letech 1949 až 1951 vyvinul vyšší programovací jazyk pojmenovaný Superplan. V tomto programovacím jazyku se mj. používalo klíčové slovo Für pro počítanou programovou smyčku. A poangličtěná varianta tohoto klíčového slova (tedy for) se dostala jak do ALGOLu, tak i do prakticky všech moderních programovacích jazyků (původní FORTRAN měl smyčku realizovanou slovem do, LISP byl založen na rekurzi a tedy smyčky původně nepodporoval).

Mezi další osobnost, která stála za vznikem ALGOLu, zmiňme Johna Backuse, který se předtím podílel mj. i na vývoji FORTRANu. John Backus přišel se zajímavou myšlenkou – pro popis syntaxe ALGOLu navrhl formalizovaný způsob zápisu, jenž je dnes známý pod jménem Backusova-Naurova forma neboli BNF. Oproti pouhému textovému popisu se jedná o velké vylepšení, které pomáhá jak vývojářům překladače, tak i samotným programátorům, neboť jim usnadňuje nalezení chyb.

Dnes se BNF popř. rozšířená varianta EBNF stále používá. Nalezneme ji například ve specifikaci programovacího jazyka Go, Pascalu nebo programovacího jazyka Lua.

Výše zmíněná komise původně pracovala na návrhu jazyka se jménem IAL neboli International Algebraic Language. Později se ovšem (velmi rozumně) shodli na tom, že se jedná o těžko vyslovitelný název, který je navíc poněkud nabubřelý. Namísto IAL byl tedy zvolen hezčí, vyslovitelný a snadno zapamatovatelný název ALGOL neboli ALGOrithmic Language, i když někomu může připadat mírně hrozivý (hvězda Algol – hlava démona – totiž nemá v některých kulturách dobrou pověst).

4. ALGOL-60

„The meetings were exhausting, interminable, and exhilarating. One became aggravated when one's good ideas were discarded along with the bad ones of others. Nevertheless, diligence persisted during the entire period. The chemistry of the 13 was excellent.“

Samotný ALGOL-58 původně nebyl ani implementovaný [*], i když vývoj překladače byl zahájen minimálně ve firmě IBM. Jinak tomu ovšem bylo v případě ALGOLu-60, jehož návrh – jak již zajisté tušíte – vznikl právě v roce 1960. Opět se sešla komise, která se skládala jak z původních členů výboru z roku 1958, tak i z několika členů nových: J. W. Backus, F. L. Bauer, J. Green, H. Rutishauser, C. Katz, K. Samelson, J. McCarthy, B. Vauquois, A. J. Perlis, J. H. Wegstein A. van Wijngaarden M. Woodger. Výsledkem byl článek „Report on the Algorithmic Language ALGOL 60“, v němž je popsána jak syntaxe (BNF), tak i sémantika nového programovacího jazyka.

Poznámka: ve skutečnosti existovala jedna implementace ALGOLu-58. Vznikla až v roce 1961 a jmenovala se Dartmouth ALGOL 30. Za jejím vznikem stojí Thomas Eugene Kurtz, který se později mj. podílel i na vzniku BASICu.

Obrázek 4: Vývoj programovacích jazyků, jejichž prapředkem je ALGOL-58.

5. Tři tváře ALGOLu

ALGOL je poněkud zvláštní a mnohdy i matoucí tím, že jeho syntax existuje ve třech rozdílných variantách, které se nazývají reference syntax, publication syntax a implementation syntax. Referenční syntax je použita především v oficiálním „Reportu“ (viz též předchozí kapitoly), publikační syntax je použita v článcích, při ukázce algoritmů na tabuli (slajdech) atd. A implementační syntax se liší podle použitého počítače a jeho schopností (znaková sada atd.). Kvůli této trojí syntaxi se zápis algoritmů v článcích a knihách mnohdy dosti podstatným způsobem odlišuje od zápisu pro konkrétní počítač. Navíc to umožňuje měnit (v článcích i konkrétní implementaci) klíčová slova a nahrazovat je za národní varianty, používat desetinnou čárku namísto desetinné tečky atd.

Příkladem mohou být aritmetické operátory, které v tištěné podobě mají tvar:

↑    (mocnina)
×, / (real), ÷ (integer)
+, -

V konkrétní implementaci (zde na počítačích IBM) se však zápis mění:

**    (mocnina)
*, / (real), / (integer)
+, -

Podobně je rozdíl mezi tiskovou podobou relačních operátorů:

<, ≤, =, ≥, >, ≠

které nelze v mnoha znakových sadách zapsat.

Nejzajímavější jsou rozdíly v logických operátorech:

¬ (not)
∧ (and)
∨ (or)
⊃ (implication)
≡ (equivalence)

Mj. i kvůli nutnosti zápisu operátorů and a or byl do ASCII tabulky přidán symbol \, takže bylo možné psát:

/\ (and)
 
\/ (or)

Tím se dostáváme k tomu, proč vlastně existovalo několik způsobů zápisu. Problém spočívá v tom, že v roce 1960 vlastně neexistoval uznávaný standard v oblasti znakové sady, protože například EBCDIC měla několik variant atd. Samotná práce na unifikované znakové sadě, kterou dnes známe pod jménem ASCII, začala právě v roce 1960, první verze byla publikována v roce 1963 a poslední revize vyšla v roce 1967. Není tedy divu, že tvůrci ALGOLu měli poměrně volné ruce (a mohli docela dobře předpokládat, že se do normy později dostanou minimálně všechny relační operátory a nikoli jenom tři z nich – ostatně způsob zápisu ≠ existuje v různých programovacích jazycích minimálně v sedmi variantách).

Poznámka: mimochodem, operátor mocniny je vyhodnocován jinak, než například v Pythonu:
>>> 2**3**2
512
>>> 2**(3**2)
512
>>> (2**3)**2
64

Zatímco v ALGOLu zápis 2↑x↑y znamená (2x)y.

6. Bloková struktura programů a lexikální rozsah platnosti

ALGOL byl prvním rozšířeným programovacím jazykem, který striktně zavedl blokovou strukturu programů, tedy konstrukci, kterou používáme dodnes. Bloky byly určeny klíčovými slovy begin a end a mohly být vnořené:

begin
comment block in main block;
    begin
        real x;
        x := 1.234;
        outreal(1,x); outstring (1,"\n")
    end
end

Někdy se setkáme s odlišným odsazením, v němž se blok začíná zapisovat přímo za slovo begin (odpadají tak hádky, o kolik mezer odsazovat):

begin
comment block in main block;
      begin real x;
            x := 1.234;
            outreal(1,x); outstring (1,"\n")
      end
end

S bloky souvisí i rozsah platnosti proměnných, který je stanoven lexikálně (v čase překladu) a nikoli dynamicky (v době běhu). V následujícím bloku kódu existují dvě proměnné x, každá s odlišnou viditelností:

begin integer x;
      x := 1;
      begin outinteger(1,x);
      end;
      begin integer x;
            x := 2;
            outinteger(1,x);
      end;
      outinteger(1,x);
end

7. Podmínky

Do ALGOLu byly zařazeny příkazy pro zápis podmínek, které jsou založeny na vyhodnocení pravdivostního výrazu, který určuje, do jaké větve („then“ nebo „else“) se řízení programu přesune. Pravděpodobně si říkáte, že se nejedná o velký objev, ovšem například ve FORTRANu se v té době používal takzvaný „aritmetický IF“ s několika nepříjemnými vlastnostmi (zejména se to týkalo určení hodnoty, která už je nulová), nehledě na to, že IF pokračoval skokem. IF založený na pravdivostní hodnotě byl zařazen až do FORTRANu IV, který vyšel až v roce 1961, tedy po ALGOLu.

Zápis podmínky s větvemi thenelse vypadá takto:

begin integer n;
      ininteger(0,n);
      if n < 0 then outstring(1,"negative")
      else outstring(1, "0 or positive");
      outstring(1,"\n")
end
Poznámka: jak si možná někteří pamatují z výuky Pascalu, před else se nepíše středník.

Podmínky je možné zanořovat a vytvářet ve větvích nové bloky, což je také novinka:

begin integer n, m;
      ininteger(0,n);
      if n < 0 then
      begin
            if n>= -2 then m := -n else m := -2
      end
      else m := 0;
      outinteger(1, m); outstring(1,"\n")
end

A konečně – samotný zápis podmínky lze použít ve výrazu, což je kupodivu konstrukce, která se do mnoha dalších jazyků inspirovaných ALGOLem nedostala (objevuje se až později ve tvaru ternárního operátoru):

begin integer n, m;
      ininteger(0,n);
      m := if n < 0 then -n else n;
      outinteger(1, m);
end
Poznámka: funkce ininteger a outinteger slouží pro čtení resp. zápis do zvoleného handle (zde standardního vstupu a výstupu).

8. Programové smyčky

„ALGOL is not a language you need to learn to get a job or to be a successful developer. However, it was hugely influential on both the practice and theory of computer programming.“

Pro zápis programových smyček se používalo klíčové slovo for (odvozené od staršího Für), které bylo doplněno o step, while/until a do. Použití je snadné (v mnoha jazycích je ovšem until nahrazeno za to):

begin integer n, m, i, s;
      real sum;
      ininteger(0,n);
 
      for i:=1 step 1 until n do
      begin
            sum := sum + i
      end
 
      outinteger(1, s);
end

V dále zmíněném ALGOLu-W by zápis vypadal takto:

begin
    integer i;
    i := 1024;
    while i > 0 do
    begin
        write( i );
        i := i div 2
    end
end.

Pro implementaci nekonečné smyčky je možné použít malého triku – zde se hodnoty 2 nikdy nedosáhne, protože je použit krok 0:

begin integer i;
      for i:=1 step 0 until 2 do
          outtext("***")
end

V dále zmíněném ALGOLu-W by zápis vypadal takto:

begin
    for i := 1 step 0 until 2 do write( "***" )
end.

Smyčky je možné vnořovat:

procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
    value n, m; array a; integer n, m, i, k; real y;
begin integer p, q;
      y := 0; i := k := 1;
      for p := 1 step 1 until n do
          for q := 1 step 1 until m do
              if abs(a[p, q]) > y then
                  begin y := abs(a[p, q]);
                      i := p; k := q
                  end
end Absmax

9. Příkaz skoku

V ALGOLu se používal i příkaz skoku, především pro implementaci složitějších programových smyček. Pro tento účel se používalo klíčové slovo goto, někdy též dvousloví go to:

begin
        integer n;
        n := 0;
start:;
        if n = 20 then goto finish
        else
        begin n := n + 1;
              outinteger(1, n);
              goto start
        end;
finish:;
        outstring(1,"\n")
end

Na cíle skoků (návěští neboli label) však byla kladena stejná pravidla, jako na lokální proměnné. Jinými slovy – návěští byla viditelná jen v rámci svého bloku. To automaticky znamenalo, že nebylo možné skočit dovnitř bloku, ovšem naopak bylo možné z bloku vyskočit. Toto jednoduše pochopitelné pravidlo (které se nijak nevymyká lexikální viditelnosti proměnných) se kupodivu do některých dalších po-algolských jazyků nedostalo.

Příkladem je jazyk C, v němž je následující program přeložitelný i spustitelný:

#include <stdio.h>
 
void main(void)
{
    goto inside;
    {
        int i;
        for (i=0; i!=10; i++) {
            puts("*");
inside:
            puts("inside");
        }
    }
}

Nebo Turbo Pascal, jehož koncepce bloků je převzata z ALGOLu:

program goto_test;
 
label
    inside;
var
    i:integer;
 
begin
    goto inside;
 
    for i := 1 to 10 do
    begin
        writeln(i);
        inside:
        writeln('inside');
    end;
    readln;
end.

Ovšem neplatí to pro Go:

package main
 
import "fmt"
 
func main() {
        var i int
        goto inside
        for i = 0; i != 10; i++ {
                fmt.Println("*")
        inside:
                fmt.Println("inside")
        }
}

Výsledek pokusu o překlad:

./goto.go:7:7: goto inside jumps into block starting at ./t.go:8:25

Obrázek 5: Skoky v Turbo Pascalu 7.0.

10. Volání hodnotou a volání jménem

Pravděpodobně nejproblematičtějším rysem ALGOLu (minimálně pro tvůrce překladačů) byl způsob volání funkcí a procedur (kde procedura je funkce, která nevrací hodnotu). V ALGOLu existují dva způsoby předávání parametrů funkcím a procedurám. První způsob se jmenuje předávání jménem (call-by-name nebo možná přesněji pass-by-name) a druhý předávání hodnotou (call-by-value, pass-by-value) neboli přiřazením. Nejdříve si ukažme druhý způsob, protože ten se z ALGOLu (a LISPu) rozšířil i do většiny dalších programovacích jazyků. Ještě před zavoláním funkce/procedury jsou parametry vyhodnoceny a je předána jejich výsledná hodnota, což známe i z dalších programovacích jazyků. Předání jménem je složitější – celý parametr (což může být složitý výraz) je do volané funkce předán tak, jak je zapsán a v těle funkce je jméno parametru tímto výrazem nahrazeno, jakoby se jednalo o expanzi makra (což je právě pro překladač složité). O tom, jak se parametry předávají, může programátor rozhodnout použitím klauzule value.

Podívejme se na příklad:

procedure sum(suc, alfa, i, a, b);
    value a, b;
    real alfa, suc;
    integer i, a, b;
    begin suc := 0;
          for i := a step 1 until b do
              suc := suc + alfa;
    end

Této proceduře se předává pět parametrů, přičemž parametry a a b jsou předány hodnotou (jako v běžných jazycích) a zbylé parametry jménem neboli „textovou expanzí“. Pokud tuto proceduru zavoláme stylem:

sum(result, u+v/2, counter, 10*x, 10*y+5)

bude se procedura vykonávat zhruba tak, jakoby se jednalo o tento kód zapsaný přímo do místa volání:

a := 10*x;
b := 10*y+5;
begin result := 0;
      for counter := a step 1 until b do
          result := result + u+v/2
end

V později vytvořených algolských jazycích bylo volání jménem nahrazeno za volání odkazem (což je případ Pascalu), popř. bylo zavedeno pouze volání hodnotou, ovšem s tím, že lze získat ukazatel na libovolnou proměnnou (C, Go).

11. Další vývoj ALGOLu: rozkol v komisi

ALGOL-60 se stal poměrně populární a dobře doplňoval ostatní dva dobové mainstreamové jazyky – FORTRAN a LISP. Po vydání „Reportu“ o ALGOLu-60 vznikla pracovní skupina, která měla za úkol navrhnout další verzi ALGOLu. V roce 1966 se komise rozhodovala mezi trojicí návrhů. Jeden z návrhů podal Niklaus Wirth, další byl podán Van Wijngaarden, o němž jsme se již zmínili v souvislosti s originálním ALGOLem. Zatímco Wirthův návrh směřoval spíše ke zjednodušení jazyka, byl Van Wijngaardenův návrh mnohem komplexnější a představoval vlastně zcela nový jazyk. A právě tento návrh byl přijat jako základ pro jazyk později pojmenovaný C++^H^H^H ALGOL 68.

Toto rozhodnutí nebylo přijato všemi členy komise s nadšením (diplomaticky řečeno). Hlavními kritiky byl jak Wirth, tak i (a to možná především) C.A.R. Hoare. Tito dva členové komisi opustili a mezi řádky můžeme číst, že se nejednalo o přátelské rozloučení. Wirth poté pokračoval ve vývoji vlastního jazyka, který vešel ve známost pod jménem ALGOL-W (paradoxní je, že i Van Wijngaarden mohl vytvořit jazyk se stejným jménem).

Obrázek 6: Snímek z videa vývoje popularity programovacích jazyků.

12. ALGOL-68

„The complexity of Algol 68, intrinsic to it, has contributed to the fact that the language was nested primarily in the academic and university environment and did not find a large support in the industry. There was a danger that Algol 68 could have become an object of purely mathematical investigations with all closeness proper to them.“

Jak již bylo naznačeno v předchozím textu, vedl návrh ideového pokračovatele ALGOLu-60 ke vzniku jazyka, který byl pojmenován ALGOL-68. Jednalo se o jazyk velmi komplikovaný, což brzdilo jeho zavedení do praxe – týkalo se to jak výrobců překladačů, tak i potenciálních uživatelů. Ostatně samotný popis tohoto jazyka měl několik set stránek psaných dosti těžkopádným stylem; porovnejte například s popisem jazyka Lua, který se vejde na dvě stránky nebo s cheatsheetem k jazyku Go, který má stran šest (i když nejde o tak rigorózní popis, jako u ALGOLu-68, prakticky všem programátorům postačí). Pro popis jazyka byla zavedena nová notace (W-Grammar podle jejího autora Adriaana van Wijngaardena, s nímž jsme se již setkali), v níž se nepopisovaly pouze sekvence klíčových slov a dalších identifikátorů (BNF, EBNF), ale i datový typ platný v daném kontextu. Samotný ALGOL-68 sice byl implementovaný, a to vícekrát, ovšem stále se u něj opakovalo tvrzení „no implementations and no users“.

Nutno poznamenat, že se v ALGOLu-68 objevilo mnoho konceptů, které byly až později přidány do dalších jazyků. Příkladem může být operátor PLUSAB neboli ‘PLUS And Becomes, který odpovídá céčkovskému += (a podobně i další aritmetické operátory). Najdeme zde i koncept, kdy se začátek nějaké konstrukce ukončuje stejným klíčovým slovem, ovšem napsaným pozpátku (viz též adopce tohoto způsobu v BASHi):

IF bool THEN some_expression ELSE other_expression FI
CASE intvalue IN expr1, expr2, …, exprN OUT  another expr ESAC

Příklad použití:

days in month :=
  CASE month OF date IN
    31,
    IF is leap year( year OF date ) THEN 29 ELSE 28
    FI,
    31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  ESAC
Poznámka: vtipkuje se, že je dobře, že autoři jazyka tento koncept nedovedli do důsledků, protože by se namísto END muselo psát NIGEB.

V ALGOLu-68 se taktéž v některých implementacích setkáme s takzvaným stroppingem. Jedná se o techniku použitou v některých (většinou postarších) programovacích jazycích pro přesnější určení klíčových slov, operátorů či jiných identifikátorů. Příkladem stroppingu mohou být některé původní operátory ve FORTRANu zapisované stylem .eq., .ne. atd. (stropping je tvořen oněmi tečkami). V ALGOLu se někdy používal zápis bez stroppingu, typicky při tvorbě článků:

¢ underline or
   bold typeface ¢
 mode xint = int;
 xint sum sq:=0;
 for i while
   sum sq≠70×70
 do
   sum sq+:=i↑2
 od

Překladače ovšem mnohdy vyžadovaly označení klíčových slov, což je dosti nepřehledný způsob, který navíc může vést k mnoha chybám:

'pr' quote 'pr'
'mode' 'xint' = 'int';
'xint' sum sq:=0;
'for' i 'while'
  sum sq≠70×70
'do'
  sum sq+:=i↑2
'od'

ALGOL-68 sice nebyl z globálního pohledu příliš úspěšný (zvláště když si uvědomíme, kam mezitím dospěl Pascal a především C), ovšem i přesto se používal. Příkladem mohou být systémy vytvářené v SSSR, kde byl ALGOL (Алгол využitý například i na prozatím nezmíněných počítačích Elbrus a Odra), popř. jeho varianta pojmenovaná Алгэк, která byla jakýmsi hybridem mezi COBOLem a originálním ALGOLem. Ve variantě ALGOLu-68 byly programovány i některé subsystémy raketoplánu Buran.

13. Algol-W

„In my opinion, Algol W is a much better teaching language than Pascal or pretty much any of the languages which have followed it.“

Paralelně a nezávisle na vývoji ALGOLu-68 pokračoval Wirth v návrhu jazyka nazvaného ALGOL-W (též psáno Algol-W). Tento jazyk se již některými svými vlastnostmi přibližoval (tehdy pochopitelně neexistujícímu) Pascalu, i když prozatím chyběla nejzásadnější vlastnost Pascalu – jeho typový systém. Jazyk dodržoval blokový zápis programů, nabízel více základních datových typů, novou konstrukci programové smyčky a několik dalších vylepšení. Syntaxe jazyka byla, jak se stalo u „pascalské“ větve zvykem, popsána pomocí BNF.

Mezi rezervovaná klíčová slova patřila:

ABS       ALGOL     AND       ARRAY     ASSERT
BEGIN     BITS      CASE      COMMENT   COMPLEX
DIV       DO        ELSE      END       FALSE
FOR       FORTRAN   GO TO     GOTO      IF
INTEGER   IS        LOGICAL   LONG      NULL
OF        OR        PROCEDURE REAL      RECORD
REFERENCE REM       RESULT    SHL       SHORT
SHR       STEP      STRING    THEN      TRUE
UNTIL     VALUE     WHILE

Příklad procedury naprogramované v Algolu-W:

procedure PQ_Sink(integer value k);
begin
    logical Done;
    Done := false;
 
    while 2*K <= PQ_Size and not Done do
    begin
        integer J;
        J := 2 * K;
        if J < PQ_Size and PQ_Greater(J, J+1)
        then
            J := J + 1;
        if PQ_Greater(K, J)
        then begin
            PQ_Exchange(K, J);
            K := J;
        end
        else begin
            Done := true;
        end;
    end
end;
Poznámka: jedná se o proceduru použitou při implementaci prioritní fronty.

14. Rozdíly mezi ALGOLem-60 a Algolem-W

Mezi původním ALGOLem-60 a Wirthovým Algolem-W nalezneme několik rozdílů, zjednodušení a současně i rozšíření. Zajímavé je, že některé změny byly později samotným Wirthem navrhnuty v jeho dalším jazyku – přelomovém Pascalu:

  1. Algol-W používal datový typ logical a nikoli boolean. V Pascalu jsme se vrátili k ALGOLu.
  2. Indexy polí se zapisovaly do kulatých závorek. Jak ALGOL-60, tak i Pascal používají hranaté závorky.
  3. Pro celočíselné dělení se používá operátor div a nikoli %.
  4. Typy parametrů předávaných do procedur jsou zapisovány přímo uvnitř závorek za jménem procedury (jako v Pascalu, ANSI C, Javě, Go atd. atd.).
  5. Byly definovány nové datové typy long real, complex, long complex, bits a řetězce o délce maximálně 255 znaků (s tím později bojoval i Pascal).
  6. Podpora záznamů (struktur) a referencí na ně (prakticky nutnost pro rozsáhlejší projekty). Koncept záznamů byl zachován i v Pascalu.
  7. Komentáře zapisované do % … % namísto použití commentend.
  8. Nový typ programové smyčky while() do, kterou taktéž známe z Pascalu.
  9. Smyčka for nutně nevyžadovala použití klauzule step
  10. Nově byly definované procedury pro vstup a výstup.

15. Od Algolu-W k Pascalu

Od Algolu-W vedla již poměrně krátká cesta k programovacímu jazyku Pascal, jehož první verze vznikla v roce 1970, což mimochodem představuje další kulaté výročí. Tím se však budeme zabývat až v navazujícím článku.

Obrázek 7: Hlavní menu vývojového prostředí Turbo Pascalu 1.0. Z tohoto menu se vyvolávaly jednotlivé moduly integrovaného vývojového prostředí. Teprve později došlo k úplnému sjednocení jednotlivých částí a hlavní obrazovkou se stal samotný programátorský editor se stavovým řádkem a hlavním menu.

16. Komu vděčíme za složené závorky a operátory ++ a –?

Zdánlivě nezávisle na ALGOLu a jím inspirovaných programovacích jazyků se v Bellových laboratořích začal vyvíjet nový typ operačního systému, který se později proslavil pod jménem UNIX. Kromě samotného jádra UNIXu byl pro tento operační systém vyvinut i jednoduchý textový editor, assembler, interpret příkazů (předchůdce dnešních shellů) a několik základních utilit, odpovídajících dnešním programům rm, ls, cp či cat.

pdp2

Obrázek 8: Počítač PDP-7.

Ken Thompson a jeho kolega Dennis Ritchie, kteří se na UNIXu podíleli, se oprávněně domnívali, že nově vytvořený operační systém vyžaduje také nový systémově orientovaný programovací jazyk, tj. jazyk, ve kterém by bylo možné psát systémové programy a popř. i uživatelské aplikace (ovšem s prioritou na vývoj samotného operačního systému). Nejprve se sice uvažovalo o využití překladače Fortranu, ovšem tato myšlenka byla vzhledem k mnoha omezeným hardwarovým možnostem mikropočítače PDP-7 následně opuštěna. Namísto toho Ken Thompson vytvořil nový programovací jazyk nazvaný jednoduše B. Tento jazyk byl založen na existujícím jazyku BCPL (Basic Combined Programming Language), jenž byl vytvořen Martinem Richardsem již v roce 1966 a jehož „dědečkem“ byl právě ALGOL. Vzhledem k tomu, že jazyk BCPL byl z hlediska konstrukce překladače poměrně složitý (což je poněkud paradoxní, neboť se jednalo o zjednodušený jazyk CPL ze začátku šedesátých let), nebylo možné, aby se jeho překladač na mikropočítači PDP-7 spouštěl z operačního systému, protože jen pro samotný překlad zdrojových kódů bylo zapotřebí cca 16 kB operační paměti.

pdp2

Obrázek 9: Známá fotografie Kena Thompsona a Dennise Ritchieho sedících před PDP.

17. Vybrané vlastnosti programovacího jazyka „B“

Z tohoto důvodu Ken Thompson z původního jazyka BCPL odstranil některé vlastnosti, které nepovažoval za podstatné (například složitější typy programových smyček) a naopak změnil jeho základní syntaxi takovým způsobem, aby se zápis programů mohl co nejvíce zkrátit. Právě z této snahy například pochází i způsob zápisu operátorů s využitím speciálních znaků a nikoli klíčových slov (včetně zcela nových operátorů ++ a –), což je zvyk používaný doposud – viz například současné programovací jazyky, jakými jsou C, C++, Java, JavaScript či programovací jazyky Go a Rust. Taktéž se v jazyku B objevuje použití středníků pro ukončení příkazů (ovšem s jiným sémantickým významem, než v ALGOLu či Pascalu).

Thompson navíc při programování překladače použil techniku využívanou dodnes – překladač programovacího jazyka B byl napsán v přímo v samotném jazyku B, což sice na samotném začátku vyžaduje takzvaný bootstrap (například první interpretr napsaný v assembleru), ale ve výsledku tato metoda vedla jak ke zrychlení vývoje, tak i ke kvalitnějšímu návrhu jazyka (z tohoto hlediska není nic lepšího, než když je programátor nucen používat své vlastní produkty :-). Při pohledu do referenční příručky jazyka B, popř. na ukázku programového kódu je vidět nápadná shoda s programovacím jazykem C, o kterém se zmíníme později (v podstatě zde chybí datové typy a struktury):

/* The following program will calculate the constant e-2 to about
   4000 decimal digits, and print it 50 characters to the line in
   groups of 5 characters.  The method is simple output conversion
   of the expansion
     1/2! + 1/3! + ... = .111....
   where the bases of the digits are 2, 3, 4, . . . */
 
main() {
        extrn putchar, n, v;
        auto i, c, col, a;
 
        i = col = 0;
        while(i<n)
                v[i++] = 1;
        while(col<2*n) {
                a = n+1 ;
                c = i = 0;
                while (i<n) {
                        c =+ v[i] *10;
                        v[i++]  = c%a;
                        c =/ a--;
                }
 
                putchar(c+'0');
                if(!(++col%5))
                        putchar(col%50?' ': '*n');
        }
        putchar('*n*n');
}
 
v[2000];
n 2000;

Na programovacím jazyku B bylo zvláštní především to, že podporoval pouze jeden datový typ – slovo (word) – jehož bitová šířka se měnila podle toho, pro jaký procesor byly programy překládány. I adresy v paměti byly reprezentovány pomocí slov (přesněji jako indexy do pole, neboť paměť byla v B považována za jedno velké lineární pole), což se později ukázalo být problematické, protože na mnoha platformách mají adresy jinou bitovou šířku než slova zpracovávaná procesorem a i aritmetické a relační operace s adresami jsou mnohdy „zvláštní“. Nicméně pro účely systémového programování na počítači PDP-7 programovací jazyk B vyhovoval a jeho překladače byly později naprogramovány i pro některé další minipočítače, například dále popsaný PDP-11.

Druhá zvláštnost spočívá v tom, že překladač jazyka B na PDP-7 i na PDP-11 překládal program nikoli přímo do strojového kódu, ale do bajtkódu, který musel být následně interpretován. Jednalo se ve své podstatě o stejnou technologii, jaká je použita například u P-kódu (Pascal) či u interpretrů Javovského bajtkódu (dnes se již čisté interpretry tohoto bajtkódu v reálných JRE nepoužívají).

18. Vznik programovacího jazyka „C“

Některé vlastnosti výše zmíněného programovacího jazyka B implementovaného na počítačích PDP-7 a později i na PDP-11 však nebyly příliš vhodné pro systémové programování, například z toho důvodu, že PDP-11, na rozdíl od PDP-7, zpracovával data různých bitových šířek, včetně bajtů (ASCII znaky). Z tohoto důvodu se vývojáři v Bellových laboratořích rozhodli, že v rámci přechodu na počítač PDP-11 vytvoří nový programovací jazyk, který mj. umožní více odstínit programátora od hardwarové architektury počítače. Tento programovací jazyk – „nový B“ – se na návrh Kena Thompsona pojmenoval C. Jestli se jedná o další písmeno v abecedě (‚C‘==‚B‘+1) nebo o následující znak v označení předchůdce obou jazyků – jazyka BCPL, je již otázka, kterou tvůrci ponechali nezodpovězenou.

MIF20 tip google

pdp2

Obrázek 10: Brian Kernighan, který spolu s Dennisem Ritchiem napsal světoznámou knížku „C Programming Language“, podle níž se popisovaný dialekt označuje K&R. Počáteční písmeno jeho příjmení se rovněž vyskytuje v názvu programovacího jazyka AWK.

Na jazyk C, který byl standardizován v několika normách (ANSI C, ISO C, viz též C89, C90, C95, C99, C11 a C18; pravděpodobně vznikne i C2×) již přímo navázaly další programovací jazyky, z nichž mnohé se používají dodnes (podobně jako samotné céčko, které je stále populární). Nejdříve „C with Classes“, z něhož se vyvinul programovací jazyk C++. Dále pak jazyky D, Objective C, Java a JavaScript, ovšem velký vliv programovacího jazyka C můžeme vidět i na dalších programovacích jazycích, například na jazyku Rust či Go.

Poznámka: zajímavá situace nastala v případě programovacího jazyka Go. Od ALGOLu-60 se totiž vývoj „algolských“ jazyků rozdělil do dvou větví – „pascalské“ (poněkud s nadsázkou se používá označení evropská větev) a „céčkové“ (americká větev). A u jazyka Go došlo k opětovnému spojení obou větví; v mnoha ohledech má Go blíže k Algolu, než k jazyku C.

19. Literatura

  1. V. Jankovič:
    ALGOL – FORTRAN – COBOL
    ALFA, 1972
  2. C.A.R. Hoare:
    The Emperor's Old Clothes
    Communications of the ACM, 1981
  3. IBM:
    IBM System/360 Operating System: ALGOL Language
     IBM
  4. B. Randell and L.J. Russell:
    ALGOL 60 Implementation: The Translation and Use of ALGOL 60 Programs on a Computer
    Academic Press, 1964. The design of the Whetstone Compiler.
  5. E. W, Dijkstra:
    Algol 60 translation: an algol 60 translator for the x1 and making a translator for algol 60
    report MR 35/61. Mathematisch Centrum, Amsterdam, 1961.
  6. Peter O'Hearn and Robert Tennent:
    Algol-like Languages
    Progress in Theoretical Computer Science Volume 2
  7. D. J. Malcolme-Lawes:
    Programming — ALGOL
    The Commonwealth and international library of science, technology, engineering, and liberal studies
  8. F. L. Bauer:
    Introduction to Algol
    Prentice Hall (January 1964)
  9. Carl-Erik Ekman, Torgil; Froberg:
    Introduction to Algol Programming
    Studentlitteratur
Poznámka: v naprosté většině případů se jedná o muzeální výtisky.

20. Odkazy na Internetu

  1. Algol 60 Lego Pieces
    http://algol60.org/6legoPieces.htm
  2. Report on the Algorithmic Language ALGOL 60
    http://www.softwarepreser­vation.org/projects/ALGOL/re­port/Algol60_report_CACM_1960_Ju­ne.pdf
  3. ALGOL na Wikipedii
    https://en.wikipedia.org/wiki/ALGOL
  4. ALGOL: The Best Language You’ve Never Heard Of
    https://www.whoishostingthis­.com/resources/algol/
  5. Timeline of programming languages
    https://en.wikipedia.org/wi­ki/Timeline_of_programmin­g_languages
  6. A History of Computer Programming Languages
    https://cs.brown.edu/~adf/pro­gramming_languages.html
  7. ALGOL 60 (Wikipedia)
    https://en.wikipedia.org/wi­ki/ALGOL60
  8. Revised Report on the Algorithmic Language Algol 60
    https://www.masswerk.at/al­gol60/report.htm
  9. Does anyone still use the ALGOL programming language?
    https://www.quora.com/Does-anyone-still-use-the-ALGOL-programming-language
  10. Was ALGOL ever used for “mainstream” programming?
    https://stackoverflow.com/qu­estions/1463321/was-algol-ever-used-for-mainstream-programming
  11. ALGOL W – Introduction
    https://try-mts.com/algol-w-introduction/
  12. ALGOL 60 – Language features
    https://try-mts.com/algol-60-language-features/
  13. A COURSE OF ALGOL 60 PROGRAMMING
    http://archive.computerhis­tory.org/resources/text/al­gol/ACM_Algol_bulletin/1064048/fron­tmatter.pdf
  14. The Algol 68 Genie project
    https://jmvdveer.home.xs4a­ll.nl/en.algol-68-genie.html
  15. ALGOL based programming languages
    https://en.wikipedia.org/wi­ki/Generational_list_of_pro­gramming_languages#ALGOL_ba­sed
  16. Category:ALGOL 60 (Rosetta Code)
    http://rosettacode.org/wi­ki/Category:ALGOL60
  17. Category:ALGOL W (Rosetta Code)
    http://rosettacode.org/wi­ki/Category:ALGOL_W
  18. Algol W
    https://everything2.com/ti­tle/Algol%2520W
  19. Historic Documents in Computer Science
    http://web.eah-jena.de/~kleine/history/history.html
  20. A comparison of PASCAL and ALGOL 68
    https://academic.oup.com/com­jnl/article/21/4/316/356817
  21. Stropping (syntax)
    https://en.wikipedia.org/wi­ki/Stropping_(syntax)
  22. A contribution to the development of ALGOL
    https://dl.acm.org/doi/10­.1145/365696.365702
  23. Syntax the Algorithmic Language Algol 60
    http://cse.csusb.edu/dick/sam­ples/algol60.syntax.html
  24. Scope (computer science)
    https://en.wikipedia.org/wi­ki/Scope_(computer_science)
  25. Scope and closure (LISP)
    https://en.wikipedia.org/wi­ki/Lisp_(programming_langu­age)#Scope_and_closure
  26. Programming languages in MTS
    https://try-mts.com/programming-languages-in-mts/
  27. ALGOL 60 – Josephus problem
    https://try-mts.com/algol-60-josephus-problem/
  28. ALGOL W – Priority queue
    https://try-mts.com/algol-w-priority-queue/
  29. Syntaxe a sémantika Algolu
    http://www.softwarepreser­vation.org/projects/ALGOL/pa­per/Backus-Syntax_and_Semantics_of_Pro­posed_IAL.pdf
  30. John Backus
    https://en.wikipedia.org/wi­ki/John_Backus
  31. Backus–Naur form
    https://en.wikipedia.org/wi­ki/Backus%E2%80%93Naur_form
  32. The future's bright… the future's Cobol
    https://www.root.cz/clanky/the-future-s-bright-the-future-s-cobol/
  33. Sedmdesátiny assemblerů: lidsky čitelný strojový kód
    https://www.root.cz/clanky/sed­mdesatiny-assembleru-lidsky-citelny-strojovy-kod/
  34. Třicet let od vydání revolučního Turbo Pascalu 5.5
    https://www.root.cz/clanky/tricet-let-od-vydani-revolucniho-turbo-pascalu-5–5/
  35. Algol 60 Forever!
    http://algol60.org/
  36. Heinz Rutishauser
    https://en.wikipedia.org/wi­ki/Heinz_Rutishauser
  37. The Development of the C Language
    http://cm.bell-labs.com/cm/cs/who/dmr/chist.html
  38. B (programming language)
    http://en.wikipedia.org/wi­ki/B_(programming_language)
  39. Users' Reference to Bo
    http://cm.bell-labs.com/cm/cs/who/dmr/kbman.html
  40. THE PROGRAMMING LANGUAGE B
    http://cm.bell-labs.com/cm/cs/who/dmr/bintro.html
  41. BCPL
    http://en.wikipedia.org/wiki/BCPL
  42. Algol 68 – Years in the USSR
    http://www.computer-museum.ru/english/algol68.htm
  43. Programming languages genealogical tree
    https://github.com/stereo­booster/programming-languages-genealogical-tree
  44. NASE A60 Algol Interpreter
    https://www.bertnase.de/a60/
  45. Most Popular Programming Languages 1965 – 2019
    https://www.youtube.com/wat­ch?v=Og847HVwRSI
  46. Comparison of programming languages
    https://en.wikipedia.org/wi­ki/Comparison_of_programmin­g_languages