Rozcestník

Vývoj a dělení prvních programovacích jazyků v období 50. - 70. let 20. století

První programovací jazyky, které vznikly v 50. letech 20. století přinesly rozsáhlou revoluci v oblasti výpočetní techniky. Programovací jazyky byly důležité pro rozvoj vědeckých a obchodních aplikací, umožňující programátorům psát kódy, které jsou srozumitelné pro lidi, a zároveň i pro počítače. V 50. letech vznikly programovací jazyky jako Fortran a LISP, které poskytly základy později příchozím jazykům, numerickým výpočtům i umělé inteligenci.

V následujícím období 60. a 70. let 20. století se realizoval významný vývoj programovacích jazyků, přičemž došlo k prvnímu formování programovacích paradigmat1. Programovací jazyky typu Cobol, Pascal a Algol60 definovaly strukturované2 a imperativní3 přístupy, které položily základ moderního programování.

Dělení programovacích jazyků

Ke dnešním dnům existují stovky, dokonce až jednotky tisícovek programovacích jazýků. Určit přesný počet je pravděpodobně nemožné, neboť žáleží na způsobu definice, co je zcela nový jazyk a co pouze nová verze jazyka již existujícího. Každý jazyk je určen pro určitou platformu, operační systém, styl kódování a zamýšlené použití. Některé žijí v relativní neznámosti, zatímco jiné jsou velmi žádané.

V následujících odstavcích se však zaměříme téměř výhradně na programovací jazyky z počátků 2. poloviny 20. století, a to s důrazem na jejich vlastnosti a rozdíly, z nichž vyplývají možnosti rozřazení těchto jazyků do patřičných skupin. [10]

Abstrakce programovacích jazyků

Jedno ze základních dělení je podle úrovně abstrakce, kterou daný jazyk poskytuje. Označení „nižší“ odkazuje na velmi malý, nebo žádný rozdíl, neboli abstrakci, mezi daným programovacím jazykem a instrukční sadou procesoru. Taktéž bývají nízkoúrovňové programovací jazyky označovány jako „těsně spjaté s hardwarem“, neboť se v nich píší programy na míru danému hardweru. Program napsaný v nižším programovacím jazyce může být typicky rychlejší a mít menší nároky na paměť než ekvivalentní program napsaný ve vyšším programovacím jazyce.

Nejdominatnější nízkoúrovňový jazyk je bezesporu Assembler (1949). Celým názvem jazyk symbolických adres (JSA) či jazyk symbolických instrukcí. Jazyk je založen na náhradě kódů instrukcí mnemotechnickými zkratkami anglických slov, které vyjadřují, co daná strojová instrukce dělá. Dále jazyk umožňuje místo konkrétní číselné paměťové adresy používat symbolické adresy v podobě návěstí. Pro převod programu z JSA do strojového kódu se používá překladač, který se nazývá assembler. Tento název se přeneseně používá i pro samotný jazyk. Je to programovací jazyk nejnižší úrovně a je závislý na strojovém kódu procesoru. Každá rodina procesorů má svůj vlastní odlišný JSA, protože ve strojových instrukcích různých rodin procesorů a možnosti rozdělování a adresování paměti bývají zásadní rozdíly. Každá firma vyrábějící procesory si definuje vlastní pravidla pro JSA svých procesorů, z kterých mohou (ale také nemusejí) vycházet nezávislí autoři a firmy.

obr. 4.: Assembler rutina pro sečtení všech prvků v poli [13]

JSA umožňuje psát extrémně rychlé a paměťově úsporné programy. Jeho nevýhody jsou především závislost na konkrétním procesoru, v důsledku čehož neumožňuje snadnou přenositelnost na jinou platformu. Navíc jeho kód je dlouhý a obtížně se hledají chyby. Proto se používá jen pro určité úlohy a ostatní části softwaru se vytvářejí ve vyšších programovacích jazycích.

Ekvivalentní programy napsané ve vyšším programovacím jazyce jsou typicky pomalejší a mají větší paměťové nároky, avšak oddělují sémantiku počítačové platformy od zápisu programu, což značně zjednodušuje jeho vývoj. Mezi další výhody se řadí například kompatibilita na různých platformách, logická struktura zdrojového kódu a kratší a lépe čitelný kód. Vyšší jazyky však sebou přináší nutnost použití kompilátoru/interpretu, neboť procesory abstraktní programovaí jazyky číst neumí, a tak je potřebují přeložit/interpretovat do již zmíněného jazyka symbolických adres.

