Erlang | |
---|---|
Sémantika | multiparadigma : paralelní , funkční programování |
Jazyková třída | multiparadigmatický programovací jazyk , paralelní programovací jazyk [d] , funkcionální programovací jazyk , deklarativní programovací jazyk , programovací jazyk , open source software , svobodný software a dovednosti |
Objevil se v | 1986 [2] |
Autor | Joe Armstrong |
Vývojář | Joe Armstrong , Ericsson a Robert Virding [d] |
Přípona souboru | .erl |
Uvolnění | |
Typový systém | silný , dynamický |
Byl ovlivněn | ML , Prolog , Lisp , PLEX [d] , Smalltalk , Miranda , Ada , Modula-2 a CHILL |
Licence | Licence Apache 2.0 [3] |
webová stránka | erlang.org _ |
OS | multiplatformní [4] |
Mediální soubory na Wikimedia Commons |
Erlang [ ˈɜːlæŋ ] [5] je funkcionální programovací jazyk se silným dynamickým typováním , určený k vytváření distribuovaných počítačových systémů . Vyvinuto a udržováno společností Ericsson . Jazyk zahrnuje prostředky pro generování paralelních odlehčených procesů a jejich interakci prostřednictvím výměny asynchronních zpráv v souladu s modelem aktéra .
Erlang byl cíleně navržen pro použití v distribuovaných, chybově odolných , paralelních real-time systémech , pro které kromě samotného jazyka existuje standardní knihovna modulů a knihovna šablonových řešení (tj. -zvané chování) - rámec OTP ( Eng. Open Telecom Platform ) . Program Erlang je přeložen do bajtkódu prováděného virtuálními stroji umístěnými na různých uzlech distribuované počítačové sítě . Systémy Erlang podporují výměnu horkého kódu , což vám umožňuje provozovat zařízení nepřetržitě.
Erlang zdědil jeho syntaxi a některé pojmy z logického programovacího jazyka Prolog [6] . Jazyk podporuje mnoho datových typů , podmíněné konstrukce , porovnávání vzorů , zpracování výjimek , zahrnutí seznamu a výrazy bitových řetězců , funkce ( anonymní funkce , funkce vyššího řádu , definice rekurzivních funkcí , optimalizace tail rekurze ), moduly , odesílání a přijímání zpráv mezi procesy. Preprocesor podporuje makra a včetně hlavičkových souborů.
Popularita Erlangu začala růst díky rozšíření oblasti jeho aplikací ( telekomunikační systémy ) na vysoce zatížené paralelní distribuované systémy sloužící milionům uživatelů WWW , jako jsou chatovací místnosti , systémy pro správu obsahu , webové servery a distribuované databáze , které vyžadují škálování . Erlang se používá v několika vysoce dostupných NoSQL databázích [7] .
V polovině osmdesátých let počítačová laboratoř Ericsson zkoumala použitelnost tehdy existujících programovacích jazyků na software pro telekomunikační systémy. Joe Armstrong , Robert Virding a Mike Williams pod vedením Bjarne Däckera po napsání prototypů programů v různých jazycích dospěli k závěru, že žádný z těchto jazyků nemá úplnou sadu funkcí potřebných v oblasti telekomunikačních systémů. V důsledku toho vznikl nový programovací jazyk - Erlang [8] . Jazyk pravděpodobně dostal své jméno na počest dánského matematika a inženýra Agnera Erlanga , zakladatele vědeckého směru studia síťového provozu v telekomunikačních systémech. Podle jiné verze byl název jazyka původně zkratkou pro „jazyk Eriksson“ [9] .
Erlang byl ovlivněn ML , Miranda , Ada , Modula-2 , CHILL , Prolog . Kromě toho, Smalltalk a proprietární jazyky Ericssonu EriPascal a PLEX [8] ovlivnily způsob aktualizace softwaru .
Trvalo čtyři roky vývoje jazyka a prototypování pomocí virtuálního stroje Prolog , po kterém v roce 1991 Mike Williams přepsal virtuální stroj Erlang do jazyka C. V roce 1992 byl Erlang poprvé použit v komerčním projektu [8] . V roce 1995 byla vydána nová verze Erlang, která absorbovala zkušenosti s používáním jazyka, které se do té doby nashromáždily. Jazyk byl považován za dostatečně vyspělý, aby mohl být používán v jiných firemních produktech (širokopásmová řešení, GPRS , ATM ) [8] .
V prosinci 1995 došlo k události, kterou Joe Armstrong považuje pro Erlanga za rozhodující: projekt AXE-N v Ellemtel na vytvoření nového routeru (jak hardware, tak systémový software v C++) selhal. V důsledku reorganizace projektu bylo možné s využitím vyvinutého zařízení a programovacího jazyka Erlang zahájit práce na ATM routerech řady AXD. Zdroje laboratoře pro takový projekt se ukázaly jako nedostatečné, a tak byla pro práci na Erlang vytvořena produkční jednotka s názvem OTP (Open Telecom Platform) [10] . V roce 1996 byl vydán stejnojmenný rámec OTP [8] .
Nečekaně [11] se v roce 1998 nejvyšší vedení Ericssonu rozhodlo nezavázat se k vývoji a údržbě vlastního programovacího jazyka a místo toho se zaměřit na Javu . Používání Erlangu bylo v nových projektech Ericsson Radio AB zakázáno kvůli plánu outsourcovat softwarovou technologii společnosti Rational Inc. [12] [13] Toto rozhodnutí velmi ovlivnilo budoucnost Erlangu: vedlo k otevření kódu Erlang pod otevřenou licencí EPL (obdoba Mozilla Public License ) [14] , a také posloužilo jako hlavní důvod pro začátek šíření jazyka mimo společnost, která jej vytvořila. Hlavní námitkou proti otevřenému zdrojovému kódu bylo vyřešení problémů souvisejících s patenty, ale tyto potíže byly překonány [15] . Brzy mnoho hlavních vývojářů opustilo Ericsson a založilo si vlastní firmu Bluetail AB [15] [12] .
Na počátku roku 2000 začala akademická obec projevovat zájem o Erlang. Od roku 2002 se každoročně koná Erlang Workshop. Ericsson pokračoval ve sponzorování projektu HiPE ( High-Performance Erlang) [16] na univerzitě v Uppsale [Poznámka 1] . Projekt HiPE se podílel na efektivní implementaci jazyka a nástrojů pro kontrolu typu a od roku 2001 je kompilátor strojového kódu vytvořený projektovým týmem součástí distribuce bezplatné verze Erlang/OTP [10] . Práce související s Erlangem provádějí i další instituce vyššího vzdělávání. Refaktorovací nástroje byly vytvořeny na University of Kent ve Velké Británii a Lorand Eötvös University v Maďarsku, nástroje pro různé typy testování – na Polytechnic University of Madrid, Chalmers University of Technology a University of Göteborg [17] .
Když systémy se symetrickým multiprocesingem teprve začínaly dobývat trh serverů a desktopů, což bylo výzvou pro vývojáře softwaru, již v roce 2006 byla vydána první verze Erlang s podporou SMP společně týmem Ericsson OTP a týmem HiPE [16] . Krátce nato byla vydána první velká erlangská monografie za téměř deset let: „Programming Erlang“ od Joe Armstronga [18] , načež mnoho vývojářů „objevilo“ Erlang / OTP [16] , a jazyk si začal získávat na popularitě [19] .
Proces vývoje jazyka zahrnuje zvážení návrhů vývoje - EEP ( Enhancement Návrh ). Prostřednictvím těchto návrhů provádí komunita Erlang změny ve standardní distribuci Erlang [20] . Předložené návrhy lze nalézt na erlang.org/eeps [21] .
Podle Mika Williamse byl Erlang koncipován tak, aby vyřešil tři problémy ve vývoji distribuovaných systémů měkkého reálného času s vysokým stupněm paralelismu : schopnost rychle a efektivně vyvíjet software; získání systému, který je odolný vůči selhání softwaru a hardwaru, a možnost aktualizovat systém za chodu, bez prostojů zařízení [22] .
Podle Williamse je filozofie, které se vývojáři Erlangu drželi, vhodná i pro vývoj softwaru v tomto jazyce [23] :
oni pracují.
Většina jazyků napsaných před Erlangem byla vyvinuta bez předchozího nalezení jejich aplikace, zatímco Erlang byl vyvinut speciálně na základě požadavků na distribuované paralelní systémy v reálném čase odolné proti chybám. S rozvojem internetu se ukázalo, že podobné požadavky má mnoho aplikací [14] , což vysvětluje rostoucí zájem o jazyk [24] .
Vysoká odolnost proti chybám spočívá v použití odlehčených procesů izolovaných od sebe, propojených pouze mechanismem pro výměnu zpráv a výstupních signálů. Princip vývojářů Erlang ve vztahu k řešení chybných situací v procesech lze vyjádřit jako prohlášení:
Nechte aplikaci padat a ať se s ní vypořádá něco jiného. [25]
Původní text (anglicky)[ zobrazitskrýt] Ať se to zhroutí a ať se s tím vypořádá někdo jinýnebo ve zkratce – „let it crash“ („nechat to padat“). Je to dáno tím, že v systému Erlang je snadné sledovat ukončení procesu, ukončit procesy spojené s tím neúspěšným a spustit nové procesy [26] .
Erlang je deklarativní programovací jazyk , který se používá k popisu toho, co by mělo být hodnoceno spíše než jak . Například definice funkce , která používá porovnávání vzorů k výběru jedné z možností pro vyhodnocení nebo extrahování datového prvku ze složené struktury, připomíná rovnici . Porovnávání vzorů je rozšířeno i na bitové řetězce , což zjednodušuje implementaci telekomunikačních protokolů [14] .
Funkce jsou objekty první třídy v Erlangu. Jazyk také široce používá seznamové inkluze (generátory seznamů) charakteristické pro paradigma funkcionálního programování [27] .
Charakteristickým rysem jazyka je použití odlehčených procesů v souladu s modelem aktéra . Tento přístup umožňuje současné provádění stovek tisíc a dokonce milionů takových procesů, z nichž každý může mít skromné požadavky na paměť [28] . Procesy jsou od sebe izolované a nemají společný stav, ale můžete mezi nimi komunikovat a přijímat stavové zprávy. Procesy komunikují pomocí asynchronního zasílání zpráv. Každý proces má svou vlastní frontu zpráv , jejíž zpracování využívá porovnávání vzorů. Proces, který zprávu odeslal, neobdrží oznámení o doručení, i když je ID procesu příjemce neplatné nebo příjemce zprávu ignoruje. Odpovědnost za správně organizovanou interakci mezi procesy tedy leží na vývojáři [29] .
Například při implementaci síťového chatu v Erlangu může struktura programu přímo odrážet simultánnost uživatelských akcí pro zasílání zpráv spuštěním nových procesů. Efektivita předávání zpráv je udržována s rostoucím počtem procesů a požadavky na paměť jsou minimalizovány tím, že odlehčené procesy jsou spravovány spíše virtuálním strojem než základním operačním systémem [30] .
Erlang byl od počátku navržen pro distribuované výpočty a škálovatelnost . Distribuce výpočtů je zabudována do syntaxe a sémantiky jazyka, takže systém lze sestavit abstrahováním od konkrétního místa výpočtu. Ve standardní distribuci může Erlang navázat komunikaci mezi procesy pomocí protokolu TCP/IP , bez ohledu na základní platformy ( operační systémy ) , které podporuje [31] .
Běžící instance běhového systému Erlang se nazývá uzel . _ _ Programy napsané v Erlangu mohou běžet na více uzlech. Uzly mohou být procesory, mnoho jader jednoho procesoru nebo dokonce celý shluk strojů. Uzel má jméno a „ví“ o existenci dalších uzlů na daném počítači nebo síti. Tvorba a interakce procesů různých uzlů se neliší od organizace interakce procesů v rámci uzlu. K vytvoření procesu na jiném uzlu potřebuje proces znát pouze jeho jméno a bez zvláštního důvodu ho nemusí zajímat fyzické umístění procesu, který s ním interaguje. Syntaxe pro odeslání zprávy procesu na hostiteli a vzdáleném je stejná [31] .
Díky distribuovaným výpočetním schopnostem zabudovaným do jazyka klastrování , vyvažování zátěže , přidávání uzlů a serverů a zvyšující se spolehlivost způsobují jen malé množství dodatečného kódu. Ve výchozím nastavení jsou uzly navrženy tak, aby fungovaly v rámci samostatného síťového segmentu ( DMZ ), ale v případě potřeby může komunikace mezi uzly probíhat pomocí kryptograficky chráněného protokolu SSL [31] .
Programy ve vysokoúrovňovém jazyce Erlang lze používat v měkkých systémech reálného času (někdy překládáno jako „pseudo-reálný“ nebo „kvazi-reálný“ [32] ). Automatizovaná správa paměti a garbage collection fungují v rámci stejného procesu, což umožňuje vytvářet systémy s milisekundovou dobou odezvy (i když je garbage collection vyžadováno), které nezaznamenávají degradaci propustnosti při vysoké zátěži [33] .
Pro systémy, které nelze vypnout kvůli upgradu kódu , Erlang nabízí horkou aktualizaci kódu . V aplikaci přitom mohou současně fungovat stará i nová verze kódu. Tímto způsobem lze upgradovat software Erlang bez prostojů a opravovat chyby [9] [34] .
Psaní v Erlangu je silné a dynamické . Dynamické psaní bylo vybráno pro Erlang, protože první vývojáři s ním byli více obeznámeni [35] . Podle Joea Armstronga by statické psaní vyžadovalo hodně práce, konkrétně by bylo extrémně obtížné implementovat systém pro rychlé načítání kódu [36] . Toto typování, při kterém jsou možné chyby typu detekovány až za běhu, však nezabránilo vytvoření systémů s velmi vysokou dostupností [35] . Data v Erlangu jsou neměnná : operace nepřepisují staré hodnoty, které jsou v paměti. V případě potřeby mohou být moduly Erlang opatřeny popisy a definicemi nových typů (které nemají vliv na kompilaci programu) pro automatickou kontrolu typu pomocí utility Dialyzer [37] .
ČíslaErlang má dva typy číselných literálů : integer a floating point , například: 125, 4.5e-20. Kromě běžného zápisu lze čísla specifikovat pomocí znaku ASCII (například $Bznamená 66) nebo společně s číselnou soustavou se základem od 2 do 36 (ve starších verzích až 16), například: 16#3f, 2#1010. Erlang používá libovolně přesná celá čísla a dvojitá přesná reálná čísla (64 bitů ), ve standardu IEEE 754-1985 [38] .
Pro práci s čísly lze využít modul math, který obsahuje obvyklou sadu matematických funkcí a funkci math:pi/0, která vrací číslo [39] . Příklad výpočtů v interaktivním shellu :
Erlang R15B01 ( erts - 5. 9. 1 ) [ zdroj ] [ 64bitový ] [ smp : 4 : 4 ] [ async - threads : 0 ] [ kernel - poll : false ] _ _ _ _ Shell V5 . 9 . 1 ( zrušit s ^ G ) 1 > 123/23 + 12 * ( 2 + 3 ) . _ 65 . 34782608695652 2 > matematika : cos ( matematika : pí ()). - 1,0 3 > náhodné : jednotné ( 10 ). 5 AtomyAtom je konstanta s názvem, který musí být uzavřen v jednoduchých uvozovkách, pokud nezačíná malým písmenem nebo obsahuje jiné znaky než písmena, čísla, podtržítka, tečky a symbol @. Pojem atom je vypůjčen z Prologu a lze jej považovat za analogický s výčty v jiných programovacích jazycích (bez nutnosti předběžné deklarace) [40] . Atomy se používají téměř výhradně při porovnávání, které má velmi efektivní implementaci v Erlangu [41] . Kromě toho mají některé atomy specifický význam v návratových hodnotách a deklaracích výjimek. Patří sem: error, ignore, noreply, ok, reply, stop, undefined[42] .
Bitové řetězce a binární dataBitový řetězec se používá k ukládání nezadaných dat do paměti. Řetězce sestávající z celého čísla oktetů se nazývají binární (nebo binární ) data ( angl. binaries ). Syntaxe pro popis bitového řetězce je poměrně flexibilní, protože popisuje bitové hodnoty jednotlivých rozsahů a lze ji dodat s modifikátorem jako [43] . Několik příkladů v interaktivním příkazovém shellu:
1 > << 23 , 89 , 120 >> . << 23 , 89 , 120 >> 2 > << "ABC" >> . << 65 , 66 , 67 >> 3 > << 10 , 17 , 42 : 16 >> . << 10 , 17 , 0 , 42 >> 4 > << $a , $b , $c >> . << "abc" >> 5 > << 1024 / utf8 >> . << 208 , 128 >>Výrazy bitového řetězce ( angl. bitstring comprehension ) jsou podobné zahrnutím seznamu, ale fungují na bitových řetězcích [44] :
1 > << << bnot ( X ): 1 >> || << X : 1 >> <= << 2#111011 : 6 >> >> . << 4 : 6 >>V tomto příkladu proměnná X přijímá bity čísla postupně 2#111011, které jsou poté invertovány binární operací NOT bnot, což vede k číslu 4.
TupleN -tice je složený datový typ s pevným počtem prvků. Při přístupu k prvkům n-tice pomocí vestavěných funkcí začíná číslování prvků od jedné, nikoli od nuly. První prvek n-tice se obvykle používá k označení role n-tice v programu. Pokud je prvním prvkem atom, nazývá se tag . V Erlangu je zvykem stavět různé datové typy založené na nicích s tagy, což usnadňuje ladění programu a je považováno za dobrý programovací styl [45] .
Existuje několik vestavěných funkcí pro práci s n-ticemi, například [45] :
1 > velikost_n-tice ({ a , 1 , "777" }). 3 2 > prvek ( 1 , { b , 2 , 3 , 4 }). b 3 > osada ( 1 , { c , 5 }, d ). { d , 5 } SeznamSeznam ( anglicky list ) je složený datový typ obsahující proměnný počet prvků. Pro manipulaci se seznamy lze využít funkce listsstandardního knihovního modulu [46] . Formálně je seznam definován tak, že má hlavu ( eng. head ) a ocas ( eng. tail ), což je syntakticky vyjádřeno jako [HEAD|TAIL], kde ocas je obvykle seznam (případně prázdný). Prázdný seznam je označen [][47] .
Seznamy lze psát známějším způsobem. Následující položky jsou ekvivalentní:
1 > [ a |[ b |[ c |[]]]]. [ a , b , c ]Pro práci se seznamy můžete použít seznamové inkluze [48] (generátory seznamů), například:
1 > [ X / 2 || X <- [ 1 , 2 , 3 , 4 ]]. [ 0 . 5 , 1 . 0 , 1 . 5 , 2 . 0 ]Standardní listsknihovní modul obsahuje funkce pro práci se seznamy (a řetězci, protože řetězec je v Erlangu seznam) [49] , jako je hledání maxima, řazení, obrácení pořadí prvků, sčítání prvků atd. V následujícím příkladu jsou dva seznamy slepeny dohromady operací zřetězení a poté rozděleny na dvě části funkcí : lists:split/2
1 > seznamy : rozdělení ( 2 , [ l , 2 , 3 ] ++ [ 4 , 5 , 6 ]). {[ l , 2 ], [ 3 , 4 , 5 , 6 ]}Modul listsmá také sadu funkcí vyššího řádu jako lists:all/2, lists:any/2, lists:dropwhile/2, lists:filter/2, lists:foldl/3, lists:foldr/3, lists:map/2, lists:foreach/2. Následující příklad ilustruje fungování funkce lists:foldr( anglicky fold - kolaps, "r" z angličtiny right - right) pro skládání seznamu , jejímž prvním parametrem by měla být funkce:
1 > D = zábava ( V , A ) -> V / A konec . % funkce D - dělení V podle A # Fun < erl_eval . 12 . 82930912 > 2 > seznamy : složka ( D , 1 , [ 1 , 2 , 4 , 8 ]). 0 _ 25 3 > 1 / ( 2 / ( 4 / ( 8 / 1 ))). 0 _ 25Výsledek konvoluce zprava doleva (v řádku 2) je shodný s dělením řetězce (řádek 3). Druhý parametr foldrudává počáteční hodnotu pro tzv. akumulátor. Pro každý prvek v seznamu (zprava doleva) se na prvek a akumulátor použije funkce určená prvním argumentem foldra hodnota se zapíše do akumulátoru. Po vyčerpání seznamu funkce vrátí hodnotu akumulátoru [50] . Funkce je poměrně výkonná, vezmeme-li v úvahu, že akumulátor může být seznam nebo n-tice [51] .
LinkaErlang nemá samostatný typ pro řetězce : interně jsou řetězce reprezentovány jako seznamy. Syntakticky lze řetězec zadat pomocí uvozovek. Je tedy "Привет!"ekvivalentní (ve vhodném kódování) seznamu [1055,1088,1080,1074,1077,1090,33]. Erlang podporuje Unicode jak v řetězci, tak v jednoznakové notaci (via $) [52] .
Atomy a řetězce vypadají docela podobně, ale mají zcela odlišné implementace. listsZatímco atomy lze pouze porovnávat, řetězce podporují mnoho dalších operací a v modulech a je pro ně mnoho funkcí string. Řetězec může vykonávat funkce atomu, ale paměť obsazená řetězcem je úměrná jeho délce, zatímco atomy jsou uloženy v systémové tabulce a pro každé použití atomu v programu existuje pouze několik bajtů, bez ohledu na délky atomu. Porovnání dvou atomů je porovnání dvou vnitřních identifikátorů provedené v jedné operaci, zatímco porovnání řetězců zahrnuje iteraci přes prvky řetězců [53] .
Booleovské hodnotyErlang používá (true) a (false) atomy pro pravdivé a nepravdivé hodnoty , které se používají při porovnávacích operacích, logických operacích, vestavěných funkcích [54] . Příklad: truefalse
1 > 2 < 3 . true 2 > is_boolean ( 125 ). Nepravdivé Funkční objekt (Zábava)Zábavný výraz vám umožňuje vytvořit anonymní funkci , například ji předat jako parametr jiným funkcím. Můžete také použít funk získání funkčního objektu pro funkci z modulu [55] . Příklady:
1 > seznamy : mapa ( zábava ( X ) -> X + 1 konec , [ 1 , 2 , 3 ]). [ 2 , 3 , 4 ] 2 > Patří = seznamy zábavy : člen / 2 . # Zábavné < seznamy . člen . 2 > 3 > Patří ( a , [ a , b ]). skutečný ZáznamAby bylo možné označit jednotlivé prvky n-tic a vyhnout se chybám při psaní programu, byla do Erlang zavedena syntaxe záznamu . Pro práci se záznamy musíte nejprve uvést popis záznamu direktivou , například u záznamu může být popis následující [56] : -recorduser
- záznam ( user , { login = "anon" , heslo , nick }).Z tohoto popisu kompilátor ví, že jsou myšleny čtyři n-tice, ve kterých druhý až čtvrtý prvek odpovídá polím login, password, nick(pořadí je důležité) záznamu s názvem user(určeným atomem v prvním prvku n-tice ). Výchozí hodnotou pro pole loginje řetězec "anon". Pokud není explicitně zadána žádná výchozí hodnota, předpokládá se atom undefined.
Vytváření záznamů a načítání prvků záznamu vždy vyžaduje explicitní název záznamu [56] :
R0 = #user {} % všechna pole jsou nastavena jako výchozí R1 = #user { login = "user1" , password = "secret" , nick = "john" } % všechna pole jsou nastavena jako výchozíSyntaxe pro přístup k hodnotám polí záznamu je: R1#user.login, R0#user.nick[56] .
Asociativní poleAsociativní pole (slovník) ukládá dvojice ve tvaru "(klíč, hodnota)". Jakýkoli termín Erlang může fungovat jako klíč i hodnota.
Mapa = #{ a => 2 , b => 3 , c => 4 , "a" => 1 , "b" => 2 , "ahoj" => 42 }, klíč = "ahoj" , mapy : najít ( Klíč , Mapa ). { dobře , 42 } Jiné typyErlang má i jiné datové typy. Typ odkazu je v běhovém prostředí Erlang téměř jedinečný [57] . Odkaz je vytvořen voláním funkce a lze jej opakovat po 2 82 voláních této funkce [58] . Odkazy lze porovnávat z hlediska rovnosti a používají se pro jednorázové příznaky nebo „ magické cookies “ [59] . make_ref/0
Identifikátor portu definuje port pro komunikaci se světem mimo systém Erlang . Port umožňuje procesu vlastníka, který jej vytvořil (tzv. připojený proces), vyměňovat si binární zprávy s programy a OS třetích stran způsobem akceptovaným v tomto operačním systému [59] [60] [41] .
ID procesu ( angl. Pid ), jak jeho název napovídá, identifikuje proces vytvořený různými funkcemi spawn. Identifikátor může být považován za jedinečný, když je systém Erlang spuštěn, ale stále může být znovu použit na dlouho běžících systémech, což v praxi obvykle není problém [59] .
Vestavěné funkce pro práci s typyPro převod typů se používají vestavěné funkce (BIF, z anglického builtin function ) tvaru x_to_y („od x do y“) a pro kontrolu, zda hodnota patří k tomu či onomu typu, funkce tvaru is_x ( "je x")):
1 > atom_to_list ( ahoj ). "hello" 2 > list_to_binary ( "svět" ). << "svět" >> 3 > tuple_to_list ({ 1 , 2 , 3 , 4 }). [ 1 , 2 , 3 , 4 ] 1 > is_integer ( 3 ). true 2 > is_tuple ( "abc" ). false 3 > is_integer ( 3 . 0 ). NepravdivéErlang poskytuje nejběžnější aritmetické operace pro celá čísla a čísla s plovoucí desetinnou čárkou :
Označení | Probíhá operace | Příklad | Příklad výsledku |
---|---|---|---|
+ | unární plus | +3 | 3 |
- | unární mínus | -3 | -3 |
+ | Přidání | 2+3 | 5 |
- | Odčítání | 7-3 | 4 |
* | Násobení | 1.2*0.4 | 0.48 |
/ | Divize | 5 / 3 | 1.6666666666666667 |
div | Celočíselné dělení | 5 div 3 | 1 |
rem | Celočíselné dělení se zbytkem | 5 rem 3 | 2 |
Všechny tyto operace jsou ponechány asociativní . Unární operace mají nejvyšší prioritu, následuje násobení a dělení a nejnižší prioritu sčítání a odčítání. V případě potřeby lze celé číslo přetypovat na typ s plovoucí desetinnou čárkou [61] .
Bitové operaceBitové operace pracují s celými čísly a výsledkem je celé číslo [62] .
Označení | Probíhá operace | Příklad | Příklad výsledku |
---|---|---|---|
bnot | bitová negace | bnot (2#1000) | -9 |
band | Bitové AND | 2 band 3 | 2 |
bor | Bitově NEBO | 1 bor 2 | 3 |
bxor | Bitový XOR | 5 bxor 3 | 6 |
bsr | Bitový posun doprava | 32 bsr 2 | 8 |
bsl | Bitový posun doleva | 1 bsl 5 | 32 |
Booleovské operace pracují s booleovskými hodnotami true(true) a false(false) vyplývajícími z porovnávání a funkcí kontroly typu [63] .
Označení | Probíhá operace | Příklad | Příklad výsledku |
---|---|---|---|
not | Negativní (NE) | not true | false |
and | Konjunkce (AND) | true and (1 < 5) | true |
andalso | Podobně and, ale nevyhodnocuje druhý operand, pokud je prvnífalse | false andalso (1 < 5) | false |
or | Disjunkce (OR) | is_atom("1") or is_atom(1) | false |
orelse | Podobně or, ale nevyhodnocuje druhý operand, pokud je prvnítrue | true orelse (1 < 5) | true |
xor | XOR | true xor true | false |
Porovnávací operace mají dva operandy a výsledkem operace je logická hodnota truenebo false. Erlang má následující operátory: ==(rovná se), /=(není se rovná), =<(menší nebo rovno), <(menší než), >(větší než), >=(větší než nebo rovno) a srovnání, která fungují bez přetypování na stejný typ: =/=(nerovná se přesně) a =:=(rovná se přesně).
Je také možné porovnávat hodnoty různých typů, ale v Erlangu jsou považovány za seřazené následovně [64] :
číslo < atom < odkaz < funkce < port < id procesu < n-tice < seznam < binární dataSeznamy jsou považovány za seřazené v lexikografickém pořadí a n-tice se porovnávají podle délky a teprve potom v lexikografickém pořadí [64] .
Proměnné se používají k ukládání hodnot jednoduchých a složených typů. Název proměnné začíná velkým písmenem (ve zvláštních případech podtržítkem) a může obsahovat písmena, čísla, podtržítka. Hodnotu lze proměnné přiřadit pouze jednou, což je vlastnost programovacího jazyka nazývaná jednoduché přiřazení [65 ] . Mezi výhody jediného zadání patří eliminace potřeby zámků a také zjednodušení ladění programu [66] .
Parametry jsou předány funkci hodnotou , takže jsou všechny vyhodnoceny před voláním funkce [65] .
Rozsah proměnné sahá od okamžiku, kdy se objeví v záhlaví deklarace funkce nebo přiřazení, do konce části deklarace funkce. Příklad [67] :
binomické ( X ) -> Y = X * X , X + Y . prod ([ 1 | T ]) -> prod ( T ); prod ([ Y | T ]) -> Y * prod ( T ); prod ([]) -> 1 .V tomto příkladu je rozsahem X celý popis funkce binomial/1a rozsah Y je od přiřazení do konce popisu. Proměnná Yv druhé části (klauzule) deklarace funkce prod/1nemá nic společného s proměnnou Yfrom binomial/1: její rozsah sahá až na konec této klauzule.
Když výpočty přesahují rámec proměnné, paměť obsazená jejím obsahem může být uvolněna během garbage collection, pokud není hodnota proměnné použita v jiné části programu [68] .
Porovnávání vzorů se v Erlangu používá pro přiřazení (včetně práce s parametry funkcí), řízení toku provádění programu, extrahování hodnot složených typů a výběr zprávy z fronty. Levá strana porovnání (nebo hlavičky funkce) může obsahovat vázané (již mající hodnotu) a nevázané (získávající hodnotu) proměnné a také literály (atomy, čísla, řetězce). V důsledku provedení může být srovnání úspěšné (v tomto případě jsou proměnné spojeny s hodnotami) a neúspěšné - proměnné zůstávají nesvázané. Ve vzoru mohou být proměnné, jejichž hodnota je vůči vzoru lhostejná: jejich názvy se píší začínající podtržítkem [69] . Proměnná s názvem _(podtržítko) odpovídá libovolné hodnotě, ale nedochází k žádné vazbě. Takovou proměnnou lze použít mnohokrát.
Programy Erlang se skládají z funkcí, které se navzájem volají. Počet parametrů funkce se nazývá arita . Když je funkce volána, části záhlaví deklarace funkce se shodují se vzorem. Pokud se parametry volání shodují, jsou formální parametry spojeny se skutečnými a je provedena odpovídající část těla funkce [70] . Záznam varianty výpočtu funkce pro určitý vzorek lze nazvat klauzulí z angličtiny. klauzule a definice funkce je sada jedné nebo více klauzulí [71] .
Pro upřesnění shody vzorů ve funkcích můžete použít ochranné výrazy , které následují za klíčovým slovem when[72] . V níže uvedeném příkladu je definována funkce pro výpočet znaménka čísla , která se vypočítává v závislosti na porovnání parametru s nulou:
znaménko ( X ) , když X > 0 -> 1 ; znaménko ( X ) když X == 0 -> 0 ; znaménko ( X ) když X < 0 -> - 1 .Erlang iteruje klauzule v pořadí, v jakém jsou zapsány, dokud není nalezena vhodná hlavička [73] . V ochranných výrazech lze použít pouze omezenou sadu vestavěných funkcí, protože tyto funkce nesmí mít vedlejší účinky .
Funkce Erlang samozřejmě podporují rekurzivní volání. V případě, kdy definice funkce končí rekurzivním voláním ( tail recursion ), Erlang používá optimalizaci: zásobník volání není aplikován [74] .
Parametrem i výsledkem funkce může být jiná funkce. V následujícím příkladu vrací funkce s jedním argumentem funkci pro přidání argumentu [75] :
1 > Plus = zábava ( X ) -> zábava ( Y ) -> X + Y konec konec . % Definice funkce, která vrací funkci # Fun < erl_eval . 6 . 82930912 > 2 > Plus ( 2 ). % Funkce vrací objekt Fun # Fun < erl_eval . 6 . 82930912 > 3 > Plus ( 2 ) ( 3 ). % Tato syntaxe nefunguje * Totéž_____.)3())2(Plus(>4'(':předsyntaxechyba:1 5 PříkladyFaktorový výpočet v Erlangu:
- modul ( skutečnost ). - export ([ fac / 1 ]). fac ( 0 ) -> 1 ; fac ( N ) , když N > 0 , je_integer ( N ) -> N * fac ( N - 1 ).Algoritmus řazení připomínající quicksort [34] :
- modul ( qsort ). - export ([ qsort / 1 ]). qsort ([]) -> []; % Triviální případ prázdného seznamu qsort ([ Pivot | Rest ]) -> % Zřetězení seznamu prvků před Pivot, seznam jednoho prvku Pivot a za Pivot qsort ([ Front || Front <- Rest , Front < Pivot ]) ++ [ Pivot ] ++ qsort ([ Zpět || Zpět <- Odpočinek , Zpět >= Pivot ]).V tomto příkladu je funkce qsortvolána rekurzivně, dokud nejsou vyčerpány všechny prvky. Výraz [Front || Front <- Rest, Front < Pivot]shromažďuje seznam Frontprvků Rest, takže prvek je Frontmenší než Pivot. Obsluha ++ lepí seznamy.
Kromě výběru popisu v definici funkce existují v Erlangu další podmíněné výrazy: case-expressions (výraz výběru) a if-výrazy. Výraz select vám umožňuje organizovat shodu vzorů v rámci funkce a obvykle má následující syntaxi:
případový výraz - výběr vzoru 1 při strážce 1 -> výraz 11 , výraz 12 , ... ; vzor 2 když stráž 2 -> výraz 21 , výraz 22 , ...; ... ukázka N když stráž N -> výraz N1 , výraz N2 , ... konecTento výraz vždy vrátí hodnotu odpovídající poslednímu výrazu vyhodnocenému v řetězci, který odpovídá vzoru. Tato návratová hodnota může sloužit jako návratová hodnota funkce nebo může být přiřazena proměnné [76] . Stejně jako v hlavičce funkce může tento vzor sledovat i ochranný výraz.
Zjednodušená verze případu-výrazu je if-výraz:
if stráž 1 -> výraz 11 , výraz 12 , ...; stráž 2 -> výraz 21 , výraz 22 , ...; ... stráž N -> výraz N1 , výraz N2 , ... konecZde охранаi je výraz strážce. První true guard výraz způsobí provedení odpovídajících výrazů, z nichž poslední je hodnotou celého if-výrazu [77] . Je třeba poznamenat, že i zde lze ve výrazu guard použít pouze omezenou sadu operací a vestavěných funkcí.
Čárky v ochranném výrazu fungují jako operátor and, například [78] :
if X =< 0 -> 'menší nebo rovno nule' ; X > 0 , X < 10 -> 'větší než nula a menší než deset' ; X >= 10 -> 'větší než nebo rovno deseti' ; konecKompilátor Erlang se stará o bezpečnost vazby proměnných uvnitř podmíněných výrazů, jak je vidět v následujícím příkladu modulu:
-modul ( špatný příklad ) . - exportovat ([ broken_if / 1 ]). broken_if ( X ) -> if X < 0 -> Z = - 1 ; X >= 0 -> Y = 1 konec , Y * Z .Při pokusu o kompilaci modulu se objeví chybové zprávy, protože v takovém kódu není jedna z proměnných spojena s hodnotou:
1 > c ( badpříklad ). špatný příklad . erl : 8 : proměnná 'Y' není bezpečná v 'if' ( řádek 4 ) v příkladu . erl : 8 : proměnná 'Z' není bezpečná v chybě 'if' ( řádek 4 )Bylo by správné definovat všechny proměnné používané dále v kódu ve všech větvích if-výrazu [79] .
Erlang Preprocessor (EPP) umožňuje vnořovat zdrojové soubory, definovat makra a provádět jednoduché a parametrizované substituce maker [80] . Makro je definováno pomocí direktivy -definea nahrazení makra se provádí zadáním názvu makra a možných parametrů za otazníkem ( ?). Následující příklad ukazuje definici a použití parametrizovaného makra:
- definovat ( NULA ( X ), X == 0 ) je_nula ( T ) když ? NULA ( X ) -> true ; je_nula ( T ) -> nepravda .Název makra se obvykle píše velkými písmeny. Definice makra musí obsahovat celé tokeny Erlang (například pokus o zadání části názvu proměnné pomocí makra způsobí chybu syntaxe). Makra lze použít ke zlepšení čitelnosti kódu ve strážcích, ladicích příkazech atd. [81] Preprocesor má několik předdefinovaných maker, která nelze přepsat: ?MODULE, ?MODULE_STRING, ?FILE, ?LINE, ?MACHINE[82] .
Pomocí direktivy [83].hrl lze zahrnout hlavičkový soubor (příponu ) s definicemi maker a záznamů . -include
Pro zpracování výjimek v Erlangu můžete použít konstrukci try-catch, která se obecně píše takto [84] :
try vyhodnoceno - výraz vzoru 1 když stráž 1 - > výraz 1 ; vzor 2 když stráž 2 -> výraz 2 ; ... vzor N při strážci N -> výraz N chytit třídu 1 : vyloučení vzoru 1 při vyloučení strážce 1 -> vyloučení výrazu 1 ; ... třída M : vzor Př M když stráž Př M -> výraz Př M ; konecStejně jako u výrazu typu case je vyhodnocený výraz porovnán se vzorem (části mezi ofa catch), aby se získal výsledek [Poznámka 2] [85] . Za klíčovým slovem catchnásledují části zpracování výjimek, ve kterých lze kromě vzorů výjimek specifikovat třídy výjimek (před dvojtečkou): error, throwa exit. Podtržítko lze použít jak ve vzoru, tak ve třídě výjimky [86] . Následující jednoduchý příklad ilustruje zachycení chyb třídy errorpři výpočtu druhé odmocniny :
1 > zkuste matematiku : sqrt ( - 1 ) catch error : Error -> { error , Error } end . { error , badarith } 2 > zkuste math : sqrt ( 4 ) catch error : Error -> { error , Error } end . 2 . 0Pro vytvoření uživatelsky definovaných výjimek použijte funkci throw/1, která vezme n-tici s podrobnějším popisem chyby, ke které došlo [87] , a vyvolá výjimku třídy throw. Použití této funkce je nežádoucí kvůli čitelnosti programového kódu, ale může být v některých případech vyžadováno při práci s vnořenými datovými strukturami, například při parsování XML [86] . Výjimky třídy jsou exitvyvolány jako výsledek volání vestavěné funkce exit/1nebo výstupního signálu [86] .
Dokud Richard Carlsson z projektového týmu HiPE nevyvinul nový mechanismus zpracování výjimek popsaný výše (zavedený ve verzi R10B), používal Erlang výrazy catch [88] .
Kód programu Erlang lze rozdělit do samostatných modulů . Modul je název pro sadu funkcí organizovaných v jednom souboru. Název modulu se musí shodovat s názvem souboru (pokud zahodíte příponu ) [89] . Modul lze zkompilovat do bajtkódu buď z příkazového řádku operačního systému nebo z Erlang shellu [90] . Soubor modulu může obsahovat deklarace funkcí a direktivy (někdy nazývané atributy) [91] . Povinný atribut je pouze -module(атом_имени_модуля).Další běžně používaný atribut - -export - se používá k určení seznamu exportovaných funkcí, tedy funkcí, které lze použít mimo modul.
Funkce v Erlangu jsou jednoznačně definovány modulem, názvem a aritou . Například math:cos/1odpovídá funkci cosz modulu math, která přebírá jeden argument. Funkci můžete volat takto: math:cos(1.2)[89] .
Zdrojový kód modulu je zkompilován do souboru BEAM, souboru obsahujícího bajtový kód virtuálního stroje BEAM ( Bogdan 's /Björn's Erlang Abstract Machine [90] ). Tento kód zase provádí ERTS ( Erlang Runtime System ) [55] .
Hlavní abstrakcí souběžného programování v Erlangu je proces . Procesy mohou plodit další procesy, běžet současně, vyměňovat si zprávy, vzájemně reagovat na ukončení.
Vytváření procesůPro vytvoření nového procesu existuje několik vestavěných funkcí ( spawna jeho analogů) [92] . Funkce vrací ID procesu, které lze použít například k odesílání zpráv nově vytvořenému procesu. V interaktivní erl konzoli můžete získat seznam procesů a další informace voláním funkcí processes()., i().respektive [93] .
Odesílání a přijímání zprávStejně jako jazyk Ockham používá Erlang k odeslání zprávy syntaxi vykřičníku: ИдПроцесса ! Сообщение. Příjem zprávy – to znamená její načtení z fronty procesu („poštovní schránky“) – se provádí pomocí příkazů příjmu, které jsou obvykle zapsány takto [94] :
přijímat vzor 1 , když stráž 1 -> výraz 11 , výraz 12 , ...; vzor 2 když stráž 2 -> výraz 21 , výraz 22 , ...; ... vzorek N když stráž N -> výraz N1 , výraz N2 , ...; UnboundVariableForOtherMessages -> expression 1 , expression 2 , ... endKdyž na takový výraz narazí, interpret postupně prohledává zprávy z fronty. Interpret spáruje každou zprávu se vzorem, a pokud se vzorem shoduje, vyhodnotí se odpovídající výrazy. Když jsou všechny zprávy vytříděny a žádná vhodná není, proces se zablokuje při čekání na nové zprávy, po kterém se opakování fronty opakuje. Pokud ve výrazu pro příjem není žádný vzor, který by jakákoli zpráva vyhovovala, nazývá se tento výraz výrazem selektivního příjmu [93] .
Zpracování chyb a ukončení procesůProces může být propojen s jiným, což má za následek obousměrné propojení mezi procesy ( anglicky link ). Pokud se některý z procesů ukončí abnormálně, je všem přidruženým procesům zaslán výstupní signál . Procesy, které přijímají signál, se ukončí a signál se dále šíří [95] [96] . Výstupní signál je n-tice, jejíž prvky jsou atom (exit), ID procesu opouštějícího procesu a důvod opuštění procesu. Důvod ukončení je předán v řetězci ukončovacích procesů [97] . 'EXIT'
Proces může zachytit chyby , pokud má nastaven příznak ukončení soutisku [ Poznámka 3] . Takový proces přijímá výstupní signály ze svých přidružených procesů ve formě normálních zpráv se stejnou strukturou n-tice. Zachycený výstupní signál se již nešíří do procesů spojených s procesem zavěšení [98] . Výstupní signál s atomem příčiny (normální ukončení procesu) nezpůsobí ukončení souvisejícího procesu. Pokud je příčinou atom , proces se bezpodmínečně ukončí (bez ohledu na příznak výstupního háku) a přidruženým procesům je poslán atom jako příčina , což jim dává šanci reagovat [99] . normalkillkilled
Erlang má také schopnost navázat jednosměrné spojení. Když sledovaný proces skončí, proces sledování obdrží zprávu s uvedením důvodu ukončení [100] .
Proces může zastavit sebe nebo jiný proces voláním funkce exit[101] .
V Erlangově plánovači procesů je I/O problém, který je vlastní mnoha dalším paralelním programovacím jazykům, vyřešen poměrně elegantně. I/O management integrovaný s plánovačem je založen na událostech již na nejnižší úrovni, což umožňuje programu zpracovávat příchozí a odchozí data bez zbytečného blokování. Tento přístup vyžaduje méně spojení, která je třeba nastavovat a rušit, a eliminuje potřebu zámků a přepínačů kontextu . Bohužel, takto poměrně efektivní metoda je pro programátory obtížnější na pochopení a používá se především v systémech s explicitními požadavky na vysokou dostupnost a nízkou dobu odezvy. Implementace událostmi řízených I/O je zabudována do systému Erlang, což je další výhoda při návrhu paralelních aplikací [102] .
Standardní knihovna obsahuje modul ios I/O funkcemi. Takové funkce mají vedlejší účinky , jako je zobrazení výstupu na konzole nebo zápis dat do souboru na disk. Například funkce io:formatpro formátovaný výstup vytiskne řetězec se substitucí parametru a v případě úspěchu vrátí atom ok[103] :
1 > io : formát ( "Příklad výstupu: ~p~n " , [ 1 ]). Příklad výstupu : 1 okMezi vlastnosti modulu iopatří standardní rozhraní I/O serveru. I / O protokol Erlang podrobně definuje spojení mezi klientem a serverem. I/O server je proces, který zpracovává požadavky a provádí požadované příkazy, například na I/O zařízení. Klient je jakýkoli proces Erlang, který potřebuje pracovat se zařízením [104] [105] .
Podle oficiální dokumentace je standardní modulová knihovna STDLIB [106] povinná pro zahrnutí do minimálního systému Erlang/OTP [107] spolu s jádrem Erlang. Knihovna obsahuje moduly, které poskytují řadu funkcí pro práci s vestavěnými typy a dalšími datovými strukturami, I/O, přístup k prostředí, práci se souborovým systémem, procesy atd.
Modul arraydefinuje (funkční) abstraktní datový typ pro dynamické pole a má funkce, které umožňují načítat a aktualizovat prvky pole, definovat rekurzivní funkce pro práci s poli. Modul stringrozšiřuje možnosti modulu listso funkce pro práci konkrétně se seznamy znaků, což jsou v Erlangu řetězce. Modul dict(z anglického slovníku - dictionary) obsahuje funkce pro asociativní pole , které umožňuje ukládat, načítat a mazat hodnoty podle klíče, spojovat pole a iterovat prvky. V modulu lze nalézt matematické funkce a modul obsahuje mathfunkce pro generování pseudonáhodných číselrandom . Modul calendarposkytuje funkce pro gregoriánský kalendář : dotaz na aktuální datum, převod jednotek měření a časových intervalů a modul timerobsahuje funkce pro převod časových intervalů na milisekundy , spouštění událostí na časovači a další funkce související s časem. Modul erlangobsahuje všechny vestavěné funkce Erlang, obecné i specifické pro virtuální stroj. Modul fileumožňuje přístup k funkcím souborového systému , jako je otevírání, čtení, zápis, mazání souborů , a modul filenameumožňuje zapisovat funkce pro manipulaci se jmény a cestami souborů abstrahující od konkrétního operačního systému. Modul ioposkytuje I/O funkce. Kromě těchto nejdůležitějších modulů obsahuje standardní knihovna mnoho dalších, které naleznete v dokumentaci [108] .
Tabulky ETS a DETSPro uspořádání sbírek v RAM nabízí Erlang modul ets (ETS, Erlang Term Storage) [ Poznámka 4 ] ). ETS může uchovávat čtyři typy kolekcí: set ( anglicky set ), objednaný set ( anglicky order set ), multiset ( anglicky bag ), multiset s opakováním ( anglicky duplicate bag ) [109] . K prvkům kolekce se přistupuje pomocí pole klíče n-tice (klíče mohou být libovolného typu). Seřazené sady jsou implementovány jako binárně vyvážené AVL stromy a zbytek kolekcí je implementován pomocí hashovacích tabulek [110] .
Tabulky DETS doplňují funkčnost tabulek ETS (s výjimkou uspořádaných sad) tím, že umožňují ukládání dat do souborů [111] .
OTP ( Open Telecom Platform ) je dobře zavedená sada užitečného chování procesů a používá se k vytváření serverových aplikací . OTP formalizuje akce procesů a umožňuje vám na nich stavět OTP aplikace (neplést s aplikací – hotovým softwarovým produktem). Moduly OTP definují společné, standardizované vzory pro vytváření souběžných aplikací [112] . Nejoblíbenějšími způsoby chování jsou generický server a pozorovatel , ale existují i další: stavový stroj , obsluha události [113] . OTP také obsahuje další middleware , jako je Mnesia DBMS .
Chování OTP se dělí na pracovní procesy ( anglicky worker process ), které provádějí vlastní zpracování požadavků, a procesy pozorovatele ( anglicky supervizoři ). Úkolem posledně jmenovaného je sledovat pracovní procesy a další procesy pozorovatele - potomky. Stromy pozorovatelů tvoří OTP aplikaci ( aplikaci ) [ 114] . Dokumentace Erlang definuje OTP aplikaci jako komponentu, která implementuje nějakou funkcionalitu, kterou lze nezávisle spouštět a zastavovat jako celek a také znovu použít v jiných systémech [115] . Vývojář aplikace zapíše kód modulu zpětného volání , který obsahuje část funkčnosti specifickou pro aplikaci [ 114] .
Ačkoli OTP není striktně řečeno součástí jazyka Erlang, stalo se natolik zakořeněné v kultuře a praxi vývojářů Erlang, že je někdy obtížné nakreslit mezi nimi hranici [113] .
Vývoj GUI aplikací (nepočítáme -li webová rozhraní ) lze provést pomocí knihovny wxErlang , knihovny wxWidgets portované do Erlangu. WxErlang je součástí standardní distribuce Erlang/OTP. WxWidgets je napsán v C++ , takže vývojáři wxErlang měli za úkol vyjádřit hierarchii objektů v Erlangu . Abychom to trochu zjednodušili, ve wxErlang jsou třídy moduly a objekty jsou odkazy. Makra C++ odpovídají makrům Erlang. Některé datové typy, pro které byly v C++ použity třídy, jsou v Erlangu reprezentovány pomocí jiných datových typů, například wxPoint je uveden jako dvou-tice. Události ve wxErlang lze zpracovat v Erlangu buď pomocí funkcí zpětného volání, nebo nativním předáváním zpráv Erlang [ 116] .
Interaktivní shell ( anglicky shell ) pro Erlang lze na systémech podobných Unixu vyvolat příkazem erl, na Windows - werl[117] . V shellu můžete zadávat výrazy a získat výsledek jejich provádění, zkoušet nový kód, provádět interaktivní ladění a také spravovat systém, který je ve výrobě [118] .
Shell umožňuje používat další funkce ("příkazy"), které jsou dostupné pouze v shellu. Například příkaz q().opustí shell a ukončí vše, co systém Erlang dělá [118] .
V shellu můžete vyvolat nabídku BREAK pomocí Ctrl+ C(na operačních systémech typu Unix) nebo Ctrl+ Break(na Windows). Toto menu obsahuje různé příkazy včetně a - okamžité zastavení, c - pokračování v práci v shellu a další informační a pomocné příkazy pro práci se systémem Erlang [118] . Kombinace kláves Ctrl+ Gvyvolá další příkazové menu, pomocí kterého můžete mimo jiné zastavit proces, který „zavěsil“ shell, a vrátit se do shellu ( ia pak c) [119] .
Text od znaku procenta ( %) do konce řádku je v Erlangu považován za komentář. Generování dokumentace ze zdrojového kódu v Erlangu může být provedeno dokumentačním systémem EDoc. K doložení kódu modulu stačí určitým způsobem přidat označený text a také soubor overview.edocpro dokumentaci na úrovni projektu (u druhé není nutné používat značky komentáře) [120] . Nástroje pro práci s kódem Erlang, jako je režim erlang v Emacsu , mají určité konvence pro použití znaků komentáře. Trojité procento tedy způsobí zarovnání doleva, dvojité procento zarovná na úrovni okolního kódu a jedno procento se používá k označení komentáře za kódem na konci řádku [121] . Vývojáři Erlang vyvinuli určité stylové konvence týkající se organizace a prezentace zdrojového kódu. Za dobrou praxi se například považuje vnořování vnořených syntaktických struktur, psaní krátkých modulů (méně než 400 řádků kódu) a funkcí (ne delších než 15–20 řádků kódu), používání smysluplných jmen pro proměnné a funkce atd. [ 122] [123]
Aplikace Dialyzer, vyvinutá v rámci projektu HiPE a zahrnutá ve standardním balíčku, umožňuje odhalit chyby (včetně překlepů) pomocí statické analýzy kódu . Program TypEr, který napsali Tobias Lindahl a Kostis Sagonas, je součástí Dialyzeru. Tento program umožňuje kontrolovat definice typů funkcí, porovnávat -spectyp funkce uvedený v direktivě s její definicí, provádět typovou inferenci [124] . Program TypeEr vypisuje všechny typy odpovídající úspěšné aplikaci funkce, v obecném případě - pouze přibližně, hrubším způsobem. Použití funkce jakýmkoli jiným způsobem nutně povede k chybě běhu [124] . Následující příklad ukazuje syntaxi definice typu (directive -type), deklaraci typu pole záznamu a direktivu -specspolu s definicí funkce:
- typ ( user_status () :: vypnuto | povoleno ). % stav - jeden ze dvou atomů - záznam ( uživatel , { login = "anon" :: řetězec (), % typů polí záznamu heslo :: řetězec (), stav :: stav_uživatele (), přezdívka :: řetězec ()}). - spec ( check_password ( string (), #user {}) -> ok | { error , string ()}). % deklarace funkce check_password ( heslo , uživatel ) -> definice funkce % ...Dialyzer (z anglického DIscrepancy AnaLYZer for ERlang Programs - „analyzátor rozporu pro programy Erlang“) detekuje nadbytečné kontroly, typové chyby, nedostupný kód v kódu jednotlivých modulů i celých aplikací . Všechny závady identifikované nástrojem musí být odstraněny, protože nástroj nedává falešné poplachy. Pro každou funkci všech testovaných modulů Dialyzer určí typ pomocí odvození typu založeného na omezení a analýzy toku dat. Po určení typů funkcí se provede analýza rozporů v programu [125] .
Erlang poskytuje EUnit pro testování jednotek a rámec Common Test pro testování systému . EUnit obsahuje nástroje pro popis testů, včetně sady maker k tomu nezbytných, a na konci testování také vytváří výstup zprávy. Moduly se testují připojením hlavičkového souboru z EUnit a funkce s testy lze buď zahrnout do samotného testovaného modulu, nebo přesunout do samostatného [126] .
Paralelní programy lze testovat pomocí Quviq Quick Check (verze Mini tohoto produktu je k dispozici zdarma) [127] . Kromě testování je možné pomocí metody model checking zkontrolovat všechny možné varianty výchozích dat . K tomu můžete použít samostatně distribuovaný nástroj McErlang [128] vytvořený na Madridské polytechnické univerzitě .
Chcete-li profilovat kód a určit stupeň pokrytí kódem testy , můžete se obrátit na moduly eprof, fprofa obslužnýcover program cprof [129] .
Pro Erlang bylo vyvinuto několik nástrojů pro refaktorování zdrojového kódu , jako je RefactorErl, Wrangler a automatický, na IDE nezávislý obslužný program. Úhlednější nástroj vám umožňuje automaticky najít a provádět ekvivalentní transformace kódu, například nahrazení
lists:filter(fun (X) -> is_something(X) end, L)na
[X || X <- L, is_something(X)][130] .Stejně jako mnoho jiných programovacích jazyků má i Erlang svá vlastní tajemství psaní efektivního kódu. Vylepšení jazyka činí některé triky zastaralými, takže dokumentace je nejlepším průvodcem problémů s optimalizací ve spojení s profilováním a zátěžovým testováním .
Například při práci se seznamy se nedoporučuje přidávat prvek na konec dlouhého seznamu pomocí zřetězení nebo funkce přidat prvek do seznamu. Místo toho zvažte přidání prvku na začátek seznamu a konečný výsledek zpracujte pomocí funkce pro obrácení pořadí prvků seznamu [131] .
Nechybí ani doporučení pro zvýšení efektivity paralelních programů. Například činnosti, které vyžadují hodně paměti, je nejlepší alokovat do samostatného procesu, protože to minimalizuje náklady na shromažďování odpadu: paměť se uvolní, když proces skončí [132] .
Podrobné srovnání funkcí Erlangu s jinými jazyky naleznete v článku Porovnání programovacích jazyků .
Erlang-system umožňuje integraci se systémy v jiných programovacích jazycích. Existují mechanismy pro síťování s C , Java , Lisp , Perl , Python , Ruby . Například pro efektivnější synchronní volání malých C funkcí můžete použít funkce specifické pro platformu ( NIF, nativně implementovaná funkce ) . Knihovny na vysoké úrovni umožňují systému Erlang reprezentovat uzly C nebo Java jako běžné uzly Erlang. Jiné jazyky se mohou blíže propojit s runtime Erlang pomocí ovladačů nebo síťových soketů přes protokoly jako HTTP , SNMP , IIOP [133] . Například Ruby může komunikovat s Erlangem prostřednictvím balíčku erlectricity a Python má implementaci uzlu Erlang ve formě balíčku py-interface [134] .
Virtuální stroj Erlang nachází využití i v jiných programovacích jazycích, jako je Elixir [135] [136] a projekt Erl2 Joe Armstronga [137] [136] . Kromě toho Robert Virding udržuje projekt Lisp Flavored Erlang („Erlang ochucený Lisp“), který používá syntaxi Lisp s kompilátorem Erlang [138] . Existují další jazyky BEAM: Efene, Joxa, Reia [139] , Luerl, Erlog [140] .
Oficiální stránka zmiňuje [141] projekt Erjang [142] , který používá virtuální stroj Java.
Přestože si zkušení programátoři Erlang již dlouho všimli, že jejich programy pro stejné úkoly jsou kratší než jiné programovací jazyky široce používané v průmyslu, empirická studie ukázala, že pro studované telekomunikační aplikace byl kód Erlang o 70–85 % kratší než v C++ . výkon systému vzrostl téměř o 100 % při přepisu kódu z C++ do Erlang [143] [144] . U jednoho z projektů použitých ve studii byl rozdíl vysvětlen napsáním dalšího kódu C++, pokud jde o obranné programování , správu paměti a kód pro komunikaci na vysoké úrovni, tedy funkce, které jsou součástí jazyka Erlang a knihoven OTP. [144] .
Vliv teorie Charlese E. Hoarea o vzájemně se ovlivňujících sekvenčních procesech je cítit v Go i Erlangu. V Erlangu si procesy podle hereckého modelu posílají zprávy přímo mezi sebou. V Go se to samé děje přes kanály [ 145 ] . Dalším rozdílem je, že potrubí v Go mají typy. Na druhé straně Erlang nemá žádné jiné typování v době kompilace než ochranné výrazy, což umožňuje odesílání zpráv jakéhokoli typu do procesů, ale „nepochopená“ zpráva bude buď ignorována, nebo zůstane navždy ve frontě [145] . Go usnadňuje organizaci skupiny "go-programů" ( angl. goroutine - náznak anglického co-routine - coroutine ) pro příjem zpráv z určitého kanálu (tento přístup je známý jako fond vláken ). V Erlangu, jehož návrh věnoval zvláštní pozornost determinismu a latenci , je implementace pracovního fondu možná, ale vyžaduje další úsilí. Více odesílatelů je triviálně implementováno v obou jazycích [145] . Proces Erlang může odeslat zprávu a čekat na odpověď (odpovídající nějakému vzoru), přičemž ignoruje ostatní zprávy ve frontě. V Go to není možné, ale podobné funkčnosti lze dosáhnout vytvořením (včetně dynamických) nových vstupů, tedy rozdělením kanálů podle jejich účelu [145] . Go vyžaduje, abyste explicitně specifikovali, které goroutiny budou interagovat s jinými zprávami předáváním zpráv, zatímco Erlang nemá sdílený proměnlivý stav mezi procesy , a proto je izolovaný proces velmi zřídka zajímavý [145] .
Abstrakce kooperujících procesů jsou v Erlang a Go dost podobné, ale aby se předešlo chybám při přechodu z jednoho jazyka do druhého, měli bychom si být vědomi nuancí: vzory, které jsou dobré v jednom jazyce, nemusí být vhodné pro jiný [145] .
Jako každý programovací jazyk není Erlang prostý nedostatků [146] . Chyby syntaxe zahrnují závislost na znaku ukončení výrazu z kontextu (může to být ., ,nebo ;), což vyžaduje další pozornost při změně výrazů na místech, přílišná upovídanost záznamů (typ záznamu je nutné uvést pokaždé, když přistupujete k členu záznam), potřeba úplného výčtu alternativ ve výrazu if, aby se zabránilo vyvolání výjimky , pokud není splněna žádná z podmínek. Mezi nevýhody patří přísně omezená množina funkcí, které lze použít v if-výrazech (tuto nevýhodu lze obejít použitím case-výrazů). Funkční styl a neměnné proměnné vedou k většímu počtu úprav v některých aplikacích (např. testech) než v jiných programovacích jazycích, protože vložení nějakého přechodného zpracování může vyžadovat nové názvy proměnných, což může vést ke změnám v kódu, který následuje. Mezi nedostatky typového systému lze poukázat na absenci typu string a také na nemožnost dynamicky přidávat nové členy do záznamů. Problémy jsou také s organizací zdrojového kódu, která je možná pouze vytvořením nového souboru, a také s nedostatkem jmenných prostorů, tříd nebo jiných prostředků pro organizaci kódu. Úroveň kvality modulů, s výjimkou těch hlavních, a dokumentace ponechává mnoho přání [146] .
Jeden z tvůrců jazyka, Joe Armstrong, ve svém projevu na konferenci o historii programovacích jazyků v roce 2007 uvedl seznam oblastí, ve kterých by bylo možné Erlang zlepšit [147] :
Hromadná distribuce Erlangu může být omezena neobvyklou syntaxí pro většinu programátorů , použitím funkčního paradigmatu a skutečností, že nejlepší implementace jazyka pro rok 2010 používá virtuální stroj BEAM, spíše než běžnější JVM [148] .
Díky svým vlastnostem Erlang a existujícím knihovnám modulů je Erlang vhodný pro vytváření síťových serverů , distribuovaných systémů, GUI programů a podobných interaktivních programů, nástrojů pro testování, řízení a monitorování, obecně aplikací s nepravidelným paralelismem, ve kterých mají být úkoly paralelizované jsou poměrně rozmanité. Erlang není zvláště vhodný pro psaní kódu náročného na plovoucí desetinnou čárku, který vyžaduje zahrnutí nativního kódu specifického pro platformu nebo náročné optimalizace nebo vytváření aplikací, které vyžadují synchronní paralelní provádění úloh. Erlang není vhodný ani pro projekty, kde musí být kód spouštěn na JVM nebo CLR , nebo projekty, které vyžadují mnoho knihoven z jiných programovacích systémů [150] .
Dá se říci, že Erlang se začal používat pro vývoj cloudových systémů ještě dříve, než se zformoval samotný koncept cloud computingu [151] . Erlang je používán ve velkých telekomunikačních a internetových aplikacích mnoha společnostmi, včetně Amazon EC2 s implementací SimpleDB , Delicious social bookmarking service , Facebook (chat backend), T-Mobile ( SMS služby a autentizační systémy) [152] . Serverový software WhatsApp je napsán v Erlangu. V lednu 2012 dokázaly servery FreeBSD WhatsApp s 96 GB RAM zpracovat 1 až 2,8 milionu připojení [153] [154] .
Erlang často připisuje pověst legendární spolehlivosti ATM přepínače AXD301 (jeden a půl milionu řádků kódu v Erlangu, půl milionu v C/C++) v síti British Telecom . Podle Ericssonu došlo v průběhu let od instalace v lednu 2002 pouze k jedné menší chybě, což má za následek odhadovanou spolehlivost systému 99,9999999 % [155] . I když realističtější odhady s přihlédnutím k mnoha dalším faktorům stále hovoří o „pěti devítkách“, úspěch routeru je připisován snadno dostupným nástrojům pro vývoj spolehlivých paralelních výpočtů zabudovaných v Erlangu [155] .
Erlang se také používá v aplikacích s otevřeným zdrojovým kódem , včetně CouchDB - databáze orientovaná na dokumenty s rozhraním REST , Disco - framework pro distribuované výpočty založený na paradigmatu MapReduce [151] [156] , Ejabberd - free (GNU GPL), distribuovaný a Jabber server odolný proti chybám napsaný primárně v Erlangu, RabbitMQ je platforma orientovaná na zprávy (implementuje AMQP , MQTT [157] ), Wings 3D je program pro 3D modelování a další. [152]
Pro Erlang bylo napsáno několik webových serverů : Yaws ( Ještě další webový server ), Cowboy a MochiWeb , knihovna pro vytváření HTTP serverů [158] . Kromě toho bylo vytvořeno několik webových frameworků a systémů pro správu obsahu , jako jsou N2O [159] , Nitrogen , Chicago Boss , Zotonic , stejně jako již aktivně nevyvíjené BeepBeep, Erlang Web, ErlyWeb [160] .
Mezi další známý software na bázi Erlang patří Riak , distribuovaná databáze NoSQL navržená na principech Amazon DynamoDB [161] , Flussonic (dříve známý jako Erlyvideo ) je multiprotokolový server pro streamování videa [162] . Pro zátěžové testování distribuovaných systémů můžete použít (také distribuovaný) nástroj napsaný v Erlang Tsung , který vám umožní emulovat tisíce (s dostatečným počtem testovacích serverů - miliony) simultánních uživatelů [163] .
Erlang je téměř ideální pro úkoly umělé inteligence (zejména výpočetní inteligence , neuroevoluce ) založené na neuronových sítích . Taková aplikace je možná díky Erlangovým pěti klíčovým vlastnostem „programovacího jazyka neuronové sítě“: izolované procesy neuronů ( zapouzdření ), paralelismus ( souběžnost , simultánnost ), mechanismus detekce selhání, nezávislost na umístění ( transparentnost umístění ) a výměna horkého kódu . Příkladem takové aplikace je implementace jednoho z přístupů k neuroevoluci – DXNN [164] .
Kolem technologií Erlang se vytvořila komunita vývojářů, která nezapře podporu začátečníkům. Zdrojový kód Erlang je dostupný prostřednictvím služby společného vývoje GitHub . Vývojáři a uživatelé Erlang mohou komunikovat prostřednictvím konference Erlang-questions (otázky Erlang) nebo na #erlang IRC kanálu na Freenode . Erlang Factory (www.erlang-factory.com) pořádá akce a konference po celém světě, včetně Erlang User Conference. Ad hoc skupina SIGPLAN ACM pravidelně pořádá Erlang Workshop a konference OSCON zahrnuje sekci o Erlangu [165] .
Programovací jazyky | |
---|---|
|