Počítačové programovací jazyky

Programovací jazyk je umělý jazyk, který lze použít k řízení chování stroje, zejména počítače. Programovací jazyky, stejně jako přirozené jazyky, jsou definovány syntaktickými a sémantickými pravidly, která popisují jejich strukturu a význam. Mnoho programovacích jazyků má nějakou formu písemného určení jejich syntaxe a sémantiky; některé jsou definovány pouze oficiální implementací.

Programovací jazyky se používají k usnadnění komunikace o úkolu organizování a manipulace s informacemi a k přesnému vyjádření algoritmů. Někteří autoři omezují termín „programovací jazyk“ na jazyky, které mohou vyjádřit všechny možné algoritmy; někdy se termín „počítačový jazyk“ používá pro omezenější umělé jazyky.

Tisíce různých programovacích jazyků byly vytvořeny a nové jazyky jsou vytvářeny každý rok.

Vlastnosti často považované za důležité pro vytvoření programovacího jazyka:

Nepočítačové jazyky, například značkovací jazyky jako HTML nebo formální gramatiky jako BNF, obvykle nejsou považovány za programovací jazyky. Často je programovací jazyk vložen do nepočítačového (hostitelského) jazyka.

Významným účelem programovacích jazyků je poskytování instrukcí počítači. Jako takové se programovací jazyky liší od většiny ostatních forem lidského vyjadřování tím, že vyžadují větší míru přesnosti a úplnosti. Při používání přirozeného jazyka pro komunikaci s ostatními lidmi mohou být lidští autoři a mluvčí nejednoznační a mohou se dopouštět drobných chyb a stále očekávat, že jejich záměr bude pochopen. Počítače však dělají přesně to, co se jim řekne, a nemohou rozumět kódu, který programátor „zamýšlel“ napsat. Kombinace definice jazyka, programu a vstupů programu musí plně specifikovat vnější chování, které nastane při spuštění programu.

Mnoho jazyků bylo navrženo od základů, upraveno tak, aby odpovídaly novým potřebám, kombinováno s jinými jazyky, a nakonec se přestaly používat. Přestože se objevily pokusy navrhnout jeden „univerzální“ počítačový jazyk, který by sloužil všem účelům, všechny se nepodařilo v této roli přijmout. Potřeba rozmanitých počítačových jazyků vyplývá z rozmanitosti kontextů, v nichž jsou jazyky používány:

Jedním z běžných trendů ve vývoji programovacích jazyků bylo přidávání větší schopnosti řešit problémy pomocí vyšší úrovně abstrakce. Nejstarší programovací jazyky byly velmi úzce svázány se základním hardwarem počítače. Jak se vyvíjely nové programovací jazyky, byly přidány funkce, které programátorům umožňují vyjádřit myšlenky, které jsou více vzdáleny jednoduchému překladu do základních hardwarových instrukcí. Protože programátoři jsou méně svázáni s potřebami počítače, jejich programy mohou dělat více výpočetní techniky s menší námahou programátora. To jim umožňuje napsat více programů za stejné množství času.

Procesory přirozeného jazyka byly navrženy jako způsob, jak eliminovat potřebu specializovaného jazyka pro programování. Tento cíl však zůstává vzdálený a jeho výhody jsou otevřené diskusi. Edsger Dijkstra zastával názor, že použití formálního jazyka je nezbytné, aby se zabránilo zavádění nesmyslných konstruktů, a zavrhl programování přirozeného jazyka jako „pošetilé“. Podobně odmítavě se k této myšlence vyjádřil i Alan Perlis.

Rozborový strom kódu Pythonu s vloženou tokenizací

Povrchová forma programovacího jazyka je známá jako jeho syntaxe. Většina programovacích jazyků je čistě textová; používají posloupnosti textu včetně slov, čísel a interpunkce, podobně jako psané přirozené jazyky. Na druhé straně existují některé programovací jazyky, které jsou více grafické povahy a používají prostorové vztahy mezi symboly k upřesnění programu.