Mezi úspěšné vyšší programovací jazyky pro námi zkoumané období se řadí Fortran, Lisp, Cobol, Algol, Basic a Pascal. Každý ze zmíněných vznikl za jiným účelem a nesmazatelně se zapsal do dějin informatiky. Je pozoruhodné, kolik z nich nachází uplatnění i dnes, i když už poměrně okrajově. [11] [13]

Kompilovat či interpretovat, to je oč tu běží

Další ze základních dělení vyšších jazyků se doslova samo nabízí, neboť každý z nich musí být pro procesor přeložen nebo interpretován. V některých případech dokonce obojí.

Kompilované jazyky jsou například Fotran (1957), Algol (1958), Cobol (1960), Basic (1964), Pascal (1970), Java (1995), a mnoho dalších. Každý program napsaný v kterémkoliv z těchto jazyků je před spuštěním nejdříve kompletně přeložen kompilátorem do strojového kódu cílového procesoru. Výstupem kompilace je obvykle spustitelný binární kód (.exe, .dll, ...), ze kterého nelze jednoduše zpětně odvodit, jak vypadal původní zdrojový kód.

Interpretované jazyky, jako například Basic, Python (1991), PHP (1995), Java a mnoho dalších, umožňují přímo vykonávat (interpretovat) zápis programu v jeho zdrojovém kódu ve zvoleném programovacím jazyce. Program proto není nutné převádět do strojového kódu cílového procesoru, jako je tomu v případě kompilátoru. Interpret tak umožňuje programování kódu, který je snadno přenositelný mezi různými počítačovými platformami. Shell vytvářející příkazový řádek je taktéž interpretován.

Interprety se mohou chovat třemi různými způsoby podle toho, jak zpracovávají zdrojový kód programu:
      1. provádějí přímo zdrojový kód (Basic),
      2. přeloží zdrojový kód do efektivnějšího mezikódu, který následně spustí (Python),
      3. přímo spustí předem vytvořený předkompilovaný mezikód, který je produktem části interpretu (Pascal, Java).

Hlavní nevýhodou interpretu je, že v případě, kdy je program interpretován, zpravidla probíhá pomaleji, než když je kompilován. Rozdíl v rychlosti závisí na velikosti programu. Obvykle trvá déle spouštět program přes interpret než spouštět kompilovaný kód, ale může trvat kratší dobu, než je celková doba potřebná ke kompilaci a spuštění. To je důležité zejména při testování kódu, jelikož cyklus editace – interpretace – ladění může být často mnohem kratší, než je cyklus editace – kompilace – spuštění – ladění.

Tento způsob kategorizace programovacích jazyků však není stoprocentní, jelikož řada programovacích jazyků existuje v implementaci jak interpretované, tak kompilované (Basic, Java). Například Basic má řadu dialektů, z nichž jedna část využívá interpretaci a druhá část kompilaci. Navíc jsou oba postupy někdy kombinovány. Zdrojový kód v takovém případě může být nejprve kompilován do mezikódu, který je poté interpretován.

Obecně si lze povšimnout, že s postupem let a vývoje jsou novější jazyky stále víc abstraktnější, a s tím jde ruku v ruce taktéž prefecence interpretu, a to právě z důvodu efektivnější a jednodušší práce pro vývojáře. Samozřejmě nebylo by to pravidlo bez výjimky, kterou je v tomto případě poptávka po nízkoúrovňových programech psaných na míru danému hardwaru. [11] [14]

Základní programovací paradigmata

Paradigma je způsob či styl, jakým programovací jazyk umožňuje vytváření, organizování a strukturování programů, pod čímž je myšlena tvorba jednotlivých prvků programu (objekty, funkce, proměnné, omezení, atd.), a možnosti definice kroků, ze kterých se výpočet skládá (přiřazení, vyhodnocení, datové toky, atd.).

Paradigmat existuje celá řada, a i když by se mohlo zdát, že každý programovací jazyk může realizovat pouze jedno paradigma, opak je pravdou. Některé jazyky se označují jako takzvané multiparadigmatické programovací jazyky. V následujícím dělení se zaměříme pouze na několik základních paradigmat, která byla pro začátek druhé poloviny 20. století klíčová.

