Erlang (programspråk)

Från Wikipedia
Hoppa till: navigering, sök
LYME är baserad på Erlang

Erlang är ett generellt programspråk som från början (år 1987) utvecklades på forskningsavdelningen[1] hos telebolaget Ericsson vid utvärderingen av olika programspråk för implementation av styrsystemen i telefonväxlar [2].

Språket är ett funktionellt programspråk, utan typdeklarationer och med dynamisk typning. Eftersom språket är designat för parallell bearbetning på flera sammankopplade system är det också synnerligen väl lämpat för användning på moderna multicore-maskiner.

Erlangs namn är avsiktligt fyndigt taget både efter (den i telefonsystem förekommande) enheten Erlang och som sammansättningen av Ericsson Language. Året 1998 släpptes språket fritt som öppen källkod och används nu av flera internationella företag.

Enligt Joe Armstrong, skaparen av Erlang, var språket ett rent forskningsprojekt från 1986 till 1997 då det som följd av projektet AXE-N:s kollaps valdes som bas för en ny ATM-växel med namnet AXD 301, vars programsystem var helt baserat på Erlang.[3]

Kodexempel[redigera | redigera wikitext]

Hello world[redigera | redigera wikitext]

Ett exempel som returnerar atomen hello_world.

 -module(hello).
 -export([world/0]).
 
 world() -> hello_world.

Fakultetfunktion[redigera | redigera wikitext]

Fakultet är ett typiskt problem som man löser rekursivt. Men rekursion är traditionellt sett — speciellt i språk som C — minneskrävande, då man behöver allokera minne för varje gång man kallar på en funktion. Så är det även i Erlang och liknande språk; men med ett undantag! Erlang anstränger sig för att, när den kan, frigöra minnet associerat med en funktion. Därför är det av yttersta vikt att använda sig av tekniken "svansrekursion" (eng: tail recursion), och alltså inte utföra något alls efter att man kallat på sig själv. Följande kodexempel kan vid första glimt se ut att följa just denna princip, men det är först när fac returnerar multiplikationen sker.

 -module(test).
 -export([fac/1]).
 
 fac(0) -> 1;
 fac(N) -> N * fac(N-1).

I Erlang löser man det genom att skicka med ackumulatorer som argument. En korrekt lösning på fakultetsproblemet skulle alltså kunna se ut så här:

 -module(test).
 -export([fac/1]).
 
 fac(N) -> fac(1, N).
 fac(N, 0) -> N;
 fac(N, I) -> fac(N*I, I-1).

Här illustreras även att en funktion med olika antal parametrar i själva verket inte är samma funktion. Den andra raden exporterar bara den funktion som heter fac och tar ett — och endast ett — argument.

Interprocesskommunikation[redigera | redigera wikitext]

Grundläggande i semantiken för Erlang är processer, som är isolerade från varandra. Det enda sättet för processer att kommunicera är genom att skicka meddelanden mellan varandra.

Nedan följer ett exempel över en modul med två publika funktioner:

  • create_server - Funktion för att skapa en process som lyssnar på meddelanden.
  • greet - Funktion för att skicka ett meddelande till processen.
 -module(messages).
 -export([create_server/0, greet/2]).
 
 create_server() -> spawn_link(fun() -> server_proc() end).
 
 % Serverproceduren som tar emot meddelanden.
 server_proc() ->
     receive 
         {meddelande,A} -> io:fwrite("Meddelande: "++A)
     end,
     server_proc(). 
 
 % Server = process-ID för servern.
 % Medd = meddelandet.
 greet(Server,Medd) ->
     Server!{meddelande,Medd}.

Funktionen create_server returnerar en processidentitet (PId), vilken används av greet-funktionen för att veta till vilken process meddelandet skall skickas.

 PId = messages:create_server().
 messages:greet(PId, "Hello world!").

Det går även att namnge processer med register(RegName, Pid)-funktionen.

 PId = messages:create_server().
 register(my_server, PId).
 messages:greet(my_server, "Hello world!").

Case-satser[redigera | redigera wikitext]

 -module(case).
 -export([conditional/1]).
 conditional(P) ->
     % För att visa, anta att P inte bör skyddas av funktionsklausulen
     case P of
         P when is_integer(P) ->
             2*P;
         P when is_list(P) ->
             hd(P);
         _ ->
             fel
     end.

Mönstermatchning[redigera | redigera wikitext]

 % Sker vid 
 % 1. Funktionsanrop, 
 % 2. case/receieve/try 
 % 3. (=)-operatorn
 -module(matchning).
 -export([funktion/1,
         konditionell/1,
         tilldelning/0]).
 funktion([]) ->
     [];
 funktion([First | _Tail]) ->    
     First.
 konditionell(X) ->    
     case X of
         A when is_atom(A) ->            
             A;
         B when is_integer(B) ->
             B;
         _ ->
             fel
     end.
 tilldelning() ->
     % A binds till 1
     % B binds till [2,3]
     [A | B] = [1,2,3],
     % C binds till 2, D till 3
     [C, D] = B,
     A + C + D.

List-comprehensions[redigera | redigera wikitext]

 -module(listcomp).
 -export([squarePositives/1]).
 squarePositives(List) ->
     [A*A || A <- List, A > 0].

Externa länkar[redigera | redigera wikitext]

Referenser[redigera | redigera wikitext]

  1. ^ Ericsson Computer Science Laboratory
  2. ^ A study called SPOTS
  3. ^ Armstrong, Joe (2007). ”A history of Erlang” (på engelska) (PDF). Proceedings of the third ACM SIGPLAN conference on History of programming languages. New York: ACM. doi:10.1145/1238844.1238850. ISBN 978-1-59593-766-7. http://dl.acm.org/citation.cfm?id=1238850. Läst 2012-01-04