Syntaxe jazyka popisuje možné kombinace symbolů, které tvoří syntakticky správný program. Význam daný kombinaci symbolů je řešen pomocí sémantiky. Vzhledem k tomu, že většina jazyků je textová, pojednává tento článek o textové syntaxi.

Syntaxe programovacího jazyka je obvykle definována pomocí kombinace regulárních výrazů (pro lexikální strukturu) a Backus-Naur formuláře (pro gramatickou strukturu). Níže je jednoduchá gramatika, založená na Lispu:

Tato gramatika specifikuje následující:

Níže jsou uvedeny příklady dobře tvarovaných tokenových posloupností v této gramatice: ‚12345‘, ‚()‘, ‚(a b c232 (1))‘

Ne všechny syntakticky korektní programy jsou sémanticky korektní. Mnoho syntakticky korektních programů je nicméně špatně vytvořených, podle pravidel jazyka; a mohou (v závislosti na specifikaci jazyka a spolehlivosti implementace) vyústit v chybu při překladu nebo provedení. V některých případech mohou takové programy vykazovat nedefinované chování. I když je program dobře definován v rámci jazyka, může mít stále význam, který není zamýšlen osobou, která ho napsala.

Při použití přirozeného jazyka jako příkladu nemusí být možné přiřadit gramaticky správné větě význam nebo věta může být nepravdivá:

Doporučujeme:  Antibiotika

Následující fragment jazyka C je syntakticky správný, ale provádí operaci, která není sémanticky definovaná (protože p je nulový ukazatel, operace p->real a p->im nemají žádný význam):

Gramatika potřebná k určení programovacího jazyka může být klasifikována podle jeho pozice v Chomského hierarchii. Syntaxe většiny programovacích jazyků může být specifikována pomocí gramatiky typu 2, tj. jde o bezkontextové gramatiky.

Typový systém definuje, jak programovací jazyk třídí hodnoty a výrazy do typů, jak může s těmito typy manipulovat a jak na sebe vzájemně působí. To zpravidla zahrnuje popis datových struktur, které lze v jazyce zkonstruovat. Návrh a studium typových systémů pomocí formální matematiky je známo jako typová teorie.

Interně jsou všechna data v moderních digitálních počítačích uložena jednoduše jako nuly nebo jedničky (binárně).

Typované versus netypované jazyky

Jazyk je napsán, pokud operace definované pro jeden datový typ nemohou být provedeny na hodnotách jiného datového typu. Například „tento text mezi uvozovkami“ je řetězec. Ve většině programovacích jazyků nemá dělení čísla řetězcem žádný význam. Většina moderních programovacích jazyků proto odmítne jakýkoli program, který se pokusí provést takovou operaci. V některých jazycích bude nesmyslná operace detekována při kompilaci programu („statická“ kontrola typu) a odmítnuta kompilátorem, zatímco v jiných bude detekována při spuštění programu („dynamická“ kontrola typu), což vyústí v runtime výjimku.

Zvláštním případem typovaných jazyků jsou jednotypové jazyky. Často se jedná o skriptovací nebo značkovací jazyky, jako je Rexx nebo SGML, a mají pouze jeden datový typ – nejčastěji znakové řetězce, které se používají pro symbolická i numerická data.

Naopak netypovaný jazyk, jako je většina assemblerových jazyků, umožňuje provádět libovolné operace s jakýmikoli daty, které jsou obecně považovány za posloupnosti bitů různých délek. Vysokoúrovňové jazyky, které jsou netypované, zahrnují BCPL a některé varianty Forth.

V praxi platí, že zatímco z hlediska typové teorie se za typově typové považuje jen málo jazyků (ověřování nebo odmítání všech operací), většina moderních jazyků nabízí určitý stupeň typování. Mnoho výrobních jazyků poskytuje prostředky k obcházení nebo podvracení typového systému.

Statické versus dynamické psaní

Při statickém psaní mají všechny výrazy svůj typ určený před spuštěním programu (typicky při kompilaci). Například 1 a (2+2) jsou celočíselné výrazy; nemohou být předány funkci, která očekává řetězec, nebo uloženy v proměnné, která je definována tak, aby obsahovala data.