1. Imperativní

Taktéž označováno jako procedurální programování, které cílí na popis výpočtu pomocí posloupnosti příkazů a určuje přesný postup, jak danou úlohu řešit. Program je sadou proměnných, jenž v závislosti na vyhodnocení podmínek mění pomocí příkazů svůj stav. Tento přístup je snadno pochopitelný, neboť se dá jednoduše přirovnat například ke kuchařskému receptu, který se typicky skládá z příkazů krok za krokem a každý příkaz je v závislosti na podmínkách svázán s určitým stavem jídla. Naivní imperativní jazyky jsou svojí nesystematičností podobné nestrukturovaným jazykům. Ukázkovým zástupcem je raná verze jazyku Basic.

      1.1. Nestrukturované

Programy jsou lineárními sekvencemi příkazů a skoky jsou v nich realizovány příkazem typu „go to“ – tedy „jdi na řádek“. V raných jazycích tohoto stylu byly navíc všechny řádky programu číslované a skoky šlo realizovat pouze uvedením konkrétního čísla řádku, což bylo velmi nepraktické. Později se objevily jazyky využívající návěstí, tedy textová označení míst, kam má program skočit. Typickými zástupci jsou rané verze jazyků Fortran a Cobol.

      1.2. Strukturované

Kvůli nepraktičnosti příkazu skoku „go to“ (ta vězí zejména v tom, že struktura programu nedává prakticky žádnou informaci o jeho vykonávání, což velmi komplikuje jeho ladění) vzniklo strukturované paradigma. Jeho hlavním přínosem je fakt, že nahrazuje příkazy skoku pomocí podmíněných cyklů („opakuj, dokud platí podmínka“) a jiných strukturovaných instrukcí, které se do sebe vnořují. Typickými zástupci jsou jazyky Pascal a C.

2. Deklarativní

Založeno na myšlence programování pomocí definic, co se má udělat, a nikoliv jak se to má udělat. Opakem tohoto principu je již zmíněné imperativní programování popisující jednotlivé úkony pomocí algoritmů. Zjednodušeně to lze popsat tak, že imperativní programy obsahují algoritmy, kterými se dosáhne chtěný cíl, zatímco deklarativní jazyky specifikují cíl a algoritmizace je ponechána interpretu daného jazyka. Snaží se minimalizovat používání proměnných, zejména globálních proměnných. Taktéž neobsahují prostředky, jak provést cyklus známý jako „do-while“ nebo „for“. Vše je řešeno pomocí rekurze. Jako příklad může posloužit dotazovací jazyk SQL (1979) a logické jazyk Prolog (1972).

obr. 5.: Deklarativní rodokmen [12]

      2.1. Funkcionální

Jedná se o typ deklarativního programovacího paradigmatu, které chápe výpočet jako vyhodnocení matematických funkcí. Výpočtem funkcionálního programu je posloupnost vzájemně ekvivalentních výrazů, které se postupně zjednodušují. Výsledkem výpočtu, pokud se k němu podaří dospět, je výraz v dále nezjednodušitelné formě. Program je chápán jako jedna funkce obsahující vstupní parametry mající jediný výstup. V praxi je rozdíl mezi matematickou funkcí a představou funkce použité v imperativním programování. Imperativní funkce mohou mít vedlejší účinky, které mění stav programu. Z toho důvodu postrádají referenční transparentnost: Stejné volání může vést k různým návratovým hodnotám v závislosti na stavu vykonávaného programu. Oproti tomu ve funkcionálním kódu návratové hodnoty funkcí záleží pouze na argumentech funkce, a tudíž dvě volání téže funkce se stejnými argumenty vrací vždy stejnou hodnotu. Eliminace vedlejších účinků může zjednodušit analýzu a pochopení chodu programu, což je jednou z klíčových motivací pro vývoj funkčního programování. Pro toto paradigma jsou realizovány i hybridními jazyky, které mohou obsahovat i prvky, které jsou v rozporu se základními principy funkcionálního programování. Například často citovaný typický funkcionální jazyk Lisp je ve skutečnosti jazykem hybridním, neboť umožňuje modifikovat hodnoty již definovaných proměnných. [11] [12] [14]

