Erlang (gjuhë programimi)

**Erlang** është një gjuhë programimi e nivelit të lartë funksionale, me qëllim të përgjithshëm, konkurrente dhe me funksione të nivelit të lartë, si dhe një sistem ekzekutimi i mbledhur nga mbeturinat .Termi Erlang përdoret në mënyrë të ndërsjellë me Erlang/OTP, ose Platforma e Telekomit të Hapur (OTP), e cila përbëhet nga sistemi i ekzekutimit Erlang, disa komponentë të gatshëm për përdorim (OTP) kryesisht të shkruar në Erlang, dhe një sërë parimesh projektimi për programet Erlang.

Sistemi i kohës së ekzekutimit Erlang është projektuar për sisteme me këto karakteristika:

* Të distribuara
* Tolerant ndaj gabimeve
* Në kohë reale të butë
* Aplikacione shumë të disponibile dhe pa ndërprerje
* Ndërrim i menjëhershëm, ku kodi mund të ndryshohet pa ndaluar një sistem.

Gjuha programuese Erlang ka përputhje të modeleve të të dhënave dhe programim funksional. Nëngrupi sekuencial i gjuhës Erlang mbështet vlerësimin e menjëhershëm, caktimin e vetëm dhe tipizim dinamike.

Një aplikacion normal Erlang është ndërtuar nga qindra procese të vogla Erlang.

Fillimisht ishte një softuer i patentuar brenda Ericsson, i zhvilluar nga Joe Armstrong, Robert Virding dhe Mike Williams në vitin 1986, por u publikua si softuer i lirë dhe me burim të hapur në vitin 1998.  Erlang/OTP mbështetet dhe mirëmbahet nga njësia e produkteve Open Telecom Platform (OTP) në Ericsson.

## Histori 
Emri *Erlang*,i atribuar Bjarne Däcker, është supozuar nga ata që punojnë në çelsat telefonikë (për të cilët është projektuar gjuha) të jetë një referencë për matematikanin dhe inxhinierin danez Agner Krarup Erlang dhe një shkurtim rrokjesh i "Ericsson Language".   Erlang u projektua me qëllim përmirësimin e zhvillimit të aplikacioneve telefonike.  Versioni fillestar i Erlang u implementua në Prolog dhe u ndikua nga gjuha programuese  "PLEX" e përdorur në centralet e mëparshme Ericsson. Deri në vitin 1988, Erlang kishte provuar se ishte i përshtatshëm për prototipizmin e centraleve telefonike, por interpretuesi i Prolog ishte shumë i ngadaltë. Një grup brenda Ericsson vlerësoi se do të duhej të ishte 40 herë më i shpejtë për të qenë i përshtatshëm për përdorim në prodhim. Në vitin 1992, filloi puna në makinën virtuale BEAM (VM), e cila kompilon Erlang në C duke përdorur një përzierje të kodit të kompiluar në mënyrë native dhe kodit të filetuar për të arritur një ekuilibër midis performancës dhe hapësirës së diskut.  Sipas bashkë-shpikësit Joe Armstrong, gjuha kaloi nga një produkt laboratorik në zbatime reale pas rënies së centralit telefonik AXE të gjeneratës së ardhshme të quajtur *AXE-N* në vitin 1995. Si rezultat, Erlang u zgjodh për centralin e ardhshëm të Modalitetit Asinkron të Transferimit (ATM) *AXD* .  Ndalimi bëri që Armstrong dhe të tjerët të bënin plane për t'u larguar nga Ericsson. Në mars të vitit 1998, Ericsson njoftoi ndërfaqen AXD301,e cila përmbante mbi një milion rreshta të Erlang dhe raportohej se arrinte një disponueshmëri të lartë prej nëntë “9”-ash. Në dhjetor të vitit 1998, zbatimi i Erlang u bë me burim të hapur dhe shumica e ekipit të Erlang dha dorëheqjen për të formuar një kompani të re, Bluetail AB.Ericsson përfundimisht e zbuti ndalimin dhe e ripunësoi Armstrong-in në vitin 2004.

Në vitin 2006, sistemit të kohës së ekzekutimit dhe VM-së iu shtua mbështetja e multiprocesimit simetrik vendas. 