Staticky typované jazyky mohou být manifestně typované nebo typově odvozené. V prvním případě musí programátor explicitně psát typy na určitých textových pozicích (například při deklaracích proměnných). Ve druhém případě kompilátor odvozuje typy výrazů a deklarací na základě kontextu. Většina mainstreamových staticky typovaných jazyků, jako je C++ a Java, je manifestně typovaná. Kompletní typová inference byla tradičně spojována s méně mainstreamovými jazyky, jako je Haskell a ML. Nicméně mnoho manifestně typovaných jazyků podporuje částečnou typovou inferenci; například Java a C# oba typy odvozují v určitých omezených případech.
Dynamické typování, také nazývané latentní typování, určuje typovou bezpečnost operací za běhu; jinými slovy, typy jsou spojovány spíše s hodnotami za běhu než s textovými výrazy. Stejně jako u typově odvozených jazyků, dynamicky typované jazyky nevyžadují, aby programátor psal explicitní typové anotace na výrazy. Mimo jiné to může umožnit, aby jedna proměnná odkazovala na hodnoty různých typů v různých bodech provádění programu. Typové chyby však nemohou být automaticky detekovány, dokud není kus kódu skutečně spuštěn, což znesnadňuje ladění. Ruby, Lisp, JavaScript a Python jsou dynamicky typovány.

Slabé psaní umožňuje, aby se s hodnotou jednoho typu zacházelo jako s jinou, například aby se s řetězcem zacházelo jako s číslem. To může být občas užitečné, ale také to může umožnit, aby některé druhy programových chyb zůstaly v době kompilace neodhaleny.

Silné psaní zabraňuje výše uvedenému. Pokus o míchání typů vyvolává chybu. Silně typované jazyky jsou často označovány jako typově bezpečné nebo bezpečné. Typová bezpečnost může zabránit výskytu určitých typů chyb programů (protože konstrukty, které je obsahují, jsou v době kompilace označeny příznakem).

Alternativní definice pro „slabě typovaný“ odkazuje na jazyky, jako je Perl, JavaScript a C++, které umožňují velké množství implicitních typových konverzí; Perl může být charakterizován jako dynamicky typovaný programovací jazyk, ve kterém může probíhat typová kontrola za běhu. Viz typový systém. Tato schopnost je často užitečná, ale občas nebezpečná; protože by umožňovala operace, jejichž objekty mohou měnit typ na požádání.

Doporučujeme:  Interpersonální chemie

Silné a statické jsou obecně považovány za ortogonální pojmy, ale použití v literatuře se liší. Někteří používají termín silně typovaný tak, aby znamenal silně, staticky typovaný, nebo, ještě více matoucím způsobem, aby znamenal jednoduše staticky typovaný. Proto bylo C nazýváno jak silně typovaným, tak slabě, staticky typovaným.

Po zadání dat musí být stroj instruován, aby prováděl operace s daty. Sémantika provádění jazyka definuje, jak a kdy by různé konstrukce jazyka měly produkovat chování programu.

Sémantika může například definovat strategii, podle které jsou výrazy vyhodnocovány na hodnoty, nebo způsob, jakým řídicí struktury podmínečně provádějí příkazy.

Většina programovacích jazyků má přidruženou základní knihovnu (někdy známou jako ‚Standardní knihovna‘, zejména pokud je zahrnuta jako součást publikovaného jazykového standardu), která je konvenčně zpřístupněna všemi implementacemi jazyka. Základní knihovny obvykle zahrnují definice pro běžně používané algoritmy, datové struktury a mechanismy pro vstup a výstup.

