Programovací jazyk je prostředek k vyjadřování postupů (algoritmů, programů) způsobem, aby daný postup byl v konečném důsledku proveditelný počítačem. Programovací jazyk je tedy takovým mostem mezi člověkem a počítačem. Programovací jazyk tedy musí být srozumitelný jak člověku, tak počítači.
Ve své podstatě má programovací jazyk mnoho společného s lidskými jazyky, jako je třeba čeština či angličtina. Z toho také vychází název "jazyk". Mezi lidským jazykem a programovacím jazykem je ovšem i několik podstatných rozdílů:
Souboru pravidel, které jazyk určují říkáme syntaxe jazyka. Syntaxí tedy rozumíme množinu pravidel, které odlišují platný výraz v daném jazyce od neplatného. Kdybychom mluvili o češtině, pak bychom mohli říct, že výraz "kočka mezi dělat zelený" neodpovídá syntaxi českého jazyka. Pojem syntaxe je pro programátora důležitý zejména v momentu, kdy jí (typicky omylem) poruší. V tu chvíli totiž daný výraz nedává počítači smysl a počítač odpoví chybovou hláškou o chybě syntaxe (anglicky syntax error). Ta znamená, že program, který jsme napsali, prostě obsahuje nějakou chybu, která je pro počítač nepřekonatelná.
Někdy mluvíme také o sémantice jazyka. Sémantika a syntaxe spolu úzce souvisejí. Zatímco v případě syntaxe mluvíme o tom, která jazyková konstrukce je či není smysluplná, sémantika určuje význam. Například v české větě "kočka leze dírou" říká syntaxe, že je to smysluplná věta, sémantika říká, co ta věta skutečně znamená. Tedy, že je tam nějaká kočka, která dělá to, že leze nějakým otvorem.
Výraz, který odpovídá nějakému programovacímu jazyku, tj. splňuje syntaxi nějakého programovacího jazyka, nazýváme kód (anglicky code).
Jak už jsme řekli, adresátem kódu je počítač. Počítač sám o sobě ovšem žádnému programovacímu jazyku nerozumí. Jedinému jazyku, kterému počítač opravdu nativně rozumí, je takzvaný binární strojový kód, který se ještě liší procesor od procesoru (tj. každý procesor má úplně jiný binární strojový kód). Na jednu stranu by bylo možné i binární strojový kód považovat za programovací jazyk, byl by to ale jazyk, ve kterém by bylo velmi obtížné programovat, a tak není vůbec potřeba se o to pokoušet. Je to totiž zbytečné, existují lepší a efektivnější metody.
Aby tedy počítač mohl rozumět nějakému programovacímu jazyku, je potřeba nějaký program, který danému programovacímu jazyku rozumí a umí s ním pracovat. Takový program může s kódem napsaným v nějakém programovacím jazyku udělat dvě věci:
I celý programovací jazyk bývá buď kompilovaný nebo interpretovaný. To znamená, že k němu existuje buď kompilátor nebo interpreter, málokdy však obojí dohromady. A i kdyby snad k nějakému programovacímu jazyku existovaly jak kompilátor tak interpreter, bude jeden z nich pouze nástavbou na tom druhém. Až na některé velmi specifické výjimky tedy můžeme programovací jazyky rozdělit na buď kompilované nebo interpretované.
Je nutné také poznamenat, že mezi kompilovanými a interpretovanými jazyky není zas tak propastný rozdíl, jak to na první pohled vypadá. Všechny dnešní moderní interpretované programovací jazyky totiž interně stejně provádějí proces kompilace, pouze je tento skryt a probíhá neviditelně na pozadí. Kompiluje se potom do speciálního binárního strojového kódu, který se nazývá bajtkód (anglicky bytecode), který neodpovídá přímo žádnému procesoru, ale bajtkód je pak sám o sobě interpretován. Výhodou tohoto postupu je, že naprogramovat interpreter bajtkódu je mnohem snažší, než naprogramovat interpreter programovacího jazyka jako celku. Zpravidla lze tímto způsobem dosáhnout významného zrychlení a tak interpretované jazyky jsou dnes jen o málo pomalejší než jazyky kompilované. Přesto ale platí, že s kompilovanými jazyky lze dosáhnout rychlejších výsledků, než s jazyky interpretovanými.
Operační systém typicky poskytuje programu jeden jediný blok paměti, jehož délka se může měnit. Je potom záležitostí samotného programu, jak bude s tímto blokem paměti hospodařit. Jednou z nejdůležitějších dovedností programu je proto způsob, jakým program přiděluje paměť jednotlivým datovým strukturám. Protože otázka přidělování paměti datovým strukturám je zcela zásadní, bývá nějakým způsobem podporována už samotným programovacím jazykem.
V zásadě proto můžeme programovací jazyky rozdělit na dvě kategorie:
programovací jazyky s explicitním alokováním - Při tomto přístupu, potřebuje-li program paměť pro nějakou datovou strukturu, požádá systémový alokátor paměti, aby mu nějakou přidělil. Ve chvíli, kdy paměť již není potřeba, řekne program systémovému alokátoru, že paměť může být uvolněna k jiným účelům. Tento přístup je jednodušší pro programovací jazyk samotný, zato je těžší pro programátora. Programátor musí vždy uvažovat o tom, kdy už daná datová struktura není potřebná. V případě, že programátor zapomene uvolnit paměť po už nepotřebné datové struktuře, zůstává tato v paměti na věky. Mluvíme pak o tzv. memory leaku. Obsahuje-li program chyby typu memory leak, roste paměť využívaná programem s délkou běhu programu. Čím déle program běží, tím více paměti potřebuje k běhu. Odstranit memory leak lze pouze restartem celého programu. Jedná se proto o velmi nepříjemnou chybu, zejména u programů, u kterých se předpokládá dlouhý běh, např. webový server.
programovací jazyky s garbage collectorem - Při tomto přístupu dochází k alokaci i uvolnění paměti automaticky. K alokaci paměti pro danou datovou strukturu dojde automaticky při jejím vytvoření, paměť je uvolněna taktéž automaticky ve chvíli, kdy struktura přestává být potřebnou, což je ve chvíli, kdy se na datovou strukturu žádné místo v programu neodkazuje. O uvolňování paměti se stará takzvaný garbage collector, tedy "sběrač smetí". Tento přístup je velmi pohodlný pro programátory, protože programátorovi odpadá nutnost starat se o přidělování (alokaci) paměti. Na druhou stranu, implementace smysluplného garbage collectoru je složitá záležitost a bylo na toto téma napsáno velké množství odborné literatury. Garbage collector se většinou implementuje u programovacích jazyků objektově orientovaného paradigmatu
Assembler je programovací jazyk, který má velmi blízko k binárnímu strojovému kódu. Assembler tak vlastně není jeden programovací jazyk, ale celá škála programovacích jazyků, pro každý druh procesoru jeden. Assembler, stejně jako binární strojový kód, pracuje přímo s instrukcemi daného procesoru. (pod pojmem instrukce si lze představit jednu konkrétní operaci, kterou má procesor provést, například přičíst 1 k nějaké paměťové buňce). Zatímco v binárním strojovém kódu je instrukce reprezentovaná binárně (pomocí jedniček a nul), v assembleru je instrukce reprezentovaná slovním výrazem čitelným pro člověka. Smyslem assembleru je tedy odstínit programátora od binární reprezentace jednotlivých instrukcí, protože tato binární reprezentace je velmi těžko zapamatovatelná a člověku se s ní proto velmi špatně pracuje.
Assembler tak byl vlastně prvním skutečným programovacím jazykem. Assembler je typickým příkladem kompilovaného jazyka čistě imperativního paradigmatu.
Assembler se sám o sobě nestará o přidělování paměti, lze ale využívat explicitní alokaci pomocí předdefinované funkcionality.
Příklad programu v jazyce Assembler:
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov eax, 1
int 0x80
section .data
msg db 'Hello, world!', 0xa
len equ $ - msg
Jazyk C vznikl jako pokus o jakýsi univerzálnější assembler. Když začal být počet různých variant procesorů neúnosně velký, začali programátoři přemýšlet nad tím, jak psát programy takovým způsobem, aby se nemusely psát pro každý druh procesoru znovu (neboť, jak už jsme říkali, assembler se liší procesor od procesoru, v assembleru tedy není možné jednoduše přenést kód na jiný procesor). Jedním z velmi úspěšných pokusů, jak tohoto cíle dosáhnout, je právě jazyk C. Jazyk C v sobě navíc integruje prvky strukturovaného programování. Vznikl tak počin, který inspiruje programátory do dnešních dob. Mnoho pozdějších programovacích jazyků v sobě nese prvky jazyka C.
Jazyk C je tedy představitelem kompilovaného jazyka strukturovaného paradigmatu.
Jazyk C taktéž sám o sobě neobsahuje prvky správy paměti, explicitní alokace je ale implementována jako standardní knihovní funkce (tj. explicitní alokaci mohou všechny programy využívat pomocí již předprogramované funkcionality).
Příklad programu v jazyce C:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
}
Jazyk Pascal vznikl původně jako jazyk vhodný pro výuku programování. Vznikl zhruba ve stejné době, jako jazyk C (asi o dva roky dříve) a podobně jako jazyk C integruje prvky strukturovaného programování. Filozofie jazyka Pascal je vlastně velmi podobná filozofii jazyku C, kromě toho, že klade větší důraz na výukové aspekty. To z něj ovšem dělá pro praxi mnohem hůře použitelný jazyk, než je jazyk C.
V dnešní době lze jazyk Pascal považovat za v podstatě překonaný. I pro samotnou výuku programování existují vhodnější programovací jazyky.
Pascal je stejně jako C představitelem kompilovaného jazyka strukturovaného paradigmatu.
Jazyk Pascal implementuje správu paměti pomocí explicitní alokace.
Příklad programu v jazyce Pascal:
program Hello_world;
begin
writeln("Hello, world!")
end.
Jazyk C++, jak už jeho název napovídá, je rozšířením jazyka C. C++ v zásadě nemění základní principy jazyka, přidává ovšem prvky objektového paradigmatu. Tím se stal mezi mnohými programátory vcelku oblíbenou možností (protože objektově orientované programování je velmi silný nástroj). Na druhou stranu, u jiné skupiny programátorů budí jazyk C++ rozpaky. Ti považují integraci OOP přístupu za nepovedenou.
C++ je kompilovaný jazyk s kombinací strukturovaného a objektového paradigmatu.
Jazyk C++ implementuje správu paměti pomocí explicitní alokace.
Příklad programu v jazyce C++:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, World!" << endl;
return 0;
}
Java je programovací jazyk čistě objektového paradigmatu, který je svojí syntaxí velmi inspirován jazykem C++. Ve své podstatě jde o takové "pročištění" syntaxe C++, aby odstranila ty prvky jazyka, které nejsou úplně kompatibilní s objektovým paradigmatem.
Jazyk Java lze chápat na pomezí mezi kompilovaným a interpretovaným jazykem. Programy v jazyce Java je sice potřeba ručně kompilovat (jako u kompilovaných jazyků), kompilují se ale do bajtkódu, který je interpretován příslušným interpreterem. Oproti klasickým interpretovaným jazykům tedy v Javě chybí vrstva, která by zajišťovala automatickou kompilaci.
Java spravuje paměť pomocí garbage collectoru.
Příklad programu v jazyce Java:
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, World");
}
}
Python je moderní programovací jazyk vyššího typu, který je pro některé své vlastnosti vhodný i pro výuku, ale i pro produkční programování.
Python je interpretovaný jazyk nabízející celou škálu paradigmatických přístupů od strukturovaného programování přes objektově orientované programování po prvky funkcionálního programování.
Jazyk Python implementuje správu paměti pomocí garbage collectoru.
Příklad kódu v jazyce Python:
print "Hello, World!"
PHP je jazyk, který byl primárně vyvinut pro vývoj webových aplikací. PHP si prošel dlouhým vývojem, kdy v první verzi se jednalo o jazyk čistě strukturovaného paradigmatu, zatímco v pozdějších verzích byly implementovány i prvky objektového paradigmatu.
Zejména kvůli svým starším verzím, které byly opravdu děsivé, je jazyk PHP stále mnohými programátory odmítán. Nutné je ale poznamenat, že v dnešní době se jedná o dospělý jazyk vhodný i pro produkční prostředí. Například celý facebook je napsán v jazyce PHP.
PHP je interpretovaný jazyk kombinující různé paradigmatické přístupy.
Jazyk PHP implementuje správu paměti pomocí garbage collectoru.
Příklad programu v jazyce PHP:
<?php
echo "Hello, World!\n";
?>
JavaScript je jazyk, který se stal standardem jako klientský jazyk webových aplikací. Běží tedy přímo ve vašem prohlížeči, zatímco si prohlížíte online webové aplikace. V poslední době začíná být ovšem oblíben i jako jazyk pro psaní serverových webových aplikací. K tomu slouží například slouží framework zvaný node.js.
JavaScript je interpretovaný jazyk, implementuje správu paměti pomocí garbage collectoru.
Příklad programu v jazyce JavaScript:
alert("Hello, World");