### Proceset 
Aplikacionet Erlang janë ndërtuar nga procese shumë të lehta Erlang në sistemin e ekzekutimit Erlang. Sistemi i ekzekutimit Erlang siguron izolim të rreptë të proceseve (kjo përfshin mbledhjen e të dhënave dhe mbeturinave, të ndara individualisht për secilin proces Erlang) dhe komunikim transparent midis proceseve (shih transparenca e vendndodhjes) në nyje të ndryshme Erlang (në hostë të ndryshëm).

Joe Armstrong, bashkëshpikësi i Erlang, përmblodhi parimet e proceseve në disertacionin e tij të doktoraturës :

* Çdo gjë është një proces.
* Proceset janë të izoluara fort.
* Krijimi dhe shkatërrimi i proceseve është një operacion i lehtë.
* Kalimi i mesazheve është e vetmja mënyrë që proceset të bashkëveprojnë.
* Proceset kanë emra unikë.
* Nëse e dini emrin e një procesi, mund t'i dërgoni një mesazh.
* Proceset nuk ndajnë burime.
* Trajtimi i gabimeve nuk është lokal.
* Proceset bëjnë atë që duhet të bëjnë ose dështojnë.

Joe Armstrong tha në një intervistë me Rackspace në vitin 2013: "Nëse Java është ' shkruaj një herë, ekzekuto kudo ', atëherë Erlang është 'shkruaj një herë, ekzekuto përgjithmonë'."

### Përdorimi 
Në vitin 2014, Ericsson raportoi se Erlang po përdorej në nyjet e saj mbështetëse, dhe në rrjetet mobile GPRS, 3G dhe LTE në mbarë botën, si dhe nga Nortel dhe Deutsche Telekom.

Erlang përdoret në RabbitMQ. Siç e shprehu Tim Bray, drejtor i Teknologjive Web në Sun Microsystems, në fjalimin e tij kryesor në Konventën e Burimit të Hapur O'Reilly (OSCON) në korrik 2008:
 
Nëse dikush do të vinte tek unë dhe do të më ofronte shumë para për të ndërtuar një sistem të madh për menaxhimin e mesazheve që duhet të jetë gjithmonë në funksion dhe nuk guxon të bjerë nga puna për vite me radhë, unë pa hezitim do të zgjidhja Erlang për ta ndërtuar.
Erlang është gjuha programuese që përdoret për të koduar WhatsApp

Është gjithashtu gjuha e zgjedhur për Ejabberd - një server mesazhesh XMPP.

Elixir është një gjuhë programuese që kompilohet në kod bajtesh BEAM (nëpërmjet Erlang Abstract Format).

Që kur u publikua si burim i hapur, Erlang është përhapur përtej telekomunikacionit, duke u vendosur në tregje të tjera vertikale si FinTech, lojërat, kujdesi shëndetësor, automobilistike, Interneti i Gjërave dhe blockchain. Përveç WhatsApp, ka edhe kompani të tjera të listuara si histori suksesi të Erlang, duke përfshirë Vocalink (një kompani e MasterCard), Goldman Sachs, Nintendo, AdRoll, Grindr, BT Mobile, Samsung, OpenX dhe SITA.

## Shembuj të programimit funksional 
### Faktorial 
Një algoritëm faktorial i zbatuar në Erlang:
```erlang
-module(fact). % This is the file 'fact.erl', the module and the filename must match
-export([fac/1]). % This exports the function 'fac' of arity 1 (1 parameter, no type, no name)

fac(0) -> 1; % If 0, then return 1, otherwise (note the semicolon ; meaning 'else')
fac(N) when N > 0, is_integer(N) -> N * fac(N-1).
% Recursively determine, then return the result
% (note the period . meaning 'endif' or 'function end')
%% This function will crash if anything other than a nonnegative integer is given.
%% It illustrates the "Let it crash" philosophy of Erlang.
```