Jádrová knihovna jazyka je uživateli často považována za součást jazyka, i když designéři ji mohli považovat za samostatnou entitu. Mnoho jazykových specifikací definuje jádro, které musí být zpřístupněno ve všech implementacích, a v případě standardizovaných jazyků může být tato jádrová knihovna vyžadována. Linie mezi jazykem a jeho jádrovou knihovnou se proto liší jazyk od jazyka. Některé jazyky jsou totiž navrženy tak, že významy některých syntaktických konstruktů nelze ani popsat bez odkazu na jádrovou knihovnu. Například v Javě je řetězcový literál definován jako instance třídy java.lang.String; podobně ve Smalltalku anonymní funkční výraz („blok“) konstruuje instanci knihovní třídy BlockContext. Naopak Scheme obsahuje více koherentních podmnožin, které stačí k tomu, aby zbytek jazyka byl zkonstruován jako knihovní makra, a tak se návrháři jazyků ani neobtěžují říci, které části jazyka musí být implementovány jako jazykové konstrukce a které musí být implementovány jako součásti knihovny.

Tvůrci a uživatelé jazyka musí zkonstruovat množství artefaktů, které řídí a umožňují praxi programování. Nejdůležitější z těchto artefaktů jsou specifikace a implementace jazyka.

Specifikace programovacího jazyka může mít několik podob, včetně následujících:

Implementace programovacího jazyka poskytuje způsob provedení tohoto programu na jedné nebo více konfiguracích hardwaru a softwaru. Existují obecně dva přístupy k implementaci programovacího jazyka: kompilace a interpretace. Obecně je možné implementovat jazyk pomocí kterékoli z těchto technik.

Programy, které jsou spouštěny přímo na hardwaru, obvykle běží o několik řádů rychleji než ty, které jsou interpretovány v softwaru.

Jednou z technik pro zlepšení výkonu interpretovaných programů je just-in-time kompilace. Zde virtuální stroj sleduje, které sekvence bajtkódu jsou často prováděny a překládá je do strojového kódu pro přímé provedení na hardwaru.

Výběr učebnic, které učí programování, v jazycích populárních i obskurních. To je jen několik z tisíců programovacích jazyků a dialektů, které byly navrženy v historii.

První programovací jazyky předcházely modernímu počítači. 19. století mělo „programovatelné“ stavy a svitky hráčských klavírů, které implementovaly to, co je dnes uznáváno jako příklady programovacích jazyků specifických pro domény. Počátkem dvacátého století děrné štítky kódovaly data a řídily mechanické zpracování. Ve třicátých a čtyřicátých letech formalismus lambda kalkulu Alonza Churche a Turingovy stroje poskytly matematické abstrakce pro vyjádření algoritmů; lambda kalkul zůstává vlivný v designu jazyků.

Každý z těchto jazyků zplodil celou rodinu potomků a většina moderních jazyků počítá alespoň jednoho z nich ve svém původu.

V šedesátých a sedmdesátých letech se také vedla značná debata o přednostech strukturovaného programování a o tom, zda by programovací jazyky měly být navrženy tak, aby jej podporovaly. Edsger Dijkstra ve slavném dopise z roku 1968 zveřejněném v Komunikacích ACM argumentoval, že příkazy GOTO by měly být odstraněny ze všech programovacích jazyků „vyšší úrovně“.

V šedesátých a sedmdesátých letech došlo také k rozšíření technik, které snížily stopu programu a také zlepšily produktivitu programátora a uživatele. Kartový balíček pro rané 4GL byl mnohem menší pro stejnou funkčnost vyjádřenou v 3GL balíčku.

Doporučujeme:  Odborné konzultace

Osmdesátá léta byla roky relativní konsolidace. C++ kombinovalo objektově orientované a systémové programování. Vláda Spojených států standardizovala Ada, programovací jazyk systémů určený pro použití dodavateli v oblasti obrany. V Japonsku i jinde se utrácely obrovské částky za zkoumání takzvaných „pátých generací“ jazyků, které obsahovaly logické programovací konstrukce. Komunita funkčních jazyků se přesunula ke standardizaci ML a Lisp. Spíše než vymýšlení nových paradigmat, všechna tato hnutí rozpracovávala myšlenky vynalezené v předchozím desetiletí.

