Zaměřené na určitý typ úloh:
Fortran, Algol 60 - vědeckotechnické výpočty
Cobol, RPG - hromadné zpracování dat
Snobol - manipulace s texty
Pascal - jednoduché výukové programy
GPSS, Simula, Simscript - modelování diskrétních systémů
ML/1 - univerzální makrojazyk
Univerzální (PL/I, Algol 68, Ada)
Jiné dělení
Procedurální (důraz na popis postupu výpočtu)
Neprocedurální (důraz na popis řešeného problému, např. LISP, Prolog, různé specializované jazyky)
Smíšené (prvky obou přístupů, např. C++)
Důležité pojmy
syntaxe - soubor gramatických pravidel jazyka
sémantika -
vztah mezi slovy a jejich významy. Na rozdíl od syntaxe, kde jde o
formální správnost struktury výroků, jde v sémantice o věcnou správnost
výroků. Sémantika se používá v programování a umělé inteligenci;
syntakticky správné, ale sémanticky nesprávné výroky a vztahy mohou
zapříčinit nečekané chyby programů, neboť nejsou obvykle automatickými
ladicími prostředky zjistitelné.
Generace programovacích jazyků
Počátky
programování – (někdy označována jako 0. generace)
Programování na mechanických strojích tenkrát znamenalo sestrojování
ozubených koleček, „ohřebíkovaných“ válečků a jiných součástek, později se
vyráběly jakési matrice, obdoba děrných štítků.
Prvním
programátorem na světě, o kterém víme, byla Augusta Ada Byron,
dcera básníka lorda Byrona. Jako na svou dobu mimořádně inteligentní a
cílevědomá žena se po své svatbě začala vzdělávat samostudiem a pomocí
domácích učitelů v různých vědních oborech, zaujala ji zejména fyzika
a matematika. Ada se začala věnovat také počítacím strojům, a tehdy se
seznámila s Charlesem Babbagem a jeho projektem Analytical Engine.
Pro tento stroj vytvářela různé programy. Z důvodů předčasné smrti
hraběnky Ady nebyl stroj úplně dokončen. Dochoval se ale téměř kompletní
program pro výpočet Bernoulliho čísel.
1. generace
V této generaci se vytvářely především
jednoúčelové programy, obvykle s využitím v matematice a fyzice.
“Programovacím jazykem” byl strojový kód, tedy přímo ten
kód, se kterým pracují elektronické součástky. Algoritmy byly zapsány
v paměti počítače přímo v číselném kódu, který zpracovával příslušný
procesor. Tento kód je ve své podstatě binární, z důvodů lepší čitelnosti
programu se však často místo binárního kódu používal osmičkový nebo
šestnáctkový kód.
Programátor tedy zapisoval přímo
číselné kódy, odpovídající jednotlivým instrukcím procesoru. Kódy byly
umístěny na pevně daných místech (adresách) v paměti, každá instrukce měla
jeden nebo více bytů. Počítač byl vybaven prostředky k převodu binárních
na osmičková (šestnáctková) čísla a naopak.
Takto vytvořené programy sice
byly zpravidla rychlé a efektivní, nicméně velkým problémem bylo hledání
chyb a úpravy programů, které byly krajně nepřehledné. Pokud bylo např.
nutno vložit do programu nový úsek, vyvolalo to posun zbytku programu na
jiné adresy v paměti a tím i nutnost opravy všech instrukcí skoku, které
obsahují adresu další vykonávané instrukce. Navíc jeden a tentýž program
měl na různých počítačích vždy různý kód, neboť každý procesor používal
svou vlastní sadu instrukcí, a bylo jej tedy třeba vždy kompletně přepsat.
2.
generace
Programování ve strojovém kódu bylo značně neefektivní a zdlouhavé, pro
větší programy až nevhodné. Proto se brzy začal používat jazyk
symbolických adres neboli Assembler. Odlišnost od
strojového kódu spočívá v užívání symbolických názvů instrukcí, což
přineslo ohromné zpřehlednění programu. Symbolické názvy proměnných a
adresových míst (realizované pomocí návěští – label) zase odbouraly
nutnost opravovat program při každé změně fyzických adres, na nichž je
v paměti umístěn. Skutečné adresy přiřazoval symbolickým až nástroj,
překládající program zapsaný v Assembleru do strojového kódu –
překladač. Vyspělejší verze Assembleru dovolovaly již používání
makroinstrukcí, obsahovaly účinné nástroje pro ladění programu –
debuggery, umožňující např. zastavení programu na daném místě,
výpis proměnných a registrů, krokování programu, atp.. Takto byly tvořeny
programové celky často o velikosti stovek kB.
Přetrvávající nevýhodou ovšem zůstávala strojová závislost jazyka a
obtížnost strukturovaného programování v Assembleru, plynoucí z faktu, že
programátor se namísto celkové koncepce zabýval převážně detaily –
jednotlivými instrukcemi. Ladění rozsáhlých programů bylo proto neobyčejně
zdlouhavé a namáhavé. Programátor té doby musel být také fundovaným
odborníkem na hardware.
Jisté
zjednodušení představovaly Autokódy, rozšíření Assembleru o
symbolické zápisy pro složitější povely (skupiny instrukcí).
Ačkoli se
Assembler dnes již užívá velmi zřídka (např. při tvorbě některých částí
operačního systému, počítačových virů nebo klíčových operací programů, kde
je důležitým parametrem rychlost a efektivita), je přesto žádoucí mít
představu o tom, jakého typu jsou a jak fungují strojové instrukce
procesorů.
3.
generace
Zřejmě
nejvýznamnější změnou bylo v 60. letech 20. století rozšíření
strojově nezávislých programovacích jazyků, podporujících metody
strukturovaného programování. Dochází k rozčlenění programu
do autonomních funkčních celků – modulů. Každý modul obsahuje rozhraní a
tělo. Rozhraní udává, jaké prostředky (datové struktury, proměnné,
operace, atp.) modul nabízí k využití ostatním modulům. Tělo obsahuje
implementační detaily a mělo by ostatním modulům zůstat skryto.
Nejjednodušším modulem je procedura nebo funkce, jejímž rozhraním jsou
její parametry. Procedura by tedy neměla komunikovat se zbytkem programu
jinak než svými parametry.
Vznik
jazyků 3. generace byl umožněn pokroky na poli teorie formálních jazyků.
K většině těchto jazyků existuje přesná norma, takže tentýž program vypadá
stejně na jakémkoliv počítači (tzv. přenositelnost jazyka).
Jeho převedení do strojového kódu zajišťuje překladač. Jde
o specializovaný program sloužící k převodu algoritmu z jednoho jazyka do
druhého.
Prvním
takovýmto programovacím jazykem byl Fortran (Formula
Translation), který vznikl u IBM v roce 1957. Byl orientován především na
matematické výpočty. Inovovaný Fortran se užívá dodnes a největší knihovny
matematických funkcí a metod na středních a velkých počítačích zejména
v USA jsou zřejmě stále napsány v něm.
Následovaly
jazyky Algol (Algorithmic Language), Cobol (Common
Business Oriented Language). Algol 58, vylepšený později do podoby Algol
60 a Algol 68 (podle let publikování), byl prvním univerzálním
programovacím jazykem vhodným pro různé typy úloh. Cobol je určen
především pro zpracování hromadných dat, dodnes se někde používá
v ekonomických aplikacích.
Jazyk PL/1 (Programming Language) z poloviny 60. let byl pokusem o co
nejuniverzálnější programovací jazyk. Zahrnoval širokou sadu příkazů,
množství datových typů, podporu práce s nejrůznějšími perifériemi, bohatě
formátovaný vstup / výstup apod. Později vznikl další univerzální jazyk,
ale poněkud jednodušší, Pascal, jehož autor Niklaus Wirth se
stal klasikem teorie programovacích technik. Pro čistotu, s jakou
prezentuje uvedené principy, se Pascal užívá k výuce i k praktickému
programování dodnes.
Další
jazyky této generace vznikaly za účelem pokrytí speciálnějších požadavků
tvorby programů. Jmenujme například jazyk C se silnou
podporou systémového programování, sdružující prostředky strukturovanosti
se strojově orientovanými prvky umožňujícími vytvořit malé a efektivní
kódy, nebo Ada (pojmenovaná tak na počest hraběnky Ady
Byronové), vytvořená na zakázku Pentagonu ve Francii, podporující tvorbu
programů pracujících v reálném čase a multitasking, s důkladně
propracovanými možnostmi ošetření programových chyb. Na mikropočítačích se
prosadil snadno zvládnutelný Basic s primitivní syntaxí,
jenž je však takřka nepoužitelný pro tvorbu rozsáhlých programů, jelikož
neumožňuje jejich efektivní strukturování.
Postupně se
objevují také programovací jazyky databázové, jako je např. SQL.
31/2.
generace
Takto bývá někdy nazývána rodina objektově
orientovaných programovacích jazyků.
objekt je nějaká skutečnost
(např. konkrétní člověk, konkrétní firma), o níž uchováváme data a
operace pro manipulaci s těmito daty.
třída je kategorie, do níž
daný objekt patří, např. třída všech lidí, třída všech firem.
dědičnost je vztah mezi
nižší a vyšší třídou, při němž třída – potomek převezme rysy od třídy –
rodiče.
polymorfismus – na stejný
podnět reagují objekty různých tříd různě.
zapouzdření znamená zabalení
dat a operací s nimi do jediné obálky tak, že implementační detaily jsou
skryty před uživatelem objektu. S každým typem dat jsou svázány
konkrétní metody, jiným způsobem s daty nelze pracovat.
Existuje množství OOP jazyků. Někteří považují jazyk
Simula67 za vůbec první z nich, nicméně Smalltalk
byl první jazyk, který zavedl úplnou implementaci pojmu OOP. Potom přišly
hybridní jazyky (tedy OOP jazyky založené na původních jazycích), jako
například C++, Objective-C, CLOS
(derivace LISPu) a Object Pascal. Mezi další důležité patří
Eiffel a Sather. Ale rychle se objevují nové
OOP jazyky, v nedávné době to byl jazyk Java.
Pro rozdělení OOP jazyků do skupin můžeme použít dvě
klíčové kategorie:
Čisté versus hybridní: čisté
OOP jazyky jsou jazyky, které nepřipouštějí jiné programovací modely.
Funkci nemůžeme napsat samostatně, pokud není součástí třídy. Nemůžeme
deklarovat globální proměnnou. Příklady čistých jayků jsou Smalltalk a
Eiffel. S hybridními jazyky můžeme dělat cokoli chceme včetně úplného
vypuštění OOP principů. Příklady hybridních jazyků jsou všechny ty, které
jsou kompatibilní s již existujícími, jako například C++ nebo Object
Pascal.
Statické versus dynamické:
statické jazyky jsou založeny na znalosti datového typu a provádějí četné
typové kontroly v době překladu. Dynamické jazyky mají slabší znalost typu
a provádějí většinu kontroly za běhu. Dynamické jazyky, jako Smalltalk,
jsou obvykle interpretovány. Statické jazyky, jako Object Pascal, jsou
vždy kompilovány.
4. generace
V 80. letech se začaly objevovat prostředky (spíše než
jazyky), které místo vypisování jednotlivých příkazů dovolují komunikovat
s počítačem pomocí obrázkových prostředků – nabídek, dialogů, obrázků,
ikon označující data nebo programy, které je možné pomocí myši přesouvat,
kopírovat, označovat a podobně.
Velmi často toto prostředí 4. generace pak generuje nějaký
kód jazyka 3. generace, který pomocí příkazů popisuje názorně
specifikované akce. Uživatel tohoto prostředí tedy vůbec nemusí umět
programovat, pouze interaktivně vytváří požadovaný výsledek co možná
vizualizovaným způsobem. Typickým je princip WYSIWYG (What You See
Is What You Get).
Z nejdostupnějších prostředků můžeme jmenovat např.
databáze Paradox nebo Visual Foxpro nebo různá
prostředí pro vytváření grafických informačních WWW stránek na Internetu,
jež jsou popsány příkazy jazyka HTML (Hypertext Markup
Language). Jde o jazyk, jež umožnuje animovat hypertextové dokumenty
umístěné vesměs na serverech, řídit způsob jejich zobrazování na
klientském počítači, vkládat do nich obrázky. S pomocí jazyku Php
je možno pak pracovat s databázemi nebo jinými dokumenty.
5.
generace
V předchozí generaci musí
programátor, byt’ maximálně jednoduchým a názorným způsobem, specifikovat
posloupnost akcí, které mají být provedeny, aby se dosáhlo požadovaného
výsledku. Naproti tom prostředky 5. generace nabízejí nalezení postupu
vedoucího k požadovanému cíli samotným počítačem. Jedná se o
neprocedurální programování. Programátor v podstatě pomocí jazyka
nadefinuje objekty, pravidla a omezení a popíše kritéria, kterým musí
vyhovovat řešení. Počítač pak může sám hledat nejvhodnější způsob dosažení
řešení. Jedním z klíčových pojmů neprocedurálního programování bývá
rekurze, která umožňuje názorně vyjádřit závislosti jednotlivých výsledků,
ale klade často vysoké nároky na kapacitu paměti počítače.
Tato generace je třeba
reprezentována logickým programováním a jazykem Prolog,
který je založený na predikátové logice I. řádu. Veškeré příkazy v Prologu
mají formu takzvaných klauzulí, což jsou prakticky logické
implikace, nebo formu platných faktů. Pokud existuje řešení vyhovující
námi zadanému systému klauzulí, Prolog je nalezne. S větší obtížností
roste i doba řešení problému.
Jinou variantou je
funkcionální programování, jehož přestavitelem je Lisp,
vycházejí z faktu, že jakýkoli počítačový program lze popsat pomocí
rekurzivní funkce. Základním prvkem programu v Lispu je tedy funkce.
Ohromnou výhodou logického a
funkcionálního programování před jazyky 3. generace je vysoká míra
abstrakce a inteligentní koncepce prostředí jazyka. Proto jsme osvobozeni
řešit implementační detaily (alokace paměti, deklarace proměnných a typů
atp.).
Největším omezením širšího
rozšíření prostředků 5. generace je jejich značná výpočetní náročnost. Ta
je i příčinou zpoždění nástupu počítačů, které měli jazyky 5. generace
podporovat již na strojové úrovni.