### Sekuenca Fibonacci 
Një algoritëm rekursiv i bishtit që prodhon sekuencën Fibonacci:
```erlang
%% The module declaration must match the file name "series.erl" 
-module(series).

%% The export statement contains a list of all those functions that form
%% the module's public API. In this case, this module exposes a single
%% function called fib that takes 1 argument (I.E. has an arity of 1)
%% The general syntax for -export is a list containing the name and
%% arity of each public function
-export([fib/1]).

%% ---------------------------------------------------------------------
%% Public API
%% ---------------------------------------------------------------------

%% Handle cases in which fib/1 receives specific values
%% The order in which these function signatures are declared is a vital
%% part of this module's functionality

%% If fib/1 receives a negative number, then return the atom err_neg_val
%% Normally, such defensive coding is discouraged due to Erlang's 'Let
%% it Crash' philosophy, but here the result would be an infinite loop.
fib(N) when N  err_neg_val;

%% If fib/1 is passed precisely the integer 0, then return 0
fib(0) -> 0;

%% For all other values, call the private function fib_int/3 to perform
%% the calculation
fib(N) -> fib_int(N-1, 0, 1).

%% ---------------------------------------------------------------------
%% Private API
%% ---------------------------------------------------------------------

%% If fib_int/3 receives 0 as its first argument, then we're done, so
%% return the value in argument B. The second argument is denoted _ to
%% disregard its value.
fib_int(0, _, B) -> B;

%% For all other argument combinations, recursively call fib_int/3
%% where each call does the following:
%% - decrement counter N
%% - pass the third argument as the new second argument
%% - pass the sum of the second and third arguments as the new
%%  third argument
fib_int(N, A, B) -> fib_int(N-1, B, A+B).
```
Heqja e komenteve e bënë një program shumë më të shkurtër.
```erlang
-module(series).
-export([fib/1]).

fib(N) when N  err_neg_val;
fib(0) -> 0;
fib(N) -> fib_int(N-1, 0, 1).

fib_int(0, _, B) -> B;
fib_int(N, A, B) -> fib_int(N-1, B, A+B).
```