Důležitým trendem v designu jazyků v 80. letech bylo větší zaměření na programování rozsáhlých systémů pomocí modulů nebo rozsáhlých organizačních jednotek kódu. Modula-2, Ada a ML vyvinuly v 80. letech pozoruhodné modulové systémy, i když jiné jazyky, jako například PL/I, již měly rozsáhlou podporu modulárního programování. Modulové systémy se často zaklínaly do generických programovacích konstruktů.

Rychlý růst internetu v polovině 90. let vytvořil příležitosti pro nové jazyky. Perl, původně skriptovací nástroj Unixu, který byl poprvé vydán v roce 1987, se stal běžným na dynamických webových stránkách. Java se začala používat pro programování na straně serveru. Tyto vývojové trendy nebyly zásadně nové, spíše šlo o vylepšení stávajících jazyků a paradigmat a byly z velké části založeny na rodině programovacích jazyků C.

Vývoj programovacího jazyka pokračuje, a to jak v průmyslu, tak ve výzkumu. Současné směry zahrnují ověřování bezpečnosti a spolehlivosti, nové druhy modularity (mixiny, delegáty, aspekty) a integraci databází. [Jak odkazovat a odkazovat na shrnutí nebo text]

4GL jsou příklady jazyků, které jsou doménově specifické, jako například SQL, který manipuluje a vrací sady dat spíše než skalární hodnoty, které jsou pro většinu programovacích jazyků kanonické. Například Perl se svým ‚here document‘ může držet více 4GL programů, stejně jako více JavaScript programů, v části vlastního perl kódu a používat proměnnou interpolaci v ‚here document‘ pro podporu vícejazyčného programování.

Je obtížné určit, které programovací jazyky jsou nejrozšířenější a co použití znamená, se liší podle kontextu. Jeden jazyk může zabírat větší počet programátorských hodin, jiný má více řádků kódu a třetí využívá nejvíce času procesoru. Některé jazyky jsou velmi populární pro konkrétní druhy aplikací. Například COBOL je stále silný v korporátním datovém centru, často na velkých sálových počítačích; FORTRAN v inženýrských aplikacích; C v embedded aplikacích a operačních systémech; a další jazyky jsou pravidelně používány pro psaní mnoha různých druhů aplikací.

Byly navrženy různé metody měření popularity jazyka, z nichž každý podléhá jinému zkreslení toho, co se měří:

Pro programovací jazyky neexistuje žádné zastřešující schéma klasifikace. Daný programovací jazyk obvykle nemá jediný jazyk předků. Jazyky obvykle vznikají spojením prvků několika předchůdců jazyků s novými myšlenkami, které jsou v té době v oběhu. Myšlenky, které mají původ v jednom jazyce, se rozptýlí v rodině příbuzných jazyků a pak náhle přeskočí rodinné mezery, aby se objevily ve zcela jiné rodině.

Úkol je dále komplikován skutečností, že jazyky mohou být klasifikovány podle více os. Například Java je jak objektově orientovaný jazyk (protože podporuje objektově orientovanou organizaci), tak souběžný jazyk (protože obsahuje vestavěné konstrukce pro paralelní běh více vláken). Python je objektově orientovaný skriptovací jazyk.

V hrubých rysech se programovací jazyky dělí na programovací paradigmata a klasifikaci podle zamýšlené oblasti použití. Paradigmata zahrnují procedurální programování, objektově orientované programování, funkční programování a logické programování; některé jazyky jsou hybridy paradigmat nebo multi-paradigmatické. Jazyk sestavení není ani tak paradigma jako přímý model základní strojové architektury. Podle účelu by programovací jazyky mohly být považovány za obecný účel, systémové programovací jazyky, skriptovací jazyky, doménově specifické jazyky nebo souběžné/distribuované jazyky (nebo jejich kombinace). Některé jazyky obecného účelu byly navrženy převážně se vzdělávacími cíli.

Programovací jazyk může být také klasifikován podle faktorů nesouvisejících s programovacím paradigmatem. Například většina programovacích jazyků používá klíčová slova v anglickém jazyce, zatímco menšina nikoli. Ostatní jazyky mohou být klasifikovány jako ezoterické nebo ne.