Erlang (programspråk)

Från Wikipedia
(Omdirigerad från Erlang (programmeringsspråk))
Erlang
Paradigmmulti-paradigm: samtidighet, funktionell
Gavs ut1986
Skapat avJoe Armstrong, Robert Virding och Mike Williams på Ericsson
UtvecklareEricsson
Datatypsdisciplindynamisk, stark
Influerat avProlog, Smalltalk, PLEX,[1] LISP
InflueratAkka, Clojure, Dart, Elixir, F#, Opa, Oz, Reia, Rust, Scala
PlattformBEAM
LicensApache License 2.0 (sen OTP 18.0) Erlang Public License 1.1 (tidigare versioner)
Webbplatshttp://www.erlang.org
Standardfiländelse(r).erl, .hrl

Erlang är ett generellt programspråk som från början (år 1987) utvecklades på forskningsavdelningen[2][3] hos telebolaget Ericsson AB vid utvärderingen av olika programspråk för implementation av styrsystemen i telefonväxlar[4]. 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 flerkärniga datorer. 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.[5]

Kodexempel[redigera | redigera wikitext]

Hello world[redigera | redigera wikitext]

Ett exempel som returnerar atomen hello_world. Alla program måste ha ett modul-namn och exportera funktioner för att de ska kunna anropas externt.

 -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(N, 1).
 fac(0, A) -> A;
 fac(N, A) -> fac(N-1, A*N).

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 sig.

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]

Varje case-sats (sv. falluppdelning) börjar med "case" följt av ett uttryck följt av "of" och sedan flera olika fall och avslutas med "end". Varje sats evalueras genom att P evalueras och sedan går man igenom de olika fallen (varje fall följs av en pil ->). Så fort uttrycket satisfieras fallet köra man uttrycket som följer efter ->, och de resterande fallen hoppar man över. Till exempel om vi låter P = 2 då kommer vi satisfiera det första fallet och då returnera 2 * 2 = 4.

 -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-konstruktion[redigera | redigera wikitext]

Genom att deklarativt beskriva elementen i en lista byggs den sedan induktivt.

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

I detta fallet skulle sista raden utläsas som: för varje element i listan List som är strikt större än noll låt elementet bli dess kvadrat i en ny lista.

Externa länkar[redigera | redigera wikitext]

Referenser[redigera | redigera wikitext]

  1. ^ Conferences, N. D. C. (4 June 2014). ”Joe Armstrong - Functional Programming the Long Road to Enlightenment: a Historical and Personal Narrative”. Joe Armstrong - Functional Programming the Long Road to Enlightenment: a Historical and Personal Narrative. https://vimeo.com/97329186. 
  2. ^ Ericsson Computer Science Laboratory
  3. ^ Bjarne Däcker (1993). Per-Olof Thyselius. red. ”Erlang — A New Programming Language” (på engelska). Ericsson Review (Stockholm: TELEFONAKTIEBOLAGET LM ERICSSON) 70 (2): sid. 51-57. http://www.ericssonhistory.com/global/Ericsson%20review/Ericsson%20Review.%201993.%20V.70/Ericsson_Review_Vol_70_1993_2.pdf. Läst 7 februari 2014. 
  4. ^ A study called SPOTS
  5. ^ 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 4 januari 2012