Erlang

De Viquipèdia

Aquest article tracta sobre el llenguatge de programació. Per a altres significats, vegeu «Erlang (desambiguació)».

Erlang és un llenguatge de programació concurrent i base d'execució (en anglès runtime). 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 a ser usat en equips de comunicació, però va ser editat com a codi obert el 1998.

Ericsson va posar al llenguatge el nom de Erlang com a tribut a Agner Kraup 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)[1] i també per la coincidència amb "Ericsson language".

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

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

Hi ha un compilador a codi Scheme dit EToS[5].

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

Taula de continguts

[edita] El llenguatge seqüencial

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'assignació per patrons (pattern matching). Cadascuna de les alternatives pot constar d'un seguit d'objectius en seqüència (separats per , comes).

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

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]).

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

%% factorial amb recursivitat final
fac2( N) -> 
              fac_tr( N, 1).

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

imprimeix_fac(N) -> 
                   R = fac2(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ó (en la cònsola werl (windows) o comanda erl (linux, windows)):

>c(fact).         % compila fact.erl generant pseudo-codi-màquina 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

[edita] El subsistema concurrent

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 a la comunicació entre ordinadors cal obrir el port 4369 del tallafocs per a TCP i UDP[7][8].

  • 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 Temporització_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(0, _Pong_Node) ->
    io:format("ping ha acabat ~n", []);

ping(N, Pong_Node) ->
    {pong_pid, Pong_Node} ! {msg_ping, self()},    % envia un msg_ping a pong

    receive
        msg_pong ->

            io:format("Ping ha rebut pong ~n", [])
    end,
    
    ping(N - 1, Pong_Node).      % iteració (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

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

start_pong() ->
    register(pong_pid, spawn(tut19, pong, [])).

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

Per a 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 a provar-ho en dues màquines de xarxes diferents cal usar l'opció -name en comptes de -sname i usar el nom qualificat del host (nom d'internet).

[edita] Referències

  1. Erlang.com - Què és un Erlang (anglès)
  2. Formats i opcions de compilació (anglès)
  3. Compilador HiPE (anglès)
  4. Erlang.se - Tot allò que voldrieu saber sobre HiPE ... (anglès)
  5. Compilador EToS (anglès)
  6. Stand-alone Erlang (anglès)
  7. Erlang distribuït amb SSL a través de tallafocs (anglès)
  8. Distribució Erlang a través de tallafocs (anglès)

[edita] Enllaços externs