### Renditje e shpejtë 
Renditje e shpejtë në Erlang, duke përdorur përfitim listash:
```erlang
%% qsort:qsort(List)
%% Sort a list of items
-module(qsort).   % This is the file 'qsort.erl'
-export([qsort/1]). % A function 'qsort' with 1 parameter is exported (no type, no name)

qsort([]) -> []; % If the list [] is empty, return an empty list (nothing to sort)
qsort([Pivot|Rest]) ->
  % Compose recursively a list with 'Front' for all elements that should be before 'Pivot'
  % then 'Pivot' then 'Back' for all elements that should be after 'Pivot'
  qsort([Front || Front = Pivot]).
```
Shembulli i mësipërm thërret në mënyrë rekursive funksionin *qsort* derisa të mos mbetet asgjë për t’u renditur. Shprehja [Front || Front  është një përftim listash (list comprehension), që do të thotë: “Ndërto një listë elementësh *Front* të tillë që `Front` është element i `Rest` dhe `Front` është më i vogël se `Pivot`.” `++` është operatori i bashkimit të listave.

Një funksion krahasimi mund të përdoret për struktura më të ndërlikuara për hir të lexueshmërisë.

Kodi i mëposhtëm do të rendiste listat sipas gjatësisë:
```erlang
% This is file 'listsort.erl' (the compiler is made this way)
-module(listsort).
% Export 'by_length' with 1 parameter (don't care about the type and name)
-export([by_length/1]).

by_length(Lists) -> % Use 'qsort/2' and provides an anonymous function as a parameter
  qsort(Lists, fun(A,B) -> length(A)  []; % If list is empty, return an empty list (ignore the second parameter)
qsort([Pivot|Rest], Smaller) ->
  % Partition list with 'Smaller' elements in front of 'Pivot' and not-'Smaller' elements
  % after 'Pivot' and sort the sublists.
  qsort([X || X  length(A) Numra të plotë =
Numrat e plotë shkruhen si sekuenca shifrash dhjetore; për shembull, 12, 12375 dhe -23427 janë numra të plotë. Aritmetika e numrave të plotë është e saktë dhe kufizohet vetëm nga memoria e disponueshme në makinë. (Kjo quhet **aritmetikë me saktësi arbitrare**.)

= Atome =
Atomet përdoren brenda një programi për të përfaqësuar vlera të dallueshme. Ato shkruhen si vargje karakteresh alfanumerike të njëpasnjëshme, ku karakteri i parë është me shkronjë të vogël. Atomet mund të përmbajnë çdo karakter nëse janë të mbyllura brenda thonjëzave të vetme, dhe ekziston një **konventë escape** që lejon përdorimin e çdo karakteri brenda një atomi.

Atomet **nuk i nënshtrohen mbledhjes së mbeturinave**, prandaj duhen përdorur me kujdes, veçanërisht kur krijohen në mënyrë dinamike.

= Numra me presje lundruese (Floats) =
Numrat me presje lundruese përdorin përfaqësimin 64-bit të IEEE 754.

= Referencat =
Referencat janë simbole globalisht unike, vetia e vetme e të cilave është se ato mund të krahasohen për barazi. Ato krijohen duke vlerësuar primitiven e Erlang-ut `make_ref()`.

= Binarë =
Një binar është një sekuencë bajtësh. Binarët ofrojnë një mënyrë të kursyeshme për ruajtjen e të dhënave binare. Ekzistojnë primitive Erlang për kompozimin dhe zbërthimin e binarëve, si dhe për hyrje/dalje efikase të tyre.

= Pids =
Pid është shkurtim për *process identifier* – një Pid krijohet nga primitivi `spawn(...)`. Pids-at janë referenca drejt proceseve Erlang

= Portet =
Portet përdoren për të komunikuar me botën e jashtme. Ato krijohen me funksionin e integruar `open_port`. Mesazhet mund të dërgohen dhe të merren nga portet, por këto mesazhe duhet të ndjekin të ashtuquajturin **“protokoll portash”**.

= Fun-et =
Fun-et janë **mbyllje funksionesh** (*function closures*). Ato krijohen me shprehje të formës:

**`fun(...) -> ... end`.**

Dhe tre lloje të të dhënave të përbëra:

;

= Tuples =
Tuple-et janë kontejnerë për një numër të caktuar të llojeve të të dhënave në Erlang. Sintaksa **{D1, D2, ..., Dn}** paraqet një tuple, argumentet e së cilës janë **D1, D2, ... Dn**. Argumentet mund të jenë lloje të të dhënave primitive ose të përbëra.

**Çdo element i një tuple-i mund të aksesohet në kohë konstante.**

= Listat =
Listat janë kontejnerë për një numër të ndryshueshëm të llojeve të të dhënave në Erlang. Sintaksa **`[Dh | Dt]`** paraqet një listë ku elementi i parë është **`Dh`**, ndërsa elementët e mbetur përbëjnë listën **`Dt`**.

Sintaksa **`[]`** paraqet një listë bosh.

Sintaksa **`[D1, D2, ..., Dn]`** është formë e shkurtuar për:

`**[D1 | [D2 | ... | [Dn | []]]]**.`

Elementi i parë i një liste mund të aksesohet në kohë konstante.

Elementi i parë quhet **koka** e listës (head).

Pjesa tjetër e listës pasi hiqet koka quhet **bishti** i listës (tail).

= Hartat (Maps) =
Hartat përmbajnë një numër të ndryshueshëm të çifteve **çelës–vlerë**.

Sintaksa është:

`**#{Key1 => Value1, ..., KeyN => ValueN}**.`

Janë dhënë dy forma të sheqerit sintaksor :

;

= Strings (Vargjet) =
Vargjet shkruhen si lista karakteresh të vendosura brenda thonjëzave të dyfishta. Kjo është vetëm **sheqer sintaksor**, që do të thotë se në fakt ato përfaqësojnë një listë me vlerat e kodeve Unicode (numra të plotë) për secilin karakter të vargut.

Për shembull, vargu **"cat"** është formë e shkurtuar për:

`**[99, 97, 116]**.`

= Records (Regjistrat) =
Regjistrat ofrojnë një mënyrë të përshtatshme për të shoqëruar një etiketë (tag) me secilin element brenda një tuple-i.

Kjo lejon që një element të referohet **me emër dhe jo sipas pozicionit**.

Një **parakompilues** (pre-compiler) merr përkufizimin e rekordit dhe e zëvendëson atë me referencën përkatëse të tuple-it.

## Stili i kodimit "Lëre të rrëzohet" 
Erlang është projektuar me një mekanizëm që e bën të lehtë për proceset e jashtme të monitorojnë rrëzimet (ose dështimet e harduerit), në vend të një mekanizmi brenda procesit si trajtimi i përjashtimeve që përdoret në shumë gjuhë të tjera programimi. Rrëzimet raportohen si çdo mesazh tjetër.Që është e vetmja mënyrë se si proceset mund të komunikojnë me njëri-tjetrin, dhe nënproceset mund të krijohen me kosto shumë të ulët (shih më poshtë). Filozofia “le të rrëzohet” preferon që një proces të rifillohet plotësisht, në vend që të përpiqet të rikuperohet nga një dështim serioz.Edhe pse përsëri kërkohet trajtimi i gabimeve, kjo filozofi rezulton në më pak kod të dedikuar për programim mbrojtës, pasi kodi për trajtimin e gabimeve është zakonisht shumë kontekstual dhe specifik.

### Pemët mbikëqyrëse 
Një aplikacion tipik **Erlang** shkruhet në formën e një peme mbikëqyrësi.Kjo arkitekturë bazohet në një hierarki procesesh, në të cilën procesi i nivelit të lartë njihet si **“mbikëqyrës”.** Mbikëqyrësi pastaj krijon disa procese fëmijë që veprojnë ose si punëtorë, ose si mbikëqyrës të niveleve më të ulëta.Hierarki të tilla mund të ekzistojnë në thellësi të ndryshme dhe kanë dëshmuar se ofrojnë një mjedis shumë të shkallëzueshëm dhe tolerant ndaj gabimeve, brenda të cilit mund të zbatohet funksionaliteti i aplikacionit.

Brenda një peme mbikëqyrësi, të gjitha proceset mbikëqyrëse janë përgjegjëse për menaxhimin e ciklit jetësor të proceseve të tyre fëmijë, dhe kjo përfshin trajtimin e situatave në të cilat këto procese fëmijë rrëzohen.Çdo proces mund të bëhet mbikëqyrës duke krijuar së pari një proces fëmijë, dhe më pas duke thirrur `erlang:monitor/2` në atë proces.Nëse procesi i monitoruar më pas rrëzohet, mbikëqyrësi do të marrë një mesazh që përmban një tuple, anëtari i parë i të cilit është atomi '`DOWN`'.Mbikëqyrësi është përgjegjës së pari për të dëgjuar mesazhe të tilla dhe për të ndërmarrë veprimet e duhura për të korrigjuar gjendjen e gabimit.

## Orientimi i njëkohshmërisë dhe shpërndarjes 
Forca kryesore e Erlang është mbështetja për konkurencën. Ai ka një grup të vogël, por të fuqishëm primitivësh për të krijuar procese dhe për të komunikuar midis tyre.Erlang është konceptualisht i ngjashëm me gjuhën Occam, megjithëse riformulon idetë e Komunikimit të Proceseve Sekuenciale (CSP) në një kornizë funksionale dhe përdor kalimin asinkron të mesazheve. Proceset janë mjeti kryesor për të strukturuar një aplikacion Erlang.Ato nuk janë as procese të sistemit operativ dhe as fije, por procese të lehta që planifikohen nga BEAM.Ashtu si proceset e sistemit operativ (por ndryshe nga fijet e sistemit operativ), ato nuk ndajnë gjendje me njëra-tjetrën. Shpenzimi minimal i vlerësuar për secilin është 300 fjalë. Kështu, shumë procese mund të krijohen pa ulur performancën. Në vitin 2005, një test me 20 milionë procese u krye me sukses me Erlang 64-bit në një makinë me 16 GB memorie me akses të rastësishëm (RAM; gjithsej 800 bajt/proces).Erlang ka mbështetur shumëpërpunimin simetrik që nga lëshimi R11B në maj 2006.

Ndërsa fijet kanë nevojë për mbështetje nga biblioteka të jashtme në shumicën e gjuhëve,Erlang ofron veçori të nivelit gjuhësor për të krijuar dhe menaxhuar procese me qëllim thjeshtimin e programimit të njëkohshëm.Megjithëse e gjithë bashkëkohësia është e qartë në Erlang,proceset komunikojnë duke përdorur kalimin e mesazheve në vend të variablave të përbashkëta,gjë që eliminon nevojën për bllokime të qarta (një skemë bllokimi përdoret ende brenda makinës virtuale).

Komunikimi ndër-proces funksionon përmes një sistemi të mesazheve asinkrone me parimin “shared-nothing”:çdo proces ka një “kuti postare”, një radhë mesazhesh që janë dërguar nga procese të tjera dhe që ende nuk janë konsumuar.Një proces përdor primitivin `receive` për të marrë mesazhet që përputhen me modelet e dëshiruara. Një rutinë e trajtimit të mesazheve i teston mesazhet me radhë kundrejt secilit model, derisa njëri prej tyre të përputhet.Kur mesazhi konsumohet dhe hiqet nga kutia postare, procesi rifillon ekzekutimin.Një mesazh mund të përfshijë çdo strukturë Erlang, duke përfshirë primitivat (numra të plotë, numra devijues, karaktere, atome), tuple, lista dhe funksione.

Shembulli i kodit më poshtë tregon mbështetjen e integruar për proceset e shpërndara:
```erlang
% Create a process and invoke the function web:start_server(Port, MaxConnections)
 ServerProcess = spawn(web, start_server, [Port, MaxConnections]),

 % Create a remote process and invoke the function
 % web:start_server(Port, MaxConnections) on machine RemoteNode
 RemoteProcess = spawn(RemoteNode, web, start_server, [Port, MaxConnections]),

 % Send a message to ServerProcess (asynchronously). The message consists of a tuple
 % with the atom "pause" and the number "10".
 ServerProcess ! {pause, 10},

 % Receive messages sent to this process
 receive
     a_message -> do_something;
     {data, DataContent} -> handle(DataContent);
     {hello, Text} -> io:format("Got hello message: ~s", [Text]);
     {goodbye, Text} -> io:format("Got goodbye message: ~s", [Text])
 end.
```
Siç tregon shembulli, proceset mund të krijohen në nyje të largëta dhe komunikimi me to është transparent, në kuptimin që komunikimi me proceset e largëta funksionon saktësisht njësoj si komunikimi me proceset lokale.

Bashkëkohësia mbështet metodën kryesore të trajtimit të gabimeve në Erlang.Kur një proces rrëzohet, ai del në mënyrë të rregullt dhe i dërgon një mesazh procesit kontrollues, i cili më pas mund të ndërmarrë veprime, si për shembull nisjen e një procesi të ri që merr përsipër detyrën e procesit të vjetër.

## Zbatimi 
Implementimi zyrtar i referencës së Erlang përdor BEAM. BEAM është përfshirë në shpërndarjen zyrtare të Erlang, të quajtur Erlang/OTP. BEAM ekzekuton bytecode i cili konvertohet në kod të filetuar në kohën e ngarkimit. Ai gjithashtu përfshin një përpilues kodi vendas në shumicën e platformave, të zhvilluar nga Projekti Erlang me Performancë të Lartë (HiPE) në Universitetin Uppsala. Që nga tetori i vitit 2001, sistemi HiPE është integruar plotësisht në sistemin Erlang/OTP me burim të hapur të Ericsson. Ai gjithashtu mbështet interpretimin, direkt nga kodi burimor nëpërmjet pemës abstrakte të sintaksës, nëpërmjet skriptit që nga versioni R11B-5 i Erlang.

## Ngarkimi i kodit të nxehtë dhe modulet 
Erlang mbështet Përditësimin Dinamik të Softuerit në nivel gjuhe. Për ta zbatuar këtë, kodi ngarkohet dhe menaxhohet si njësi “moduli”; moduli është një njësi kompilimi. Sistemi mund të mbajë dy versione të një moduli në memorie në të njëjtën kohë, dhe proceset mund të ekzekutojnë kod njëkohësisht nga secili. Versionet referohen si versioni “i ri” dhe “i vjetër”. Një proces nuk do të kalojë në versionin e ri derisa të bëjë një thirrje të jashtme në modulin e tij.

Një shembull i mekanizmit të ngarkimit të kodit të nxehtë:
```erlang
%% A process whose only job is to keep a counter.
 %% First version
 -module(counter).
 -export([start/0, codeswitch/1]).

 start() -> loop(0).

 loop(Sum) ->
  receive
    {increment, Count} ->
     loop(Sum+Count);
    {counter, Pid} ->
     Pid ! {counter, Sum},
     loop(Sum);
    code_switch ->
     ?MODULE:codeswitch(Sum)
     % Force the use of 'codeswitch/1' from the latest MODULE version
  end.

 codeswitch(Sum) -> loop(Sum).
```
Për versionin e dytë, shtojmë mundësinë për ta rivendosur numërimin në zero.
```erlang
%% Second version
 -module(counter).
 -export([start/0, codeswitch/1]).

 start() -> loop(0).

 loop(Sum) ->
  receive
    {increment, Count} ->
     loop(Sum+Count);
    reset ->
     loop(0);
    {counter, Pid} ->
     Pid ! {counter, Sum},
     loop(Sum);
    code_switch ->
     ?MODULE:codeswitch(Sum)
  end.

 codeswitch(Sum) -> loop(Sum).
```
Vetëm kur merr një mesazh që përbëhet nga atomi `**code_switch**,` cikli do të ekzekutojë një thirrje të jashtme te **codeswitch/1** (**`?MODULE`** është një makro e paraprocesorit për modulin aktual). Nëse ka një version të ri të modulit të numëruesit në memorie, atëherë do të thirret funksioni i tij **codeswitch/1**.Praktika e të pasurit një pike hyrëse specifike në një version të ri i lejon programuesit të transformojë gjendjen në atë që nevojitet në versionin më të ri.Në shembull, gjendja mbahet si një numër i plotë.

Në praktikë, sistemet ndërtohen duke përdorur parimet e projektimit nga **Platforma e Telekomit të Hapur**, gjë që çon në dizajne më të përditësueshme të kodit.Ngarkimi i suksesshëm i kodit të nxehtë është i vështirë.Kodi duhet të shkruhet me kujdes për të shfrytëzuar lehtësitë e **Erlang-ut**.

## Shpërndarja 
Në vitin 1998, Ericsson publikoi Erlang si softuer falas dhe me burim të hapur për të siguruar pavarësinë e tij nga një shitës i vetëm dhe për të rritur ndërgjegjësimin për gjuhën. Erlang, së bashku me bibliotekat dhe bazën e të dhënave të shpërndarë në kohë reale Mnesia, formon koleksionin OTP të bibliotekave. Ericsson dhe disa kompani të tjera e mbështesin Erlang komercialisht.

Që nga publikimi me kod të hapur, Erlang është përdorur nga disa firma në të gjithë botën, duke përfshirë Nortel dhe Deutsche Telekom. Edhe pse Erlang u krijua për të mbushur një vend të caktuar dhe ka mbetur një gjuhë e panjohur për pjesën më të madhe të ekzistencës së tij, popullariteti i tij po rritet për shkak të kërkesës për shërbime të njëkohshme. Erlang ka gjetur njëfarë përdorimi në vendosjen e serverave masivë të lojërave online me role (MMORPG) për shumë lojtarë.

## Shih edhe 
* **Elixir** – një gjuhë programimi funksionale, konkurrente dhe e përgjithshme që funksionon mbi BEAM.

* **Luerl** – Lua në BEAM, e projektuar dhe implementuar nga një prej krijuesve të Erlang-ut.

* **Lisp Flavored Erlang (LFE)** – një gjuhë programimi e bazuar në Lisp që funksionon mbi BEAM.
* **Mix** – mjet ndërtimi (build tool).
* **Phoenix** – kornizë (framework) për zhvillimin e aplikacioneve web.
* **Gleam** – një gjuhë programimi e nivelit të lartë, funksionale, konkurrente dhe e përgjithshme, që kompilohet në Erlang.

## Referime 
 

## Lidhje të jashtme 
*