Erlang

De la Viquipèdia, l'enciclopèdia lliure
Aquest article tracta sobre el llenguatge de programació. Vegeu-ne altres significats a «Erlang (desambiguació)».
Infotaula de llenguatge de programacióErlang
Tipusllenguatge de programació multiparadigma, concurrent programming language (en) Tradueix, llenguatge de programació funcional, llenguatge de programació declaratiu, llenguatge de programació, programari de codi obert, programari lliure i habilitat Modifica el valor a Wikidata
Data de creació1986 Modifica el valor a Wikidata
DissenyJoe Armstrong Modifica el valor a Wikidata
DesenvolupadorJoe Armstrong, Ericsson i Robert Virding Modifica el valor a Wikidata
EpònimAgner Krarup Erlang i Ericsson Modifica el valor a Wikidata
Paradigma de programacióProgramació declarativa, programació funcional, computació concurrent i programació multiparadigma Modifica el valor a Wikidata
Darrera versió estable26.2.4 () Modifica el valor a Wikidata
Llenguatge de programacióErlang Modifica el valor a Wikidata
Influenciat perML, Prolog, Lisp, PLEX, Smalltalk, Miranda, Ada, Modula-2 i CHILL Modifica el valor a Wikidata
Sistema operatiumultiplataforma Modifica el valor a Wikidata
Extensió dels fitxerserl Modifica el valor a Wikidata
Codi fontCodi font Modifica el valor a Wikidata
LlicènciaLlicència Apache, versió 2.0 i Erlang Public License (en) Tradueix Modifica el valor a Wikidata
Pàgina weberlang.org Modifica el valor a Wikidata

Erlang és un llenguatge de programació concurrent i un sistema d'execució (en anglès runtime) que inclou una màquina virtual (BEAM, acrònim de "Bogdan/Björn's Erlang Abstract Machine")[1] i biblioteques (OTP: "Open Telephony Platform").[2] El subsistema seqüencial és un llenguatge de programació funcional amb tipus dinàmics i avaluació estricta. El subsistema concurrent segueix el Model d'Actors.

Erlang era originalment un llenguatge de la casa Ericsson per ésser usat en equips de comunicació, però va ser editat com a codi obert el 1998.[3]