1 paradigma: Základní způsob, jakým programovací jazyk umožňuje vytváření, organizování a strukturování programů.

2 strukturovaný přístup: Programování klade důraz na organizaci kódu pomocí jasně definovaných a čitelných struktur, což zvyšuje srozumitelnost, udržovatelnost a snižuje možnost chyb v programu.

3 imperativní přístup: Programování se zaměřuje na popis kroků, které počítač musí provést. Programátor přímo řídí, jakým způsobem se mají operace vykonat.

4 dialekt: Verze či varianta programovacího jazyka.

5 standard programovacího jazyka: Soubory pravidel pro způsob psaní kódu.

Reference

[1] „Flipperworld,“ 2 Únor 2019. [Online]. Available: https://cs.flipperworld.org/inertnet/fortran-jazyk-programovani-popis-hlavni-prikazy-a-funkce. [Přístup získán 25. říjen 2023].

[2] L. Hanyk, „Katedra geofyziky MFF UK,“ 15 Listopad 2011. [Online]. Available: chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://geo.mff.cuni.cz/~lh/NPRF017/Poprve-Fortran.pdf. [Přístup získán 25. říjen 2023].

[3] P. Tišňovský, „ROOT.CZ,“ Programovací jazyk LISP a LISP machines, 25. Březen 2010. [Online]. Available: https://www.root.cz/clanky/programovaci-jazyk-lisp-a-lisp-machines/. [Přístup získán 25. říjen 2023].

[4] P. Tišňovský, „ROOT.CZ,“ Jemný úvod do rozsáhlého světa jazyků LISP a Scheme, 9. červenec 2019. [Online]. Available: https://www.root.cz/clanky/jemny-uvod-do-rozsahleho-sveta-jazyku-lisp-a-scheme/. [Přístup získán 25. říjen 2023].

[5] P. Tišnovský, „ROOT.CZ,“ Programování mainframů: COBOL, 15. prosinec 2009. [Online]. Available: https://www.root.cz/clanky/programovani-mainframu-cobol/. [Přístup získán 25. říjen 2023].

[6] V. Čevela, „Historie programování a VT u nás,“ 23. květen 2020. [Online]. Available: http://prog-story.technicalmuseum.cz/index.php/cobol/374-detaily. [Přístup získán 25. říjen 2023].

[7] P. Tišnovský, „ROOT.CZ,“ Šedesátiny převratného programovacího jazyka ALGOL-60, 4. únor 2020. [Online]. Available: https://www.root.cz/clanky/sedesatiny-prevratneho-programovaciho-jazyka-algol-60/. [Přístup získán 27. říjen 2023].

[8] B. Corporation, „Computer History Museum,“ 1961. [Online]. Available: http://images.computerhistory.org/revonline/images/102627302-03-01.jpg?w=600. [Přístup získán 30 říjen 2023].

[9] „Pascal,“ ČVUT, [Online]. Available: https://iat.fs.cvut.cz/Pascal/aii/pascal.htm. [Přístup získán 27 říjen 2023].

[10] M. Upson, „Bootcamps by BestColleges,“ How Many Coding Languages Are There?, 18. dubna 2023. [Online]. Available: https://www.bestcolleges.com/bootcamps/guides/how-many-coding-languages-are-there/. [Přístup získán 14. Listopad 2023].

[11] Coursera , „coursera.org“ 5 Types of Programming Languages, 12. listopadu 2023. [Online]. Available: https://www.coursera.org/articles/types-programming-language/. [Přístup získán 16. listopadu 2023].

[12] O. Michálek, „itnetwork.cz“ Úvod do funkcionálního programování, 2019. [Online]. Available: https://www.itnetwork.cz/programovani/haskell/uvod-do-funkcionalniho-programovani/. [Přístup získán 17. listopadu 2023].

[13] P. Tišnovský, „mojefedora.cz“ Použití assembleru v Linuxu, 25. května 2016. [Online]. Available: https://mojefedora.cz/pouziti-assembleru-v-linuxu/. [Přístup získán 17. listopadu 2023].

[14] „Royalprice“, Klasifikace programovacích jazyků, [Online]. Available: https://royalprice.ru/cs/obzor-windows/klassifikaciya-yazykov-programmirovaniya-kompyuternye-yazyki/. [Přístup získán 17. listopadu 2023].