Ericsson va posar al llenguatge el nom d'Erlang com a tribut a Agner Krarup Erlang matemàtic danès pioner en l'estudi de xarxes de telecomunicacions (que també dona el seu nom a una mesura d'ús de la xarxa)[4] i també per la coincidència amb "Ericsson language".[5]

El compilador erlc per defecte genera codi intermedi amb extensió .beam perquè el runtime l'interpreti. Però hi ha d'altres formats i opcions.[6]

Existeix un compilador HiPE (High performace Erlang compiler)[7] desenvolupat per la Universitat d'Uppsala i actualment integrat en la distribució de codi obert. Per utilitzar-lo cal afegir el paràmetre [native] a l'ordre de compilació.[8]

Hi ha un compilador a codi Scheme anomenat EToS.[9]

Existeix també una distribució aprimada "Stand-alone Erlang"[10] que genera executables i no codi intermedi (requereix instal·lar des de l'usuari "joe").

El llenguatge seqüencial[modifica]

El llenguatge utilitza una sintaxi similar a la del Prolog. S'estructura en una seqüència de clàusules cadascuna de les quals s'acaba en un . punt. Les clàusules no declaratives consten d'objectius alternatius (separats per ; punt i coma) basats en l'èxit de l'encaix de patrons (pattern matching). Cadascuna de les alternatives pot constar d'un seguit d'objectius en seqüència (separats per , comes).

Resumint i remarcant: A la fi d'una instrucció, la coma (operador de conjunció) indica seqüència, el punt i coma (operador de disjunció) introdueix alternativa (per ex. un altre cas d'encaix de patrons), i el punt indica final de clàusula (per ex. final d'una definició de funció).

Una funció s'identifica pel nom i el nombre de paràmetres (aritat) com ara "func/2". Dues funcions poden fer servir el mateix nom si tenen un nombre de paràmetres (aritat) diferent. S'acostuma a fer servir el mateix nom, per exemple quan cal definir una funció subordinada recursiva afegint un acumulador als paràmetres.

Les variables (assignables una sola vegada) comencen amb majúscula, les constants (dites àtoms) en minúscula o entre apòstrofs si contenen caràcters no alfanumèrics.

Les claus rectangulars [ ] indiquen llista, les arquejades { } indiquen tupla.

Els paràmetres formals no usats en una descripció de funció cal prefixar-los amb un caràcter de subratllat _ altrament mostra un missatge d'"Atenció variable no usada".

Avaluador d'expressions i documentació introductòria aquí.[11]

Exemple de programació (fitxer "fact.erl"):

-module(fact). % el mòdul ha de tenir el mateix nom que el fitxer
-export([fac/1, imprimeix_fac/1, llista_de_fac/1]). % llista de nom_funció/aritat

%% ';' (punt-i-coma) indica alternativa (disjunció d'objectius)
%% ',' (coma) indica seqüència (conjunció)
%% '.' (punt) indica fi de la clàusula o definició

%% factorial
fac(0) -> 1; % cas simple
fac(N) when N > 0 -> % cas recursiu
 N * fac(N-1).

%% factorial amb recursivitat final
%% fac_rf/1 (1 paràmetre)

fac_rf(N) ->
 fac_rf(N, 1).

%% fac_rf/2 (2 paràmetres)

fac_rf(0, Acum) -> Acum ;
fac_rf(N, Acum) when N > 0 ->
 fac_rf(N-1, N * Acum).

imprimeix_fac(N) ->
 R = fac_rf(N), 
 io:format("El factorial de ~w és ~w~n", [N, R]).

llista_de_fac([]) -> true; % cas simple

llista_de_fac([ Cap_de_llista| Resta]) -> % cas recursiu 
 imprimeix_fac(Cap_de_llista),
 llista_de_fac(Resta).

Compilació i execució a l'avaluador d'expressions (cònsola werl (cas de windows) o comanda erl (unix, windows)):

>c(fact). % compila fact.erl generant codi intermedi a fact.beam
{ok. fact}

>fact:imprimeix_fac(4) % crida mòdul:funció(paràmetres)
El factorial de 4 és 24
ok

>fact:llista_de_fac([2,3,4]).
El factorial de 2 és 2
El factorial de 3 és 6
El factorial de 4 és 24
true

El subsistema concurrent[modifica]

El llenguatge incorpora un sistema de creació de processos en el propi runtime independent del propi del sistema operatiu, així com un sistema de comunicació entre ells.

Per la comunicació entre ordinadors cal obrir el port 4369 del tallafocs per a TCP i UDP.[12][13]

  • la funció spawn(Mòdul, Funció, Args) crea un nou procés executant la funció especificada i retorna el PID (identificador) del procés creat.
  • la funció self() retorna el PID propi.
  • el símbol ! indica enviar. La construcció PID_destí ! {msg_id, Dades} envia dades al procés de destinació.
  • la construcció receive posa el procés en espera de recepció:
receive
 {msg_id1, Dades} -> <accions> ;
 {msg_id2, Dades2} -> <accions2> ;
 after Termini_en_milisegons -> <accions_cas_de_no_rebre_res>
end.

Un node és una instància del runtime de Erlang en un ordinador (host) determinat. La comunicació es pot establir entre diversos nodes del mateix o de diferents sistemes via TCP/IP.

Un exemple:

-module(tut19).
-export([start_ping/1, start_pong/0, ping/2, pong/0]).

%% ping -- cas simple (N = 0)
ping(0, _Pong_Node) ->
 io:format("ping ha acabat ~n", []);

%% ping -- cas recursiu
ping(N, Pong_Node) ->
 {pong_pid, Pong_Node} ! {msg_ping, self()}, % envia un msg_ping a pong amb el pid propi (''self()'')

 receive
 msg_pong ->

 io:format("Ping ha rebut pong ~n", [])
 end,

 ping(N - 1, Pong_Node). % recursivitat final (descomptant una vegada)

pong() ->
 receive
 {msg_ping, Ping_PID} ->

 io:format("Pong ha rebut ping ~n", []),

 Ping_PID ! msg_pong, % li torna un msg_pong

 pong() % torna a esperar (recursivitat final)

 after 20000 ->
 io:format("Pong s'ha cansat d'esperar i plega ~n", [])
 end.

start_pong() ->
 register(pong_pid, spawn(tut19, pong, [])). % registra l'àtom pong_pid amb valor de l'id. del procés engegat (spawn)

start_ping(Pong_Node) ->
 spawn(tut19, ping, [3, Pong_Node]).

Per provar-ho en una mateixa màquina o en dues màq. de la mateixa xarxa local engegarem dues finestres de comandes des del directori del fitxer "tut19.erl". En una escriurem la comanda

>erl -sname pong
Eshell V5.5.4
(pong@host_a)1>c(tut19). % compila
 {ok, tut19}
(pong@host_a)2>tut19:start_pong().
(pong@host_a)3>

En l'altra

>erl -sname ping
Eshell V5.5.4
(ping@host_b)1>tut19:start_ping(pong@host_a).
(ping@host_b)2>

i ja en veureu el resultat. Per provar-ho en dues màquines de xarxes diferents cal fer servir l'opció -name en comptes de -sname i posar-hi el nom qualificat del host (nom d'internet, com ara host.domini.tld).

Vegeu també[modifica]

Referències[modifica]

Enllaços externs[modifica]

A Wikimedia Commons hi ha contingut multimèdia relatiu a: Erlang